Wie man lokale und entfernte Commits in Git sicher rückgängig macht

Meistern Sie wesentliche Git-Revisionskontrolltechniken, um Fehler lokal und remote sicher zu verwalten und zu korrigieren. Dieser Leitfaden beschreibt die Unterschiede zwischen `git reset` (zum Umschreiben des lokalen Verlaufs mit Soft-, Mixed- oder Hard-Modi) und `git revert` (zum sicheren Rückgängigmachen gemeinsam genutzter Commits). Lernen Sie, `git reflog` als Ihr ultimatives lokales Sicherheitsnetz zu nutzen und verstehen Sie Best Practices für Force Pushing.

34 Aufrufe

Wie man lokale und entfernte Commits in Git sicher rückgängig macht

Bei der Arbeit mit Git ist die Fähigkeit, Fehler zu korrigieren, grundlegend für einen reibungslosen Entwicklungsworkflow. Ob Sie zu früh einen Commit gemacht, versehentlich sensible Daten eingeschlossen haben oder einfach eine Reihe von Änderungen rückgängig machen müssen, das Verständnis, wie man lokale und entfernte Operationen sicher rückgängig macht, ist entscheidend. Dieser Leitfaden entschlüsselt die wichtigsten Werkzeuge für die Bereinigung der Revisionskontrolle: git reset, git revert und git reflog. Das Beherrschen dieser Befehle ermöglicht es Ihnen, Ihre Historie souverän zu verwalten und sicherzustellen, dass Sie Änderungen löschen oder rückgängig machen können, ohne wertvolle Arbeit zu verlieren.

Es ist von entscheidender Bedeutung, zwischen der Änderung der lokalen Historie (was im Allgemeinen sicher ist) und dem Überschreiben der geteilten Remote-Historie (was erhebliche Probleme für Kollaboratoren verursachen kann) zu unterscheiden. Wir werden uns auf die sichersten Methoden für beide Szenarien.

Die wichtigsten Werkzeuge zum Rückgängigmachen von Änderungen verstehen

Git bietet verschiedene Mechanismen, um mit Commits umzugehen, die Sie entfernen oder ändern möchten. Die Wahl des Werkzeugs hängt vollständig davon ab, ob der Commit bereits in ein geteiltes Repository gepusht wurde und ob Sie den Commit vollständig aus der Historie löschen oder einen neuen Commit einführen möchten, der seine Auswirkungen aufhebt.

1. git reset: Lokale Historie umschreiben

git reset ist das mächtigste (und potenziell gefährlichste) Werkzeug zur Manipulation der lokalen Commit-Historie. Es verschiebt den aktuellen Branch-Pointer (HEAD) auf einen anderen Commit. Der entscheidende Aspekt von git reset ist, wie es mit dem Staging-Bereich und dem Arbeitsverzeichnis umgeht, gesteuert durch die Optionen --soft, --mixed und --hard.

Modi von git reset

Modus Auswirkung auf HEAD Auswirkung auf den Staging-Bereich (Index) Auswirkung auf das Arbeitsverzeichnis
--soft Verschiebt den HEAD-Pointer. Unverändert. Unverändert.
--mixed (Standard) Verschiebt den HEAD-Pointer. Setzt sich zurück, um dem neuen HEAD zu entsprechen. Unverändert.
--hard Verschiebt den HEAD-Pointer. Setzt sich zurück, um dem neuen HEAD zu entsprechen. Setzt sich zurück, um dem neuen HEAD zu entsprechen (GEFAHR: Nicht-gespeicherte Änderungen gehen verloren).

Anwendungsfall: Verwenden Sie git reset, wenn Sie Änderungen lokal committet haben, von denen Sie feststellen, dass sie nicht hätten committet werden sollen, oder wenn Sie Änderungen unstagieren möchten, während Sie sie in Ihrem Arbeitsverzeichnis behalten.

Praktische Beispiele für git reset

A. Commit rückgängig machen (Änderungen gestaged lassen):
Wenn Sie einen Commit gemacht, aber festgestellt haben, dass Sie weitere Dateien hinzufügen mussten, bevor Sie pushen, verwenden Sie --soft:

# Verschiebt HEAD einen Commit zurück, behält aber die Änderungen gestaged (bereit, dem nächsten Commit hinzugefügt zu werden)
git reset --soft HEAD~1

B. Unstagieren und Änderungen lokal behalten:
Wenn Sie einen Commit gemacht haben und nun alles unstagieren, aber die Dateiänderungen in Ihrem Arbeitsverzeichnis behalten möchten:

# Verschiebt HEAD und unstagiert Änderungen, behält aber die Dateien in Ihrem Arbeitsbereich modifiziert
git reset --mixed HEAD~1
# oder einfach:
git reset HEAD~1

C. Vollständiges Löschen (GEFÄHRLICH für aktuelle Commits):
Wenn Sie den letzten Commit und alle seit diesem Commit vorgenommenen lokalen Änderungen vollständig verwerfen möchten (Rückkehr zum Zustand des vorherigen Commits):

# WARNUNG: Dies verwirft alle Arbeiten seit dem angegebenen Commit.
git reset --hard HEAD~1

