Knowledge

Git CheatSheet: wichtige Befehle für den Alltag

Git ist eine Versionsverwaltung für Softwareprojekte. Änderungen werden versioniert, Branches trennen Arbeitsstände und die Historie zeigt, was wann geändert wurde.

Die meisten Probleme mit Git entstehen nicht durch Git selbst, sondern durch Fehler in der Anwendung. Viele Fehler entstehen, weil vor einem commit, push, reset oder merge nicht geprüft wird, was Git gerade sieht. Änderungen werden versehentlich mitcommitted. Oder es wird an der Historie gearbeitet, obwohl der Branch bereits mit anderen geteilt wurde.

Ein Branch ist ein eigener Arbeitszweig im Repository. Damit kann ein Feature, Bugfix oder Experiment getrennt vom Hauptbranch entwickelt werden.

Lokal kann ich Fehler korrigieren, Commits zurückdrehen oder Änderungen verwerfen. Sobald ein Branch geteilt wurde, sollte seine Historie grundsätzlich als unveränderlich gelten. Ausnahme: eigene Feature-Branches, wenn klar ist, dass niemand anderes darauf arbeitet.

Lange laufende Branches werden schnell teuer. Je länger ein Branch vom Hauptstand abweicht, desto höher wird das Risiko für Konflikte, doppelte Arbeit und schwer nachvollziehbare Änderungen. Riskant wird es, wenn neue Branches von unfertigen Feature-Branches abzweigen. Dann hängen mehrere Arbeitsstände voneinander ab. Das macht Merge, Review und Fehleranalyse unnötig schwer.

Für Details zu einem Befehl immer die Git-Hilfe nutzen:

Hilfe zu einem Git-Befehl anzeigen

git BEFEHL --help

Beispiel:

git push --help

1. Neues Repository anlegen und mit einem Remote-Repository verbinden

Häufig entsteht ein Projekt zuerst lokal. Danach wird es mit einem Remote-Repository verbunden. Beispiele dafür sind GitHub, GitLab, Bitbucket, Gitea oder ein interner Git-Server.

Repository initialisieren

Im Projektordner wird Git initialisiert.

git init

Hinweis:

Ohne weitere Angaben erstellt git init im aktuellen Ordner ein neues lokales Git-Repository.

Dateien vormerken

Danach werden die vorhandenen Dateien für den ersten Commit vorgemerkt.

git add .

Hinweis:

. steht für das aktuelle Verzeichnis. Es werden alle Änderungen im aktuellen Verzeichnis und darunter für den nächsten Commit vorgemerkt.

Ersten Commit erstellen

Danach wird der erste Stand lokal committed.

git commit -m "Initial commit"

Wichtige Parameter:

-m übergibt die Commit-Nachricht direkt in der Befehlszeile.

"Initial commit" ist die Beschreibung des Commits.

Hauptbranch umbenennen

Der Hauptbranch wird auf main umbenannt. main ist heute bei vielen Projekten der übliche Name für den stabilen Hauptstand.

git branch -M main

Wichtige Parameter:

-M ist die erzwungene Umbenennung des aktuellen Branches. Technisch entspricht das einer Kombination aus Umbenennen und Überschreiben, falls der Zielname bereits existiert.

main ist der neue Name des Hauptbranches.

Remote-Repository verknüpfen

Danach wird das lokale Repository mit dem Remote-Repository verknüpft. origin ist der lokale Kurzname für das Remote-Repository.

git remote add origin git@github.com:USERNAME/REPOSITORY.git

Wichtige Bestandteile:

remote verwaltet entfernte Repositories.

add fügt ein neues Remote-Repository hinzu.

origin ist der frei wählbare Name für das Remote-Repository. origin ist Konvention, aber kein Pflichtname.

git@github.com:USERNAME/REPOSITORY.git ist die SSH-Adresse des Remote-Repositorys. Bei GitLab, Bitbucket, Gitea oder internen Git-Servern sieht diese Adresse entsprechend anders aus.

Hauptbranch übertragen

Danach wird der lokale Hauptbranch in das Remote-Repository übertragen.

git push -u origin main

Wichtige Parameter:

