Wie man einen spezifischen Git-Commit aus dem aktuellen Branch rückgängig macht und entfernt

GitGitBeginner
Jetzt üben

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einleitung

In diesem Labor lernen Sie, wie Sie Ihren Git-Commit-Verlauf verwalten. Sie üben das Rückgängigmachen von Änderungen mit git reset, das sichere Zurücksetzen öffentlicher Commits mit git revert und das Entfernen spezifischer Commits aus Ihrem Branch mithilfe eines interaktiven Rebase. Sie lernen auch, wie Sie das reflog verwenden, um entfernte Commits wiederherzustellen. Dies sind wesentliche Fähigkeiten, um einen sauberen und verständlichen Projektverlauf aufrechtzuerhalten.

Den Commit-Verlauf inspizieren

Bevor Sie den Verlauf ändern, müssen Sie zunächst wissen, wie Sie ihn anzeigen können. Der Befehl git log ist das primäre Werkzeug dafür. Für dieses Labor wurde ein Git-Repository mit mehreren Commits initialisiert, um den Verlauf eines realen Projekts zu simulieren.

Beginnen wir mit der Inspektion des Commit-Verlaufs. Wir verwenden das Flag --oneline, um jeden Commit in einer einzigen Zeile anzuzeigen, und --graph, um den Commit-Verlauf als Graph darzustellen, was nützlich ist, um Branches und Merges zu visualisieren.

Führen Sie den folgenden Befehl in Ihrem Terminal aus:

git log --oneline --graph

Sie sollten eine Liste der fünf Commits sehen, die für Sie erstellt wurden, wobei der aktuellste Commit oben steht. Jede Zeile zeigt einen eindeutigen Commit-Hash (eine Kurzform davon) und die Commit-Nachricht an.

* 7d3d24a (HEAD -> master) chore: Add last-commit file
* 8a9f1b3 docs: Update documentation in file1
* c2e4d6f fix: Add a temporary file that should be removed
* 5e1a3b2 feat: Add file2.txt
* 1b4c0a9 feat: Add file1.txt

Hinweis: Ihre Commit-Hashes werden sich von dem obigen Beispiel unterscheiden. Dies ist zu erwarten, da jeder Hash eindeutig ist.

Nehmen Sie sich einen Moment Zeit, um den Verlauf zu überprüfen. Sie werden diese Commits in den folgenden Schritten bearbeiten.

Den letzten Commit mit git reset rückgängig machen

Manchmal macht man einen Commit und stellt sofort fest, dass man einen Fehler gemacht hat. Der Befehl git reset ist perfekt für dieses Szenario. Er kann den HEAD-Zeiger des aktuellen Branches auf einen früheren Commit verschieben und damit einen oder mehrere Commits effektiv "rückgängig machen".

Wir werden die Option --soft verwenden, die den Commit rückgängig macht, aber die Änderungen aus diesem Commit in Ihrem Staging-Bereich (dem Index) belässt. Dies ist nützlich, wenn Sie die Änderungen erneut committen möchten, vielleicht mit einer anderen Nachricht oder kombiniert mit anderen Änderungen.

Machen wir den letzten Commit, "chore: Add last-commit file", rückgängig.

git reset --soft HEAD~1

Hier bezieht sich HEAD~1 auf den Commit direkt vor dem aktuellen HEAD.

Überprüfen Sie nun den Status Ihres Repositories:

git status

Sie werden sehen, dass last-commit.txt nun unter "Changes to be committed" aufgeführt ist. Das bedeutet, dass der Commit selbst rückgängig gemacht wurde, aber die Dateiänderungen sind immer noch gestaged.

On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	new file:   last-commit.txt

Zeigen Sie abschließend erneut den Log an, um zu bestätigen, dass der Commit aus dem Verlauf entfernt wurde:

git log --oneline --graph
* 8a9f1b3 (HEAD -> master) docs: Update documentation in file1
* c2e4d6f fix: Add a temporary file that should be removed
* 5e1a3b2 feat: Add file2.txt
* 1b4c0a9 feat: Add file1.txt

Wie Sie sehen können, wurde der letzte Commit aus dem Log entfernt, aber Ihre Arbeit wartet sicher im Staging-Bereich.

Einen Commit mit git revert rückgängig machen

