Git
Chapters ▾ 2nd Edition

2.4 Git Grundlagen - Ungewollte Änderungen rückgängig machen

Ungewollte Änderungen rückgängig machen

Es kommt sicherlich irgendwann der Zeitpunkt, an dem du eine Änderung rückgängig (engl. undo) machen willst. Wir werden hier einige grundlegende Werkzeuge besprechen, mit denen du genau das tun kannst. Sei vorsichtig, man kann diese Aktionen nicht immer rückgängig machen. Das ist einer der wenigen Bereiche in Git, in denen du Arbeit verlieren könntest, wenn du etwas falsch machst.

Eines der häufigsten Undos tritt auf, wenn du zu früh committest und möglicherweise vergessen hast, einige Dateien hinzuzufügen, oder wenn du Fehler in deiner Commit-Nachricht hast. Wenn du diesen Commit wiederholen möchtest, nimm zusätzlichen Änderungen vor, die du vergessen hast, stage Sie und committe erneut mit der Option --amend:

$ git commit --amend

Dieser Befehl übernimmt deine Staging-Area und verwendet sie für den Commit. Wenn du seit deinem letzten Commit keine Änderungen vorgenommen hast (z.B. du führst diesen Befehl unmittelbar nach deinem vorherigen Commit aus), dann sieht dein Snapshot genau gleich aus; du änderst nur deine Commit-Nachricht.

Der gleiche Commit-Message-Editor wird aufgerufen, enthält aber bereits die Nachricht deines vorherigen Commits. Du kannst die Nachricht wie gewohnt bearbeiten, aber sie überschreibt den vorherigen Commit.

Wenn du beispielsweise einen Commit durchführst und dann feststellst, dass du vergessen hast, eine Datei zu ändern, könntest du Folgendes tun:

$ git commit -m 'Initial commit'
$ git add forgotten_file
$ git commit --amend

Du erhälst am Ende einen einzigen Commit – der zweite Commit ersetzt die Ergebnisse des Ersten.

Anmerkung

Es ist wichtig zu verstehen: wenn du deinen letzten Commit änderst, korrigierst du ihn nicht. Du ersetzt ihn durch einen neuen, verbesserten Commit. Der alte Commit wird entfernt und der neue Commit an seine Stelle gesetzt. Tatsächlich ist es so, als ob der letzte Commit nie stattgefunden hätte und er nicht mehr in deinem Repository-Verlauf auftaucht.

Der naheliegendste Nutzen für die Änderung von Commits besteht darin, kleine Verbesserungen an deinem letzten Commit vorzunehmen, ohne dein Repository-Verlauf mit Commit-Nachrichten der Form „Ups, vergessen, eine Datei hinzuzufügen“ oder „Verdammt, einen Tippfehler im letzten Commit behoben“ zu überladen.

Anmerkung

Änderne nur lokale Commits, die noch nicht gepusht wurden. Das Ändern zuvor übertragener Commits und das forcierte pushen des Branches verursacht Probleme bei ihren Mitstreitern. Weitere Informationen darüber, was dabei passiert und wie du es wieder gerade ziehen kannst, wenn du dich auf der Empfängerseite befinden, findest du unter Die Gefahren des Rebasing.

Eine Datei aus der Staging-Area entfernen

Die nächsten beiden Abschnitte erläutern, wie du mit deiner Staging-Area und den Änderungen des Arbeitsverzeichnisses arbeitest. Der angenehme Nebeneffekt ist, dass der Befehl, mit dem du den Zustand dieser beiden Bereiche bestimmst, dich auch daran erinnert, wie du Änderungen an ihnen rückgängig machen kannst. Nehmen wir zum Beispiel an, du hast zwei Dateien geändert und möchtest sie als zwei separate Änderungen übertragen, aber du gibst versehentlich git add * ein und stellst sie dann beide in der Staging-Area bereit. Wie kannst du eine der beiden aus der Staging-Area entfernen? Der Befehl git status meldet:

$ git add *
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    README.md -> README
    modified:   CONTRIBUTING.md

Direkt unter dem Text „Changes to be committed“, steht, dass man git reset HEAD <file>…​ verwenden soll, um die Staging-Area zu entleeren. Lass uns also diesem Rat folgen und die Datei CONTRIBUTING.md aus der Staging-Area entfernen:

$ git reset HEAD CONTRIBUTING.md
Unstaged changes after reset:
M	CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    README.md -> README

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   CONTRIBUTING.md

Der Befehl klingt etwas merkwürdig, aber er funktioniert. Die Datei CONTRIBUTING.md ist modifiziert und wieder im Status unstaged überführt.

Anmerkung

Es stimmt, dass git reset ein riskanter Befehl sein kann, besonders, wenn du das --hard Flag mitgibst. In dem oben beschriebenen Szenario wird die Datei in deinem Arbeitsverzeichnis jedoch nicht angetastet, so dass er relativ sicher ist.