-u aktiviert das Upstream-Tracking. Dadurch weiß Git künftig, welcher lokale Branch zu welchem Remote-Branch gehört. Danach reichen für diesen Branch meistens git push und git pull ohne weitere Angaben.

origin ist der Name des Remote-Repositorys.

main ist der Branch, der übertragen wird.

Wichtig:

git init erstellt nur ein lokales Repository. Erst durch git remote add origin ... und git push -u origin main wird es mit einem Remote-Repository verbunden und übertragen.

2. Bestehendes Repository holen

Liegt das Repository bereits auf einem Git-Server, wird es lokal geklont.

Repository per SSH klonen

Mit sauber eingerichteten SSH-Keys ist SSH im Alltag meist die bessere Wahl.

git clone git@github.com:USERNAME/REPOSITORY.git

Wichtige Bestandteile:

clone kopiert ein bestehendes Remote-Repository lokal auf den Rechner.

git@github.com:USERNAME/REPOSITORY.git ist die SSH-Adresse des Remote-Repositorys. Bei anderen Git-Hosting-Plattformen sieht die Adresse entsprechend anders aus.

Repository per HTTPS klonen

Alternativ kann das Repository per HTTPS geklont werden.

git clone https://github.com/USERNAME/REPOSITORY.git

clone kopiert das Projekt lokal und richtet das Remote-Repository direkt ein.

3. Aktuellen Zustand prüfen

Wenn unklar ist, was Git gerade sieht, kommt zuerst der Status.

Status prüfen

Der Status zeigt, welche Dateien geändert wurden, welche neu sind und welche bereits für den nächsten Commit vorgemerkt wurden.

git status

Hinweis:

git status verändert keine Dateien. Der Befehl zeigt nur den aktuellen Zustand.

Nicht vorgemerkte Änderungen anzeigen

Noch nicht vorgemerkte Änderungen können mit diff angesehen werden.

git diff

Hinweis:

git diff zeigt lokale Änderungen, die noch nicht in der Staging Area liegen.

Vorgemerkte Änderungen anzeigen

Bereits vorgemerkte Änderungen werden separat geprüft.

git diff --staged

Wichtige Parameter:

--staged zeigt die Änderungen, die bereits in der Staging Area liegen und beim nächsten Commit übernommen würden.

git status sagt, was los ist. git diff zeigt, was sich wirklich geändert hat.

4. Änderungen für einen Commit vorbereiten

Ein Commit besteht nicht automatisch aus allen Änderungen. Du entscheidest, was hinein soll.

Einzelne Datei vormerken

Eine einzelne Datei wird gezielt für den nächsten Commit vorgemerkt.

git add path/to/file.php

Alle Änderungen vormerken

Alle Änderungen im aktuellen Verzeichnis werden vorgemerkt. Das ist praktisch, aber gefährlich, wenn vorher nicht geprüft wurde.

git add .

Hinweis:

. steht für das aktuelle Verzeichnis.

Nur bekannte Dateien vormerken

Nur Änderungen an bereits bekannten Dateien werden vorgemerkt. Neue Dateien werden damit nicht automatisch hinzugefügt.

git add -u

Wichtige Parameter:

-u nimmt Änderungen an bereits getrackten Dateien auf. Neue Dateien werden nicht automatisch hinzugefügt.

Wichtig:

Nicht blind git add . ausführen. Erst git status, dann entscheiden.

5. Commit erstellen

Ein Commit speichert die vorgemerkten Änderungen lokal in der Historie.

Commit erstellen

Die vorgemerkten Änderungen werden mit einer Commit-Message in die lokale Historie geschrieben.

git commit -m "Add OAuth token service"

Wichtige Parameter:

-m übergibt die Commit-Message direkt in der Befehlszeile.

Schlechte Commit-Message

Eine Commit-Message sollte sagen, was geändert wurde. Allgemeine Aussagen helfen später kaum.

git commit -m "fix"

Bessere Commit-Message

Besser ist eine konkrete Beschreibung.

git commit -m "Fix token refresh for expired access tokens"

Gute Commit-Messages sind kein Selbstzweck. Sie helfen später beim Lesen der Historie, beim Debugging und beim Review.

6. Änderungen aus dem Remote-Repository holen

fetch und pull werden oft verwechselt.

Remote-Informationen holen

