Ein Durchlauf des Tutorials Einen Commit rückgängig machen: warum der letzte Commit kaputt ist und wie git reset --soft ihn ohne Arbeitsverlust korrigieren lässt.
Dieses Szenario beginnt in einem Portfolio-Projekt, in dem der letzte Commit subtil kaputt ist. Sie lesen die Historie, machen den Commit rückgängig, ohne Ihre Änderungen zu verlieren, und commiten ihn richtig neu. So sieht jeder Schritt aus und warum.
Die Situation
Das Projekt hat zwei Commits. Der jüngste, „Add header section", hat einen Navigations-Header zu index.html hinzugefügt. Das passende CSS für diesen Header wurde in style.css geschrieben, aber nie gestaged: Es liegt weiterhin als nicht commitete Änderung im Arbeitsbaum.
Der Commit ist also unvollständig. Die commitete Seite enthält Header-Markup, das auf nicht gespeicherte Styles verweist. Wer diesen Commit auscheckt, bekommt einen kaputten Header zu sehen.
Starten Sie mit git log --oneline und git status. Das Log zeigt den Commit „Add header section"; status zeigt style.css als modifiziert, aber nicht gestaged. Diese Diskrepanz ist das ganze Problem.
Die Korrektur Schritt für Schritt
Prüfen, was commitet wurde
git log bestätigt den letzten Commit, und git status zeigt, dass style.css immer noch im Arbeitsbaum modifiziert ist. Damit wissen Sie, dass der Commit index.html, aber nicht style.css erfasst hat.
Den Commit rückgängig machen, Änderungen behalten
git reset --soft HEAD~1
Das setzt den Branch-Zeiger um einen Commit zurück. Die index.html-Änderung, die im Commit war, kehrt in die Staging-Area zurück, bereit, erneut commitet zu werden. Nichts in Ihren Dateien wird gelöscht.
Diesmal alles stagen
git add index.html style.css
Markup und passende Styles sind nun gemeinsam gestaged, sodass der nächste Commit vollständig wird.
Die vollständige Änderung neu commiten
git commit -m "Add header section"
Die Historie hat wieder einen einzelnen Commit „Add header section", aber diesmal inklusive style.css. Die Seite ist heil.
Warum hier --soft richtig ist
git reset hat drei Modi; der Unterschied liegt nur darin, wo Ihre Änderungen landen:
--soft bewegt HEAD zurück und behält die Änderungen gestaged. Hier ideal, weil Sie sofort neu commiten wollen.
--mixed (Standard) behält die Änderungen, aber ungestaged, im Arbeitsbaum.
--hard verwirft die Änderungen vollständig.
git reset --hard HEAD~1 würde hier zusammen mit dem Commit auch die Header-Arbeit löschen. Greifen Sie zu --hard nur, wenn Sie die Änderungen wirklich loswerden wollen.
Falls Sie --hard versehentlich ausführen, ist der Commit meist noch mit git reflog rettbar, das jede Position auflistet, die HEAD eingenommen hat. Das Tutorial „Recover Lost Commits" behandelt diesen Weg.
Eine Einschränkung: geteilte Commits
Alles oben Genannte schreibt die Historie um, was bei einem nur lokal existierenden Commit völlig sicher ist. Sobald ein Commit gepusht und von anderen gepullt wurde, zwingt das Umschreiben alle in einen divergierten Branch. Auf einem geteilten Branch heben Sie die Änderung mit einem neuen Commit auf:
git revert HEAD