kind: reference search: commit, add, status, diff, log, branch, checkout, switch, merge, Konflikt, pull, push, clone, restore, revert, stash, gitignore, tag, HEAD

Git: Versionen verwalten

Die Befehle aus Versionsverwaltung mit Git zum Nachschlagen: Commits anlegen, die Geschichte ansehen, mit Branches arbeiten, Konflikte lösen, mit anderen teilen und Fehler rückgängig machen. Wie dein Workspace sich bei einem Git-Server anmeldet, steht unter Git-Server: Zugang und Veröffentlichen.

1. Die Begriffe

Begriff Was es ist
Repository ein Ordner, dessen Geschichte Git verwaltet; die Geschichte selbst liegt im versteckten Ordner .git
Commit ein gespeicherter Stand aller Dateien, mit Nachricht, Autor, Zeit und einer ID wie a3ac34a
Arbeitsverzeichnis die Dateien, wie du sie gerade siehst und bearbeitest
Staging Area was mit dem nächsten Commit gespeichert wird; git add legt Änderungen dorthin
Branch ein Name, der auf einen Commit zeigt und mit jedem neuen Commit weiterrückt, zum Beispiel main
HEAD wo du gerade bist: meist ein Branch, nach git checkout HEAD~2 ein einzelner Commit
Remote ein anderes Repository, mit dem du Commits austauschst, meist origin auf einem Git-Server

HEAD~1 ist der Commit vor HEAD, HEAD~2 der davor. Statt einer ID genügen ihre ersten Zeichen, solange sie eindeutig sind.

Linus Torvalds 2018 auf einer Konferenz: ein Mann mit Brille und kurzem Haar in einem schwarzen T-Shirt, lächelnd.

Linus Torvalds (geboren 1969). Das Terminal im Workspace läuft unter Linux: Das hat er 1991 als Student in Helsinki angefangen, »nur ein Hobby«, schrieb er damals. Heute läuft Linux auf den meisten Servern der Welt und in jedem Android-Handy.

2005 brauchte er für die Arbeit an Linux eine neue Versionsverwaltung und schrieb in wenigen Tagen die erste Fassung von Git.

Foto: Raysonho, 2018, CC0 (Wikimedia Commons)

2. Alleine arbeiten

Ein Repository anlegen

Befehl Was er tut
git init macht den aktuellen Ordner zu einem Repository, ohne Commits
git clone ADRESSE holt eine Kopie eines Repositorys mit seiner ganzen Geschichte in einen neuen Ordner
git clone ADRESSE ordner dasselbe in einen Ordner mit anderem Namen

Bevor du den ersten Commit machst, muss Git wissen, wer du bist: Git sagen, wer du bist. Ein Repository für eine Aktivität klonst du so, wie es unter Repository klonen steht.

Änderungen speichern

Befehl Was er tut
git status zeigt, welche Dateien geändert, bereitgelegt oder Git noch unbekannt sind (»Untracked files«)
git add datei legt eine neue oder geänderte Datei für den nächsten Commit bereit; git add . alles im Ordner
git commit -m "Nachricht" speichert alles Bereitgelegte als Commit
git commit -a -m "Nachricht" legt vorher alle geänderten Dateien bereit, die Git schon kennt; neue Dateien brauchen trotzdem git add
git diff zeigt die Änderungen, die noch nicht bereitgelegt sind, Zeile für Zeile
git diff --staged zeigt, was bereitgelegt ist und mit dem nächsten Commit gespeichert wird
git mv alt neu benennt eine Datei um oder verschiebt sie
git rm datei löscht eine Datei und legt das Löschen bereit

Der Ablauf ist fast immer derselbe:

git status
git add README.md
git commit -m "Anleitung ergänzt"

Eine gute Nachricht sagt in einer Zeile, was der Commit ändert, so dass du ihn in git log später wiederfindest: »Punkte zählen, wenn ein Stern gefangen wird«, nicht »weiter«.

Die Geschichte ansehen