fetch holt Informationen vom Remote-Repository, verändert den aktuellen Arbeitsstand aber nicht direkt.

git fetch

Hinweis:

git fetch aktualisiert nur die Informationen über das Remote-Repository. Der aktuelle Arbeitsstand wird nicht verändert.

Änderungen holen und integrieren

pull holt Änderungen vom Remote-Repository und integriert sie in den aktuellen Branch.

git pull

Hinweis:

git pull entspricht vereinfacht einem fetch mit anschließender Integration in den aktuellen Branch.

Änderungen aus main holen

Änderungen aus einem bestimmten Remote-Branch können gezielt geholt werden.

git pull origin main

Wichtige Bestandteile:

origin ist das Remote-Repository.

main ist der Branch, dessen Änderungen geholt und integriert werden.

fetch schaut nach. pull holt und integriert.

7. Änderungen zusammenführen mit merge

merge führt Änderungen aus einem anderen Branch in den aktuellen Branch zusammen.

Feature-Branch aktualisieren

Typischer Fall: Der eigene Feature-Branch soll auf den aktuellen Stand des Hauptbranches gebracht werden.

git switch feature/oauth-token-service
git fetch
git merge origin/main

Wichtige Bestandteile:

feature/oauth-token-service ist der lokale Feature-Branch.

origin/main ist der Remote-Tracking-Branch des Hauptbranches aus dem Remote-Repository origin.

Damit werden die Änderungen aus origin/main in den aktuellen Feature-Branch übernommen.

Gibt es keine Konflikte, läuft der Merge meist direkt durch. Gibt es Konflikte, müssen sie manuell gelöst werden.

Konflikte anzeigen

Nach einem Konflikt sollte zuerst geprüft werden, welche Dateien betroffen sind.

git status

Konfliktdatei vormerken

Danach werden die Konfliktdateien bearbeitet und wieder vorgemerkt.

git add path/to/conflict-file.php

Merge abschließen

Anschließend wird der Merge abgeschlossen.

git commit

Wichtig:

Ein Merge sollte nicht blind durchgeführt werden. Nach dem Merge Tests ausführen und prüfen, ob die eigene Änderung noch sauber funktioniert.

8. Änderungen ins Remote-Repository übertragen

Lokale Commits werden mit push ins Remote-Repository übertragen.

Änderungen pushen

Die lokalen Commits werden in den bereits verknüpften Remote-Branch übertragen.

git push

Hinweis:

Ohne weitere Angaben pusht Git den aktuellen Branch zum verknüpften Remote-Branch, sofern Upstream-Tracking eingerichtet ist.

Neuen Branch pushen

Ein neuer Branch muss beim ersten Push mit dem Remote-Repository verknüpft werden.

git push -u origin feature/oauth-token-service

Wichtige Parameter:

-u aktiviert das Upstream-Tracking. Der lokale Branch wird dadurch mit dem Remote-Branch verbunden.

origin ist das Remote-Repository.

feature/oauth-token-service ist der Branch, der übertragen wird.

Nach diesem ersten Push reichen für diesen Branch normalerweise:

git push

und:

git pull

Risiko:

Vor dem Push sollten Tests laufen. Ein Push ist nicht nur lokal. Ab diesem Moment betrifft der Stand meistens auch CI, Reviews oder andere Entwickler.

9. Branches sauber nutzen

Branches halten Features, Bugfixes und Experimente vom Hauptbranch getrennt.

Lokale Branches anzeigen

Lokale Branches anzeigen.

git branch

Hinweis:

Ohne Parameter zeigt git branch die lokalen Branches.

Alle Branches anzeigen

Lokale und Remote-Branches anzeigen.

git branch -a

Wichtige Parameter:

-a zeigt lokale Branches und Remote-Tracking-Branches.

Neuen Branch erstellen

Einen neuen Branch erstellen und direkt hineinwechseln.

git switch -c feature/oauth-token-service

Wichtige Parameter:

-c erstellt einen neuen Branch und wechselt direkt in diesen Branch.

Auf main wechseln

Zurück auf den Hauptbranch wechseln.

git switch main

Hinweis:

main ist hier der Name des Zielbranches. In älteren Projekten kann der Hauptbranch auch anders heißen.

