git ready

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

Änderungen mit revert zurückrollen

eingetragen am 16 Mar 2009

Du hast alles erledigt. Vielleicht hattest du am Vormittag nicht genügend Kaffee oder es war kurz vor dem Mittagessen, doch irgendwie kam der Bug in das Repository und du möchtest ihn wieder raus bekommen. Glücklicherweise ist git revert das nötige Skalpell, um den kontaminierten Commit wieder heraus zu operieren.

Nehmen wir an, unsere Historie sieht wie folgt aus:

Der “revert”-Befehl arbeitet ungefährt so: Es werden alle Änderungen aus dem letzten Commit umgedreht und damit ein neuer Commit erzeugt. Um also den letzten Commit im aktuellen Branch zurückzurollen, reicht folgender Befehl:

$ git revert HEAD
Finished one revert.
[master]: created 1e689e2: 
  "Revert "Updated to Rails 2.3.2 and edge hoptoad_notifier""

Unser Repository würde dann ungefähr so aussehen:

Du kannst auch jeglichen Hash für jeden Commit übergeben, um dessen Änderungen zurückzurollen. Falls der Commit zum Zurückrollen nicht sauber angewendet werden kann, muss der Merge natürlich manuell aufgelöst werden.

Standardmäßig öffnet der Befehl deinen EDITOR, um die Commit-Nachricht des Reverts zum Zurückrollen der Änderungen zu bearbeiten. Nutze diese Gelegenheit, um das Zurückrollen der Änderungen kurz zu erläutern! Wenn du die Commit-Nachricht aus irgendwelchen Gründen nicht bearbeiten willst, wird das durch die Option --no-edit ermöglicht.

Eine andere nützliche Option ist das Argument -n oder --no-commit. Sie belässt die zurückgerollten Änderungen einfach in deinem Arbeitsverzeichnis und wendet sie nicht automatisch an. Wenn Dateien für die Vollendung des Reverts weiter bearbeitet oder mehrere Commits zurückgerollt werden müssen, ist diese Option genau richtig.

Das Zurückrollen von Merges ist etwas ärgerlich. Es kann sein, dass du folgende Nachricht beim Zurückrollen eines Merges bekommst:

$ git revert HEAD~1
fatal: Commit 137ea95 is a merge but no -m option was given.

Bei Merges musst du einen der zusammengeführten Commits auswählen, zu denen zurückgerollt werden soll. Mit der Option -m oder --mainline kannst du jenen Commit auswählen, der Teil der ‘Hauptlinie’ ist. Die Option erfordert ein nummerisches Argument und das kann etwas irreführend sein. Schauen wir uns den Merge-Commit von oben an:

$ git log HEAD~1 -1
commit 137ea95c911633d3e908f6906e3adf6372cfb0ad
Merge: 5f576a9... 62db4af...
Author: Nick Quaranto <nick@quaran.to>
Date:   Mon Mar 16 16:22:37 2009 -0400

    Merging in rails-2.3 branch

Wenn wir ein git revert HEAD~1 -m 1 durchführen, wird der erste Commit des Merges zurückgerollt (5f576a9). Die Option -m 2 wird den zweiten Commit zurückrollen (62db4af). Es gilt herauszufinden, welcher Commit zurückgerollt werden soll. Die standardmäßige Commit-Nachricht zeigt den Commit, der zurückgerollt wurde.

$ git revert HEAD~1 --no-edit --mainline 2
Finished one revert.
[master]: created 526b346: "Revert "Merging in rails-2.3 branch""

$ git log -1
commit d64d3983845dfa18a5d935c7ac5a4855c125e474
Author: Nick Quaranto <nick@quaran.to>
Date:   Mon Mar 16 19:24:45 2009 -0400

    Revert "Merging in rails-2.3 branch"

    This reverts commit 137ea95c911633d3e908f6906e3adf6372cfb0ad, reversing
    changes made to 62db4af8c77852d2cc9c19efc6dfb97e0d0067f5.

Die Git-Dokumentation schlägt einen Blick in diese Nachricht von Linus vor, wenn du etwas Hilfe beim Auflösen von Merges benötigst. Ich werde hoffentlich bald ein paar bessere Beiträge für diese Situationen haben. Wenn du andere großartige Verwendungen für das Zurückrollen von Commits hast (oder vielleicht sogar Horrorgeschichten oder wie es dich gerettet hat) lass es uns wissen!