Im Moment ist dieser Aufruf alles, was du über den Befehl git reset wissen musst. Wir werden viel ausführlicher darauf eingehen, was reset bewirkt und wie man damit umgeht, um wirklich interessante Aufgaben zu erledigen, siehe Kapitel 7 Git Reset.

Änderung in einer modifizierten Datei zurücknehmen

Was ist, wenn du feststellst, dass du deine Änderungen an der Datei CONTRIBUTING.md nicht behalten willst? Wie kannst du sie in den Ursprungszustand zurücksetzen, so wie sie beim letzten Commit ausgesehen hat (oder anfänglich geklont wurde, oder wie auch immer du sie in dein Arbeitsverzeichnis bekommen hast)? Glücklicherweise sagt dir git status, wie du das machen kannst. Im letzten Beispiel sieht die Unstaged-Area so aus:

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   CONTRIBUTING.md

Git erklärt dir, wie du die von dir vorgenommenen Änderungen verwerfen kannst. Lassen es uns ausführen:

$ git checkout -- CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    README.md -> README

Wie du siehst, wurde die Änderungen rückgängig gemacht.

Wichtig

Es ist sehr wichtig zu begreifen, dass git checkout -- <file> ein riskanter Befehl ist. Alle lokalen Änderungen, die du an dieser Datei vorgenommen hast, sind verloren – Git hat diese Datei einfach durch die zuletzt committete oder gestagte Version ersetzt. Verwenden diesen Befehl nur, wenn du dir absolut sicher bist, dass du diese nicht gespeicherten lokalen Änderungen nicht benötigst.

Wenn du die Änderungen, die du an dieser Datei gemacht hast, beibehalten möchten, sie aber vorerst aus dem Weg räumen willst, sollten wir das Stashing und Branching in Kapitel 3 – Git Branching durchgehen; das sind im Allgemeinen die besseren Methoden, um das zu erledigen.

Denke daran, dass alles, was in Git committet wird, fast immer wiederhergestellt werden kann. Sogar Commits, die auf gelöschten Branches lagen oder Commits, die mit einem --amend Commit überschrieben wurden, können wiederhergestellt werden (siehe Kapitel 10 Daten-Rettung für das Wiederherstellen der Daten). Aber: alles, was du verworfen und nie committet hast, wirst du wahrscheinlich nie wieder sehen.

Änderungen mit git restore Rückgängig machen

Git Version 2.23.0 führte einen neuen Befehl ein: git restore. Es ist im Grunde eine Alternative zu git reset, die wir gerade behandelt haben. Ab Git Version 2.23.0 verwendet Git für viele dieser Vorgänge git restore anstelle von git reset.

Lasse uns unsere Schritte wiederholen und die Dinge mit git restore anstelle von git reset rückgängig machen.

Eine Datei mit git restore unstagen

Die nächsten beiden Abschnitte zeigen, wie du an Änderungen in deinem Staging-Bereich und im Arbeitsverzeichnisses mit git restore arbeitest. Das Schöne daran ist, dass der Befehl, mit dem du den Status dieser beiden Bereiche bestimmst, dir auch zeigt, wie du Änderungen an ihnen rückgängig machen kannst. Angenommen, du hast zwei Dateien geändert und möchtest sie als zwei separate Änderungen committen. Du gibst jedoch versehentlich git add * ein und committest beide. Wie kannst du eine der beiden wieder unstagen? Der Befehl git status zeigt folgendes:

$ git add *
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   CONTRIBUTING.md
	renamed:    README.md -> README

Direkt unter dem Text „Changes to be committed“ steht git restore --staged <file> …​ zum unstagen. Verwenden wir diesen Rat, um die Datei CONTRIBUTING.md zu unstagen:

$ git restore --staged CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	renamed:    README.md -> README

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   CONTRIBUTING.md

Die Datei CONTRIBUTING.md ist modifiziert und wieder im Status unstaged überführt.

Eine geänderte Datei mit git restore rückgängig machen

Was ist, wenn du merkst, dass du deine Änderungen an der Datei CONTRIBUTING.md nicht beibehalten willst? Wie kannst du sie in den Ursprungszustand zurücksetzen, so wie sie beim letzten Commit ausgesehen hat (oder anfänglich geklont wurde, oder wie auch immer du sie in dein Arbeitsverzeichnis bekommen hast)? Glücklicherweise sagt dir git status, wie du das machen kannst. Im letzten Beispiel sieht die Unstaged-Area so aus:

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   CONTRIBUTING.md

Git erklärt dir, wie du die von dir vorgenommene Änderungen verwerfen kannst. Lassen es uns ausführen:

$ git restore CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	renamed:    README.md -> README
Wichtig

Es ist wichtig zu verstehen, dass git restore <file> ein gefährlicher Befehl ist. Alle lokalen Änderungen, die du an dieser Datei vorgenommen hast, sind weg. Git hat diese Datei durch die zuletzt committete oder gestagte Version ersetzt. Verwende diesen Befehl nur, wenn du dir absolut sicher bist, dass du diese nicht gespeicherten lokalen Änderungen nicht benötigst.

scroll-to-top