Branch mit checkout erstellen

Die ältere Schreibweise mit checkout funktioniert weiterhin.

git checkout -b feature/oauth-token-service

Wichtige Parameter:

-b erstellt einen neuen Branch und wechselt direkt hinein.

Mit checkout wechseln

Mit checkout kann auch auf einen bestehenden Branch gewechselt werden.

git checkout main

Neue Arbeit bekommt einen eigenen Branch. Der Hauptbranch sollte stabil bleiben.

10. Historie lesen

Git ist nur dann wirklich hilfreich, wenn die Historie lesbar bleibt.

Kompakte Historie anzeigen

Die Commit-Historie kompakt anzeigen.

git log --oneline

Wichtige Parameter:

--oneline zeigt jeden Commit in einer Zeile.

Historie mit Branch-Struktur anzeigen

Die Historie inklusive Branch-Struktur anzeigen.

git log --oneline --graph --decorate --all

Wichtige Parameter:

--oneline zeigt jeden Commit in einer Zeile.

--graph zeigt die Branch-Struktur als einfache Textgrafik.

--decorate zeigt zusätzliche Referenzen wie Branch- und Tag-Namen.

--all berücksichtigt alle Branches.

Commit-Details anzeigen

Details zu einem bestimmten Commit anzeigen.

git show COMMIT_HASH

Konkreten Commit anzeigen

Beispiel mit konkretem Commit-Hash.

git show a1b2c3d

Hinweis:

COMMIT_HASH ist ein Platzhalter für die eindeutige Commit-ID. Meist reichen die ersten Zeichen, solange sie eindeutig sind.

Damit lässt sich nachvollziehen, warum ein Commit entstanden ist.

11. Änderungen einer Datei nachvollziehen

git blame zeigt, welcher Commit welche Zeile zuletzt geändert hat.

Zeilenhistorie einer Datei anzeigen

Die letzte Änderung pro Zeile anzeigen.

git blame path/to/file.php

Zeilenbereich prüfen

Für größere Dateien kann ein bestimmter Zeilenbereich geprüft werden.

git blame -L 20,60 path/to/file.php

Wichtige Parameter:

-L 20,60 begrenzt die Ausgabe auf die Zeilen 20 bis 60.

git blame ist kein Werkzeug zum Beschuldigen. Es ist ein Werkzeug, um Kontext zu finden. Der nächste Schritt ist meistens git show.

12. Dateien löschen oder aus Git entfernen

Eine Datei kann aus Git und gleichzeitig lokal gelöscht werden.

Datei löschen

Die Datei wird aus Git und aus dem Arbeitsverzeichnis entfernt.

git rm path/to/file.php

Löschung committen

Danach wird die Löschung committed.

git commit -m "Remove unused file"

Datei nur aus Git entfernen

Eine Datei kann auch nur aus Git entfernt werden, lokal aber erhalten bleiben.

git rm --cached .env

Wichtige Parameter:

--cached entfernt die Datei nur aus dem Git-Index. Lokal bleibt sie vorhanden.

Das ist typisch, wenn eine Datei versehentlich versioniert wurde, lokal aber weiter gebraucht wird.

Risiko:

Wenn Zugangsdaten bereits gepusht wurden, reicht Entfernen aus Git nicht. Dann gelten sie als kompromittiert und müssen geändert werden.

13. Lokale Änderungen verwerfen

Eine einzelne Datei kann auf den letzten Commit zurückgesetzt werden.

Datei zurücksetzen

Lokale Änderungen an einer Datei werden verworfen.

git restore path/to/file.php

Alle lokalen Änderungen verwerfen

Alle lokalen Änderungen im aktuellen Verzeichnis werden verworfen.

git restore .

Hinweis:

. steht für das aktuelle Verzeichnis.

Datei aus Staging entfernen

Eine Datei kann aus der Staging Area entfernt werden. Die Änderung bleibt lokal vorhanden, landet aber nicht mehr im nächsten Commit.

git restore --staged path/to/file.php

Wichtige Parameter:

--staged entfernt Änderungen aus der Staging Area, ohne die lokale Änderung zu löschen.

Risiko:

restore kann Arbeit löschen. Vorher git diff lesen.