⚠️ Warnung Best Practice: Verwenden Sie git reset --hard niemals für Commits, die bereits in ein geteiltes Remote-Repository gepusht wurden, es sei denn, Sie sind absolut sicher, dass niemand anderes auf diesen Commits aufgebaut hat. Das Umschreiben der geteilten Historie verursacht Kopfschmerzen für Kollaboratoren.

2. git revert: Sicher zurücknehmen von gepushten Commits

git revert ist die bevorzugte Methode, um Änderungen rückgängig zu machen, die bereits öffentlich geteilt wurden. Anstatt die Historie umzuschreiben, erstellt git revert einen neuen Commit, der die Änderungen eines bestimmten früheren Commits explizit rückgängig macht. Die Historie bleibt intakt, was es kollaborationsfreundlich macht.

Anwendungsfall: Verwenden Sie git revert, wenn Sie Änderungen zurücknehmen müssen, die bereits auf dem Remote-Server sind (z.B. eine Funktion, die einen Fehler eingeführt hat).

Praktisches Beispiel für git revert

Angenommen, der Commit-Hash a1b2c3d4 hat einen Fehler eingeführt. Um einen Commit zu erstellen, der seine Auswirkungen rückgängig macht:

# Erstellt einen neuen Commit, der die in a1b2c3d4 eingeführten Änderungen umkehrt
git revert a1b2c3d4

# Wenn Sie keinen Editor für die Revert-Commit-Nachricht öffnen möchten:
git revert -n a1b2c3d4
# Dann die Änderungen manuell committen
git commit -m "Revert: Fixed issue introduced by a1b2c3d4"

3. git reflog: Das Sicherheitsnetz

Was passiert, wenn Sie ein destruktives git reset --hard ausführen und feststellen, dass Sie gerade stundenlange Arbeit gelöscht haben? Hier kommt git reflog ins Spiel. Das Referenzprotokoll (reflog) verfolgt jede Änderung an HEAD in Ihrem lokalen Repository – jeden Commit, Reset, Merge und Checkout. Es ist Ihre lokale Undo-Historie.

Anwendungsfall: Wiederherstellung von Commits, die durch ein aggressives git reset verloren gegangen sind, oder Navigation zu einem temporären Zustand, den Sie zuvor besucht haben.

Anzeigen und Wiederherstellen mit git reflog

Sehen Sie sich zuerst Ihre Historie der HEAD-Bewegungen an:

$ git reflog

a1b2c3d HEAD@{0}: reset: moving to HEAD~2
4f5e6d7 HEAD@{1}: commit: Finished feature X
b8a9c0d HEAD@{2}: commit: Started implementation of feature X
...

Wenn Sie versehentlich über den Commit 4f5e6d7 hinaus zurückgesetzt haben (was HEAD@{1} war), können Sie ihn einfach wiederherstellen:

# Setzen Sie auf den Zustand zurück, in dem Sie sich einen Schritt vor der destruktiven Aktion befanden
git reset --hard HEAD@{1}

Tipp: git reflog-Einträge werden normalerweise 90 Tage lang lokal gespeichert. Es ist das ultimative lokale Sicherheitsnetz für Operationen, die reset oder Branch-Löschung beinhalten.

Rückgängigmachen von Remote-Änderungen (Force Push)

Wenn Sie git reset verwendet haben, um Commits zu entfernen, die bereits auf das Remote-Repository gepusht wurden, wird Ihre lokale Historie von der Remote-Historie abweichen. Git verhindert einen standardmäßigen git push, da dieser Non-Fast-Forward-Updates beinhaltet.

Um das Remote-Repository mit Ihrer neuen, umgeschriebenen lokalen Historie zu synchronisieren, müssen Sie einen Force Push verwenden.

# Verwenden Sie --force-with-lease als sicherere Alternative zu --force
git push origin <branch-name> --force-with-lease

Warum --force-with-lease verwenden?

--force-with-lease ist sicherer als die „blunt“ --force-Option. Es prüft, ob seit Ihrem letzten Pull niemand neue Commits auf den Remote-Branch gepusht hat. Wenn jemand das Remote-Repository in der Zwischenzeit aktualisiert hat, wird der Push abgelehnt, wodurch verhindert wird, dass Sie unwissentlich deren Arbeit löschen.

Zusammenfassung, wann welcher Befehl zu verwenden ist

Die Wahl des richtigen Werkzeugs hängt vom Zustand und Ziel Ihrer Commits ab:

  1. Lokale, nicht gepushte Commits: Verwenden Sie git reset (soft, mixed oder hard), um das Staging anzupassen oder die Historie vollständig zu löschen.
  2. Gepushte, geteilte Commits: Verwenden Sie git revert, um einen entgegenstehenden Commit zu erstellen und die öffentliche Historie zu bewahren.
  3. Versehentlicher Historienverlust: Verwenden Sie git reflog, um zuvor verlorene HEAD-Zustände zu finden und wiederherzustellen.
  4. Erzwingen von Remote-Updates: Verwenden Sie git push --force-with-lease nur, nachdem Sie die Historie lokal sicher mit git reset für gepushte Commits umgeschrieben haben.