Befehl Was er zeigt
git log alle Commits, der neueste oben, mit ID, Autor, Datum und Nachricht
git log --oneline jeden Commit in einer Zeile
git log --oneline --graph --all alle Branches als Graph, wo sie sich trennen und wieder zusammenkommen
git log --author=Name nur die Commits einer Person; git log -- datei nur die, die eine Datei ändern
git show a3ac34a einen Commit mit allen seinen Änderungen
git blame datei zu jeder Zeile, in welchem Commit und von wem sie zuletzt geändert wurde

Eine lange Ausgabe zeigt Git seitenweise wie less: Pfeiltasten und Leertaste blättern, Q beendet.

Dateien ignorieren

Was dein Programm erzeugt (übersetzte Programme, Bilder, die es rechnet, Ordner wie node_modules), gehört nicht ins Repository. Eine Datei .gitignore im Repository nennt sie, ein Muster pro Zeile:

hello
*.o
build/

hello ist eine Datei mit genau diesem Namen, *.o jede Datei, die auf .o endet, build/ ein ganzer Ordner. git status zeigt sie danach nicht mehr an, und git add . lässt sie aus. Die .gitignore selbst wird committet, damit sie für alle gilt. Eine Datei, die schon committet ist, ignoriert Git erst, wenn du sie mit git rm --cached datei aus dem Repository nimmst; im Ordner bleibt sie.

3. Branches

Anlegen, wechseln, zusammenführen

Befehl Was er tut
git branch listet die Branches auf; vor dem, auf dem du bist, steht ein *
git branch feature legt einen Branch an, der auf den aktuellen Commit zeigt; du bleibst, wo du bist
git checkout feature wechselt zu dem Branch: Die Dateien im Ordner sind jetzt die von dort
git checkout -b feature beides auf einmal: anlegen und wechseln
git merge feature holt die Commits von feature in den Branch, auf dem du bist
git branch -d feature löscht den Branch, wenn seine Commits schon gemergt sind; -D auch sonst

Vor dem Wechseln sollte git status nichts Geändertes zeigen: Committe erst, oder leg die Änderungen mit git stash beiseite (siehe unten). Neuere Fassungen von Git kennen für das Wechseln auch git switch feature und git switch -c feature; sie tun dasselbe wie die beiden checkout-Zeilen oben.

Gemergt wird immer in den Branch, auf dem du gerade bist. Um feature in main zu bringen:

git checkout main
git merge feature

Konflikte lösen

Haben zwei Commits dieselben Zeilen verschieden geändert, kann Git sie nicht von selbst zusammenführen. git merge oder git pull melden dann CONFLICT, und in der Datei stehen beide Fassungen:

<<<<<<< HEAD
HOLAAA
=======
HEYYYY
>>>>>>> ef91739

Oben steht deine Fassung, unten die, die dazukommen soll. So löst du den Konflikt:

  1. Öffne die Datei und stell die Fassung her, die gelten soll: eine der beiden, beide oder eine dritte.
  2. Lösche die drei Zeilen mit <<<<<<<, ======= und >>>>>>>.
  3. git add datei, für jede Datei mit Konflikt; git status zeigt, welche es noch gibt.
  4. git commit -m "Konflikt gelöst", danach wie gewohnt git push.

Visual Studio Code zeigt über jedem Konflikt die Knöpfe »Accept Current Change«, »Accept Incoming Change« und »Accept Both Changes«; sie erledigen die Schritte 1 und 2. Willst du lieber wieder zum Stand vor dem Merge, bricht git merge --abort ihn ab.

4. Gemeinsam arbeiten

Befehl Was er tut
git remote add origin ADRESSE nennt ein anderes Repository origin, damit du mit ihm Commits austauschen kannst
git remote -v zeigt, welche Remotes es gibt und wo sie liegen
git push -u origin main schickt main zum ersten Mal und merkt sich origin als Ziel für diesen Branch
git push schickt deine neuen Commits zum Remote
git pull holt die neuen Commits vom Remote und führt sie mit deinen zusammen
git config pull.rebase false sagt Git einmal, dass git pull zusammenführen soll, wenn beide Seiten neue Commits haben
git push origin --tags schickt auch die Tags (siehe unten)