14. HEAD zurücksetzen

HEAD ist der aktuelle Commit. Mit reset wird der Verlauf verschoben. Das ist nützlich, aber gefährlich.

Letzten Commit zurücknehmen, Änderungen gestaged behalten

Der letzte Commit wird entfernt. Die Änderungen bleiben gestaged.

git reset --soft HEAD~1

Wichtige Parameter:

--soft verschiebt HEAD, lässt die Änderungen aber in der Staging Area.

HEAD~1 bedeutet: ein Commit vor dem aktuellen Commit.

Das ist nützlich, wenn die Commit-Message falsch war oder noch etwas in denselben Commit soll.

Letzten Commit zurücknehmen, Änderungen lokal behalten

Der letzte Commit wird entfernt. Die Änderungen bleiben lokal erhalten, sind aber nicht mehr gestaged.

git reset --mixed HEAD~1

Wichtige Parameter:

--mixed verschiebt HEAD und entfernt die Änderungen aus der Staging Area. Die Dateien bleiben lokal geändert.

Letzten Commit hart verwerfen

Der letzte Commit und die Änderungen werden verworfen.

git reset --hard HEAD~1

Wichtige Parameter:

--hard verschiebt HEAD und setzt Arbeitsverzeichnis sowie Staging Area zurück. Lokale Änderungen gehen verloren.

Risiko:

reset --hard ist kein Aufräumbefehl. Er löscht lokale Arbeit.

15. Commit rückgängig machen

Wenn ein Commit bereits gepusht wurde, ist revert meist sauberer als reset.

Commit rückgängig machen

revert erstellt einen neuen Commit, der die Änderungen eines alten Commits rückgängig macht.

git revert COMMIT_HASH

Konkreten Commit rückgängig machen

Beispiel mit konkretem Commit-Hash.

git revert a1b2c3d

Hinweis:

COMMIT_HASH ist ein Platzhalter für den Commit, der rückgängig gemacht werden soll.

Auf den Punkt:

reset verändert Historie. revert schreibt einen Gegen-Commit. In Team-Branches ist revert meistens die bessere Wahl.

16. Rollback auf einen alten Stand

Ein alter Commit kann zunächst nur angesehen werden.

Alten Commit ansehen

Damit landet man in einem losgelösten Stand. Gut zum Prüfen, nicht zum normalen Weiterarbeiten.

git switch --detach COMMIT_HASH

Wichtige Parameter:

--detach wechselt auf einen Commit ohne aktiven Branch. Das eignet sich zum Prüfen, nicht zum normalen Weiterarbeiten.

Branch von altem Stand erstellen

Von einem alten Stand kann ein neuer Branch erstellt werden.

git switch -c rollback-test COMMIT_HASH

Wichtige Parameter:

-c erstellt einen neuen Branch und wechselt direkt hinein.

COMMIT_HASH ist der Commit, von dem der neue Branch ausgehen soll.

Damit kann ein alter Stand untersucht oder als Basis für eine Reparatur genutzt werden.

Branch hart zurücksetzen

Der aktuelle Branch kann hart auf einen alten Commit zurückgesetzt werden.

git reset --hard COMMIT_HASH

Wichtige Parameter:

--hard setzt Branch, Staging Area und Arbeitsverzeichnis auf den angegebenen Commit zurück.

COMMIT_HASH ist der Zielstand.

Risiko:

Das ist ein harter Eingriff. In gemeinsam genutzten Branches nur mit Absprache.

17. Force Push

Wenn die Historie lokal verändert wurde, kann ein normaler Push abgelehnt werden.

Force Push mit Schutz

--force-with-lease prüft vorher, ob sich der Remote-Branch verändert hat. Das reduziert das Risiko, Arbeit anderer zu überschreiben.

git push --force-with-lease

Wichtige Parameter:

--force-with-lease erzwingt den Push nur, wenn der Remote-Branch noch dem Stand entspricht, den Git lokal kennt.

Force Push ohne Schutz

Die härtere Variante überschreibt ohne diese zusätzliche Prüfung.

git push --force

Wichtige Parameter:

--force überschreibt den Remote-Stand ohne diese Schutzprüfung.

Force Push ist kein normaler Alltagsbefehl. Auf gemeinsamen Branches nur mit Absprache.

