git ready

Lerne Git Commit für Commit
von Nick Quaranto, Übersetzung von Nico Gulden

Verlorene Commits wieder herstellen

eingetragen am 17 Jan 2009

Du hast ein git reset --hard HEAD^ durchgeführt und soeben deinen letzten Commit weg geworfen. Es stellt sich jedoch heraus, dass du diese Änderungen wirklich brauchst. Du wirst niemals in der Lage sein, den Algorithmus ein zweites Mal so perfekt zu implementieren, also willst du ihn zurück haben. Keine Panik! Git sollte den Commit noch haben. Wenn du einen Reset durchführst, geht der weggeworfene Commit in einen “baumelnden” Status über. Er befindet sich weiterhin in Gits Datenspeicher und wartet auf die nächste Müllsammlung (garbage collection), um aufgeräumt zu werden. Sofern du seit dem Wegwurf kein git gc ausgeführt hast, solltest du den Commit wieder herstellen können.

Für die Beispiele arbeite ich mit dem Code für dieses Blog:

$ git show-ref -h HEAD
  7c61179cbe51c050c5520b4399f7b14eec943754 HEAD

$ git reset --hard HEAD^
  HEAD is now at 39ba87b Fixing about and submit pages so they don't look stupid

$ git show-ref -h HEAD
  39ba87bf28b5bb223feffafb59638f6f46908cac HEAD

Unser HEAD ist um einen Commit zurück gesetzt worden. Mit git pull können wir einfach an diesen Punkt zurück kehren. Aber wir nehmen an, dass nur unser lokales Repository von dem Commit weiß. Wir benötigen den SHA1-Hash des Commits, um sie zurück zu holen. Mit dem fsck Befehl können wir zeigen, dass Git den Commit noch kennt:

$ git fsck --lost-found
  [... some blobs omitted ...]
  dangling commit 7c61179cbe51c050c5520b4399f7b14eec943754

Mit dem reflog Befehl kannst du ebenfalls sehen, dass Git den Commit noch kennt:

$ git reflog
  39ba87b... HEAD@{0}: HEAD~1: updating HEAD
  7c61179... HEAD@{1}: pull origin master: Fast forward
  [... lots of other refs ...]

Jetzt haben wir unseren SHA1-Hash: 7c61179. Wenn wir den Commit sofort in unseren aktuellen Branch zurück haben möchten, erledigt das git merge für uns:

$ git merge 7c61179
  Updating 39ba87b..7c61179
  Fast forward
    css/screen.css |    4 ++++
    submit.html    |    4 ++--
    2 files changed, 6 insertions(+), 2 deletions(-)

Dieser Befehlt holt unsere verlorenen Änderungen zurück und stellt sicher, das HEAD auf den Commit zeigt. Von hier aus kannst du mit der Arbeit normal fortfahren! Du kannst mit dem SHA1-Hash in einen neuen Branch beginnen, aber ein Merge ist die schnellste und einfachste Art, einen verlorenen Commit wieder herzustellen, sobald du den Hash hast. Wenn du andere Alternativen kennst, teile sie uns in den Kommentaren mit!

Wenn du dir weitere Optionen für diese Situation ansehen möchtest, so verfügt Mathieu Martin’s
illustrated guide to recovering lost commits with Git
über genügend Material.