Während git reset großartig für lokale Änderungen ist, schreibt es den Verlauf neu, was problematisch sein kann, wenn Sie Ihre Commits bereits mit anderen geteilt haben. Eine sicherere Methode, um Änderungen an einem öffentlichen Branch rückgängig zu machen, ist git revert. Dieser Befehl erstellt einen neuen Commit, der die Umkehrung der Änderungen eines bestimmten Commits anwendet.

Zuerst bereinigen wir unser Arbeitsverzeichnis, indem wir die Änderungen aus dem vorherigen Schritt erneut committen.

git commit -m "chore: Add last-commit file again"

Nehmen wir nun an, wir möchten den Commit rückgängig machen, der file2.txt hinzugefügt hat. Dieser Commit liegt weiter zurück in unserem Verlauf. Wir werden ihn rückgängig machen. Wir können ihn anhand seiner Position relativ zu HEAD referenzieren. Wenn wir den Log aus Schritt 1 betrachten, ist "feat: Add file2.txt" der vierte Commit von oben, daher können wir ihn als HEAD~3 referenzieren.

Führen Sie den Revert-Befehl aus:

git revert HEAD~3

Dies öffnet Ihren Standard-Texteditor (standardmäßig vim) mit einer vorab ausgefüllten Commit-Nachricht wie "Revert 'feat: Add file2.txt'". Sie können die Datei einfach speichern und schließen, um die Standardnachricht zu akzeptieren.

In vim geben Sie :wq ein und drücken Sie Enter, um zu speichern und zu beenden.

Überprüfen Sie nun erneut den Log:

git log --oneline --graph

Sie werden einen neuen Commit oben sehen: "Revert 'feat: Add file2.txt'".

* 1e2d3f4 (HEAD -> master) Revert "feat: Add file2.txt"
* 7d3d24a chore: Add last-commit file again
* 8a9f1b3 docs: Update documentation in file1
* c2e4d6f fix: Add a temporary file that should be removed
* 5e1a3b2 feat: Add file2.txt
* 1b4c0a9 feat: Add file1.txt

Der ursprüngliche Commit ist immer noch im Verlauf vorhanden, aber seine Änderungen wurden durch den neuen Revert-Commit rückgängig gemacht. Sie können dies überprüfen, indem Sie die Dateien im Verzeichnis auflisten.

ls

Sie werden feststellen, dass file2.txt nicht mehr vorhanden ist.

Einen Commit mit interaktivem Rebase entfernen

Für komplexere Verlaufsmanipulationen, wie das Entfernen eines Commits aus der Mitte eines Branches, können Sie den interaktiven Rebase (git rebase -i) verwenden. Dies ist ein sehr mächtiger Befehl, der den Commit-Verlauf umschreibt, daher sollte er mit Vorsicht verwendet werden, insbesondere bei Branches, die mit anderen Entwicklern geteilt werden.

Unser Ziel ist es, den Commit mit der Nachricht "fix: Add a temporary file that should be removed" zu entfernen. Wenn wir uns den aktuellen Log ansehen, ist dieser Commit nun HEAD~3.

Starten Sie den interaktiven Rebase-Prozess:

git rebase -i HEAD~4

Dieser Befehl öffnet Ihren Texteditor (standardmäßig vim) mit einer Liste der letzten 4 Commits.

pick fd5a181 fix: Add a temporary file that should be removed
pick 5f27a4d docs: Update documentation in file1
pick 284be6f chore: Add last-commit file again
pick 8a460c5 Revert "feat: Add file2.txt"

## Rebase 9403080..8a460c5 onto 9403080 (4 commands)
#
## Commands:
## p, pick <commit> = use commit
## d, drop <commit> = remove commit
## ...

Um den Commit zu entfernen, ändern Sie das Wort pick in drop (oder d) für die Zeile, die "fix: Add a temporary file that should be removed" enthält.

Ändern Sie dies:

pick fd5a181 fix: Add a temporary file that should be removed

Zu diesem:

drop fd5a181 fix: Add a temporary file that should be removed

Drücken Sie in vim i, um in den Einfügemodus zu wechseln, nehmen Sie Ihre Änderungen vor, und drücken Sie dann Esc, um den Einfügemodus zu verlassen. Speichern und beenden Sie, indem Sie :wq eingeben und Enter drücken. Git wird die verbleibenden Commits auf den neuen Verlauf anwenden.