Hol mit git pull, bevor du anfängst, und schick mit git push, wenn du fertig bist. Lehnt Git deinen Push ab, weil jemand vor dir gepusht hat, steht unter Wenn Git den Push ablehnt, was zu tun ist. Bricht git pull ab, weil du Dateien geändert hast, die auch in der neuen Version anders sind, hilft git stash wie unter Eine neue Version der Vorlage holen.

5. Zurückgehen und rückgängig machen

Einen alten Stand ansehen

Befehl Was er tut
git checkout HEAD~2 die Dateien, wie sie zwei Commits vorher waren
git checkout a3ac34a die Dateien, wie sie in diesem Commit waren; git checkout v1.0 wie bei einem Tag
git checkout main zurück zum neuesten Stand von main
git restore --source HEAD~2 datei nur diese eine Datei so, wie sie zwei Commits vorher war; danach wie jede Änderung committen

Nach git checkout auf einen Commit oder Tag meldet Git detached HEAD: Du bist auf keinem Branch. Ansehen und ausprobieren geht, aber Commits von hier gehören zu keinem Branch. Willst du von hier aus weiterarbeiten, leg zuerst mit git checkout -b neuer-name einen Branch an.

Änderungen zurücknehmen

Welcher Befehl passt, hängt davon ab, wie weit die Änderung schon gekommen ist:

Die Änderung ist … Befehl Was passiert
nur im Arbeitsverzeichnis git restore datei Die Datei ist wieder auf dem Stand des letzten Commits. Die Änderung ist weg.
mit git add bereitgelegt git restore --staged datei Die Änderung kommt aus der Staging Area zurück ins Arbeitsverzeichnis; verloren geht nichts.
im letzten Commit, noch nicht gepusht git commit --amend -m "Nachricht" Der letzte Commit wird ersetzt, mit dem, was jetzt bereitliegt, und der neuen Nachricht.
schon committet git revert HEAD Ein neuer Commit hebt den letzten auf; statt HEAD geht jede Commit-ID.
noch nicht fertig, soll aber kurz weg git stash legt alle Änderungen beiseite, der Ordner ist wieder auf dem Stand des letzten Commits; git stash pop holt sie zurück, git stash list zeigt, was beiseite liegt
Einen Commit, den andere schon mit git pull geholt haben können, ersetzt du nicht mit --amend, sondern hebst ihn mit git revert auf: Sonst passt ihre Geschichte nicht mehr zu deiner, und der nächste Push wird abgelehnt.

Was einmal committet war, findet Git meist wieder: git reflog listet, wo HEAD in letzter Zeit überall stand, auch Commits, auf die kein Branch mehr zeigt. Was mit git restore verworfen wurde, war nie committet und ist wirklich weg.

6. Tags

Ein Tag ist ein fester Name für einen Commit, etwa für eine Version, die du abgibst. Anders als ein Branch rückt er nicht weiter.

Befehl Was er tut
git tag -a v1.0 -m "Abgabe" gibt dem aktuellen Commit den Namen v1.0, mit einer Nachricht
git tag listet die Tags auf
git push origin v1.0 schickt einen Tag zum Remote; git push origin --tags alle
git checkout v1.0 die Dateien, wie sie bei diesem Tag waren (detached HEAD, siehe oben)

7. Zum Nachschlagen

Zu jedem Befehl zeigt git help befehl alle Optionen, zum Beispiel git help commit.

Cover von »Pro Git«, zweite Auflage: der Titel in Orange auf Schwarz, darunter Scott Chacon und Ben Straub.

Pro Git, Scott Chacon und Ben Straub, Apress, 2. Auflage 2014. Alles, was hier fehlt: Rebase, Git auf einem Server, die Arbeit mit GitHub und wie Git seine Commits intern speichert. Frei lesbar, auch auf Deutsch: auf git-scm.com.

Cover: Apress, CC BY-NC-SA 3.0 (progit2)

  • Git Reference: jeder Befehl mit allen Optionen, auf Englisch.
  • Learn Git Branching: Branches, Merge und mehr als Spiel im Browser, mit einem gezeichneten Commit-Graphen, der sich bei jedem Befehl ändert.
  • Mist, Git!: kurze Rezepte für die Pannen, die allen passieren, vom falschen Branch bis zur vergessenen Datei im letzten Commit.