18. Git LFS für große Dateien

Git ist schlecht für große Binärdateien. Dafür gibt es Git LFS.

Git LFS ist kein reines Client-Feature. Der Git-Server muss LFS unterstützen.

GitHub, GitLab und Bitbucket unterstützen Git LFS grundsätzlich. Bei GitLab Self-Managed, Gitea oder internen Git-Servern hängt es von der Konfiguration ab. Bei einfachen Bare-Repositories ist LFS nicht automatisch vorhanden.

Git LFS installieren

Git LFS lokal aktivieren.

git lfs install

Hinweis:

git lfs install richtet Git LFS lokal ein.

Dateityp über LFS verwalten

Einen Dateityp für LFS vormerken.

git lfs track "*.zip"

Wichtige Bestandteile:

"*.zip" ist ein Dateimuster. Alle passenden ZIP-Dateien werden künftig über LFS verwaltet.

LFS-Regel committen

Die LFS-Regel wird in .gitattributes gespeichert und sollte committed werden.

git add .gitattributes
git commit -m "Configure Git LFS"

Große Datei hinzufügen

Eine große Datei wird danach normal hinzugefügt und gepusht. Git LFS übernimmt die Verwaltung im Hintergrund.

git add large-file.zip
git commit -m "Add large file via LFS"
git push

Git LFS ist für große Dateien. Build-Artefakte, Docker Images und Packages gehören meist in eine Registry.

19. Nützliche Erweiterungen

git fame

git fame zeigt Statistiken zu Autoren und Änderungen im Repository.

git fame installieren

Installation über Python/Pip.

pip install git-fame

git fame ausführen

Statistik im aktuellen Repository erzeugen.

git fame

Zeilenstatistiken sind interessant, aber keine Qualitätsmessung.

git extras

git extras stellt je nach Installation zusätzliche Hilfsbefehle bereit.

Zusatzbefehle nutzen

Einige typische Befehle aus git extras.

git summary
git effort
git changelog

Diese Werkzeuge helfen beim Überblick. Sie ersetzen aber kein Lesen der Commits.

20. Git und CI/CD

In vielen Projekten startet CI/CD nach einem Push oder Pull Request.

CI bedeutet Continuous Integration. Nach einem Push oder Pull Request werden automatisch Prüfungen ausgeführt:

  • Tests
  • Code Style
  • statische Analyse
  • Build
  • Security Checks

CD bedeutet Continuous Delivery oder Continuous Deployment.

Continuous Delivery heißt: Ein auslieferbarer Stand wird vorbereitet.

Continuous Deployment heißt: Ein erfolgreicher Stand wird automatisch ausgeliefert.

CI prüft den Code. CD bringt ihn Richtung Auslieferung.

21. Typischer Arbeitsablauf

Aktuellen Hauptstand holen

Zuerst auf den Hauptbranch wechseln und den aktuellen Stand holen.

git switch main
git pull

Feature-Branch erstellen

Danach einen neuen Feature-Branch erstellen.

git switch -c feature/oauth-token-service

Änderungen prüfen

Nach der Umsetzung wird geprüft, was geändert wurde.

git status
git diff

Änderungen committen

Dann werden die Änderungen vorgemerkt und committed.

git add .
git commit -m "Add OAuth token service"

Feature-Branch pushen

Der Branch wird ins Remote-Repository übertragen.

git push -u origin feature/oauth-token-service

Danach folgt Pull Request oder Merge Request mit Review und CI-Prüfung.

22. Fehler vermeiden

Vor Commit prüfen

Vor jedem Commit sollte geprüft werden, welche Änderungen wirklich enthalten sind.

git status
git diff

Vor jedem Push sollten Tests ausgeführt werden. Je nach Projekt können das zum Beispiel diese Befehle sein:

PHP-Tests ausführen

./vendor/bin/phpunit

Maven-Tests ausführen

./mvnw test

Gradle-Tests ausführen

./gradlew test

Keine Secrets committen

Sensible Dateien gehören nicht ins Repository.

.env
*.key
*.pem
secrets.json

Typische .gitignore

Eine typische .gitignore kann so aussehen.

.env
var/
vendor/
node_modules/
.idea/