Einen bestimmten Commit in Git auschecken – so geht es
Sie möchten sehen, wie Ihr Projekt vor drei Wochen aussah, einen Bug in einer alten Version reproduzieren oder eine einzelne Datei aus einem früheren Stand zurückholen? Dafür „checken” Sie einen bestimmten Commit aus. Hier stehen die konkreten Befehle, der Unterschied zwischen dem alten git checkout und den neueren Kommandos git switch und git restore – und warum der „detached HEAD” harmlos bleibt, solange Sie eine einzige Regel beachten.
Zuerst: Welchen Commit wollen Sie überhaupt?
Jeder Commit hat einen eindeutigen SHA-Hash (z. B. a1b2c3d…). Diesen Hash finden Sie mit dem Log:
git log --oneline
Die Ausgabe sieht etwa so aus:
a1b2c3d (HEAD -> main) Login-Formular validiert
9f8e7d6 Header-Layout korrigiert
3c4d5e6 Erste Version der Startseite
Die kurze ID vorne (7 Zeichen) reicht für alle Befehle aus, solange sie im Repository eindeutig ist. Statt eines Hashes können Sie auch relative Angaben nutzen:
HEAD– der aktuelle CommitHEAD~1– ein Commit davor,HEAD~3– drei davor- ein Branch- oder Tag-Name wie
mainoderv1.2.0
Geht es Ihnen um einen Branch, der nur auf dem Server liegt und lokal noch fehlt, läuft das etwas anders – über git fetch und einen Tracking-Branch. Das erklärt Wie checke ich einen Remote-Branch aus?.
Einen Commit auschecken
Der klassische Befehl lautet:
git checkout 9f8e7d6
Danach entspricht Ihr Arbeitsverzeichnis exakt dem Zustand dieses Commits. Sie können den Code lesen, das Projekt bauen, testen – alles wie damals. Git meldet dabei etwas in dieser Art:
Note: switching to '9f8e7d6'.
You are in 'detached HEAD' state...
HEAD is now at 9f8e7d6 Header-Layout korrigiert
Diese Meldung ist keine Warnung vor einem Fehler, sondern eine Zustandsbeschreibung, die Sie einordnen müssen, bevor Sie weiterarbeiten.
Was „detached HEAD” wirklich bedeutet
HEAD ist der Zeiger auf „die Stelle, an der Sie gerade stehen”. Normalerweise zeigt HEAD auf einen Branch (z. B. main), und der Branch zeigt auf einen Commit. Wenn Sie direkt einen Commit auschecken, überspringt Git den Branch: HEAD zeigt jetzt direkt auf den Commit. Das ist der „losgelöste” (detached) Zustand.
Der Zustand ist harmlos, solange Sie nur schauen. Kritisch wird er erst, wenn Sie neue Commits erzeugen: Diese Commits gehören zu keinem Branch. Sobald Sie den detached HEAD verlassen, sind sie ohne Namen kaum wiederzufinden und werden irgendwann von Gits Garbage Collection entfernt.
Die Regel ist deshalb einfach: Nur ansehen? Alles gut. Etwas verändern und behalten? Vorher einen Branch anlegen.
Nur zurückkehren, ohne etwas zu ändern
Wenn Sie sich einen alten Stand nur angeschaut haben, kehren Sie so zu Ihrem Branch zurück:
git switch -
Das Minuszeichen bedeutet „der vorige Branch”. Alternativ nennen Sie den Branch direkt:
git switch main
Mit älterem Git (vor Version 2.23) verwenden Sie stattdessen git checkout main.
Am alten Commit weiterarbeiten – so retten Sie Ihre Änderungen
Wollen Sie ab dem alten Commit einen neuen Entwicklungszweig starten, legen Sie sofort einen Branch an:
git switch -c experiment-alt 9f8e7d6
-c steht für „create”. Der Befehl erstellt den Branch experiment-alt, der auf dem alten Commit basiert, und wechselt hinein. Ab jetzt sind Sie nicht mehr detached, und jeder Commit landet sicher in diesem Branch. Brauchen Sie das Experiment später nicht mehr, löschen Sie den Branch wieder.
Mit dem klassischen Befehl entspricht das:
git checkout -b experiment-alt 9f8e7d6
Falls Sie bereits im detached HEAD Änderungen committet haben und erst dann merken, dass ein Branch fehlt: Legen Sie ihn nachträglich genau an der aktuellen Stelle an, bevor Sie wegwechseln:
git switch -c gerettet
Nur eine einzelne Datei aus einem alten Commit holen
Häufig wollen Sie gar nicht das ganze Projekt zurückdrehen, sondern nur eine Datei aus einem früheren Stand zurückholen – etwa eine versehentlich gelöschte Konfiguration. Dafür ist seit Git 2.23 git restore gedacht:
git restore --source=9f8e7d6 config/settings.php
Die Datei config/settings.php wird auf den Stand jenes Commits gesetzt, alle anderen Dateien bleiben unberührt, und Sie bleiben auf Ihrem Branch. Kein detached HEAD. Die Änderung liegt danach als unstaged Change bereit; mit git add und git commit machen Sie sie dauerhaft.
Der ältere, gleichwertige Befehl:
git checkout 9f8e7d6 -- config/settings.php
checkout, switch, restore – warum es drei Befehle gibt
Bis Git 2.23 (Sommer 2019) machte git checkout gleich mehrere sehr verschiedene Dinge: den Branch wechseln, einen Commit auschecken und Dateien zurücksetzen. Weil das Verwechslungen und Datenverlust begünstigte, wurde die Funktion aufgeteilt:
git switch– zwischen Branches und Commits wechselngit restore– Dateiinhalte im Arbeitsverzeichnis wiederherstellengit checkout– bleibt erhalten und kann weiterhin beides, wird aber für neue Projekte nicht mehr empfohlen
git checkout verschwindet nicht und ist in keiner Weise „falsch”. Wenn Sie es gewohnt sind, funktioniert es weiter. Für neuen Code sind switch und restore aber eindeutiger und verzeihen mehr. Prüfen Sie Ihre Version mit git --version.
Typische Fehler und wie Sie sie lösen
„Your local changes would be overwritten by checkout”
Sie haben uncommittete Änderungen – welche, zeigt git status –, die der Wechsel überschreiben würde. Sichern Sie sie zwischen:
git stash
git switch 9f8e7d6
# ... ansehen ...
git switch -
git stash pop
git stash legt Ihre Änderungen auf einen Stapel und stellt das saubere Verzeichnis her; git stash pop holt sie zurück.
„error: pathspec ‘9f8e7d6’ did not match any file(s) known to git”
Den Commit gibt es nicht (Tippfehler im Hash) oder er ist noch nicht lokal vorhanden. Bei einem geklonten Repository hilft oft ein git fetch, um fehlende Historie nachzuladen.
Sie haben im detached HEAD committet und sind schon weggewechselt
Die verwaisten Commits sind meist noch da. git reflog listet, wo HEAD überall war, samt Hashes. Merken Sie sich den Hash und legen Sie einen Branch darauf an: git switch -c gerettet <hash>.
FAQ
Verliere ich Änderungen, wenn ich einen alten Commit auschecke? Committete Arbeit auf Ihrem Branch geht nicht verloren – der Branch behält seinen Stand, egal wo Sie hinschauen. Gefährdet sind nur neue Commits, die Sie im detached HEAD erzeugen, ohne dafür einen Branch anzulegen.
Wie sehe ich schnell die Unterschiede zwischen einem alten Commit und jetzt, ohne auszuchecken?
Mit git diff 9f8e7d6 vergleichen Sie den alten Commit direkt mit Ihrem aktuellen Arbeitsstand. Für einen einzelnen Commit zeigt git show 9f8e7d6, was dort geändert wurde – ganz ohne Wechsel.
Was ist der Unterschied zwischen git switch und git checkout?
git switch ist der neuere, auf Branch- und Commit-Wechsel spezialisierte Befehl (ab Git 2.23). git checkout kann dasselbe und zusätzlich Dateien wiederherstellen, ist dadurch aber missverständlicher. Funktional erreichen Sie mit beiden dasselbe Ziel.