Ein Durchlauf des Tutorials Verlorene Commits wiederherstellen: wie git reset --hard so wirken kann, als hätte es einen Commit gelöscht, und wie git reflog ihn wieder findet, damit Sie ihn zurückholen.
Dieses Szenario vermittelt die beruhigendste Tatsache in Git: Ein Commit, den Sie mit git reset --hard „verloren" haben, ist meist noch da. Sie sehen den Commit aus der Historie verschwinden und holen ihn mit git reflog zurück.
Die Situation
Git verknüpft jeden Commit mit seinem Vorgänger und speichert ihn per Hash, sodass nichts wirklich gelöscht wird.
Das Projekt hat drei Commits: Initial commit, Add header navigation und Add skills section. Nach einem git reset --hard, der einen Schritt zu weit ging, taucht der letzte Commit nicht mehr in git log auf. Er sieht aus, als wäre er gelöscht.
Ist er nicht. Der Reset hat den Branch-Zeiger zurückbewegt und den Add skills section-Commit unreferenziert an Ort und Stelle gelassen. Git erinnert sich weiterhin an ihn.
git reset --hard verwirft Arbeitsänderungen und bewegt den Branch, weshalb es sich destruktiv anfühlt. Das Commit-Objekt überlebt, aber der einzige einfache Weg zurück führt über das Reflog.
Die Wiederherstellung Schritt für Schritt
Sobald git reflog Ihnen den Hash liefert, zeigen Sie einen Branch wieder darauf, um den Commit wiederherzustellen.
Sehen, dass der Commit fehlt
git log
Das Log endet nun bei Add header navigation. Der Skills-Commit ist aus dieser Sicht verschwunden, und genau dieses Symptom beheben Sie.
Ihn im Reflog finden
git reflog
Das Reflog listet jede Bewegung von HEAD, einschließlich des Add skills section-Commits vor dem Reset. Notieren Sie seinen Hash (oder seine HEAD@{n}-Referenz).
Den Branch auf diesen Commit zurücksetzen
git reset --hard <commit-hash>
Den Branch auf den Hash des verlorenen Commits zu zeigen bringt Add skills section zurück in git log. Die Historie ist wieder vollständig.
Warum der Commit rettbar war
Ein Commit überlebt, solange etwas ihn referenziert, weshalb das Reflog ihn zurückholen kann.
git log und git reflog beantworten unterschiedliche Fragen:
git log zeigt Commits, die vom aktuellen Branch aus erreichbar sind. Ein Reset entfernt den Commit aus dieser Kette, sodass er hier verschwindet.
git reflog zeigt, wo HEAD überall war, mit oder ohne Branch. Der verlorene Commit ist hier weiterhin aufgeführt, mit dem Hash, den Sie brauchen.
Sie können entweder den rohen Hash oder die HEAD@{1}-artige Referenz aus dem Reflog kopieren. Beides funktioniert mit git reset --hard.
Das Reflog ist lokal in Ihrem Clone. Es ist ein persönliches Sicherheitsnetz, nicht mit dem Remote geteilt, und daher immer für Ihre eigenen Fehler verfügbar.
Verschiedene Arten verlorener Arbeit wiederherstellen
git reflog ist die erste Anlaufstelle für fast jeden „Ich habe es verloren"-Moment, weil es jede Position aufzeichnet, die HEAD eingenommen hat:
- Nach
git reset --hard — den Commit in git reflog finden, dann git reset --hard <hash>, um zu ihm zurückzukehren (oder git checkout <hash>, um zuerst zu schauen).
- Ein gelöschter Branch — seine Spitze ist noch im Reflog; legen Sie ihn mit
git branch <name> <hash> neu an.
- Ein misslungenes Rebase oder Amend — die Commits von vor dem Rebase sind im Reflog; setzen Sie auf den Eintrag von vor dessen Ausführung zurück.
- Wenn das Reflog ihn nicht mehr hat — Einträge verfallen (standardmäßig nach etwa 90 Tagen oder nach
git gc). git fsck --lost-found kann manchmal noch hängende Commits zutage fördern.
Probieren Sie es hier aus: einen Commit machen, ihn mit reset --hard wegwerfen und ihn dann aus dem Reflog zurückholen. Wenn Sie das einmal getan haben, ist reset --hard nicht mehr beängstigend.