Überprüfen Sie den Log, um das Ergebnis zu sehen:

git log --oneline --graph

Der "schlechte" Commit ist nun aus dem Verlauf verschwunden.

* a5b4c3d (HEAD -> master) chore: Add last-commit file again
* f9e8d7c docs: Update documentation in file1
* 1e2d3f4 Revert "feat: Add file2.txt"
* 5e1a3b2 feat: Add file2.txt
* 1b4c0a9 feat: Add file1.txt

Überprüfen Sie auch die Dateien im Verzeichnis. Die Datei bad-commit-file.txt wurde entfernt.

ls

Einen entfernten Commit mit git reflog wiederherstellen

Was passiert, wenn Sie versehentlich einen Commit entfernen? Git speichert eine Aufzeichnung aller Änderungen am HEAD-Zeiger in einem speziellen Log, dem reflog. Dies ist Ihr Sicherheitsnetz. Sie können es verwenden, um verlorene Commits zu finden und wiederherzustellen.

Betrachten wir das Reflog, um den gerade umgeschriebenen Verlauf zu finden.

git reflog

Sie sehen eine Liste der von Ihnen durchgeführten Aktionen. Suchen Sie nach der Zeile, die rebase (finish): returning to refs/heads/master anzeigt. Der Eintrag direkt darunter, wahrscheinlich HEAD@{1}, repräsentiert den Zustand Ihres Branches vor dem Rebase.

a5b4c3d (HEAD -> master) HEAD@{0}: rebase (finish): returning to refs/heads/master
1e2d3f4 HEAD@{1}: rebase (start): checkout HEAD~3
...

Wir können unseren Branch mit git reset --hard in diesen vorherigen Zustand zurückversetzen. Dieser Befehl ist destruktiv und verwirft alle uncommitted Änderungen, verwenden Sie ihn also vorsichtig.

Setzen wir unseren Branch auf den Zustand vor dem Rebase zurück, der in diesem Fall HEAD@{1} ist.

git reset --hard HEAD@{1}

Sie sehen eine Meldung, die bestätigt, dass HEAD nun auf dem Commit vor dem Start des Rebase liegt.

HEAD is now at 1e2d3f4 Revert "feat: Add file2.txt"

Überprüfen Sie nun ein letztes Mal den Log:

git log --oneline --graph

Sie sollten den Verlauf so sehen, wie er vor dem Rebase war:

* f461400 (HEAD -> master) Revert "feat: Add file2.txt"
* acea45c chore: Add last-commit file again
* c04b3f5 docs: Update documentation in file1
* 9403080 feat: Add file2.txt
* ee39412 feat: Add file1.txt

Beachten Sie, dass der Commit "fix: Add a temporary file that should be removed" immer noch nicht vorhanden ist – das ist korrekt! Der Befehl git reset --hard HEAD@{1} hat uns in den Zustand vor dem Start des interaktiven Rebase zurückversetzt, nicht vor das Entfernen des Commits. Der interaktive Rebase hat diesen unerwünschten Commit erfolgreich aus unserem Verlauf entfernt. Sie können ls ausführen, um zu bestätigen, dass bad-commit-file.txt immer noch nicht vorhanden ist. Das reflog ist ein unschätzbar wertvolles Werkzeug zur Wiederherstellung von Fehlern in Git.

Zusammenfassung

In diesem Lab haben Sie praktische Techniken zur Verwaltung Ihres Git-Commit-Verlaufs gelernt. Sie haben mit der Inspektion des Verlaufs mit git log begonnen. Anschließend haben Sie das Rückgängigmachen von Commits mit git reset --soft, das sichere Rückgängigmachen von Änderungen mit git revert und das Entfernen spezifischer Commits mit dem mächtigen Befehl git rebase -i geübt. Schließlich haben Sie gelernt, wie Sie git reflog als Sicherheitsnetz verwenden, um Commits wiederherzustellen, die aus dem Verlauf entfernt wurden. Diese Fähigkeiten sind unerlässlich, um einen sauberen und überschaubaren Projektverlauf aufrechtzuerhalten.