1647 Stimmen

Wie kann man mehrere Git-Commits rückgängig machen?

Ich habe ein Git-Repository, das wie folgt aussieht:

A <- B <- C <- D <- HEAD

Ich möchte, dass der Kopf der Verzweigung auf A zeigt, d.h. ich möchte, dass B, C, D und HEAD verschwinden, und ich möchte, dass head ein Synonym für A ist.

Es klingt so, als ob ich entweder versuchen könnte, neu zu basen (trifft nicht zu, da ich zwischendurch Änderungen vorgenommen habe) oder zu revertieren. Aber wie kann ich mehrere Übertragungen rückgängig machen? Mache ich einen nach dem anderen rückgängig? Ist die Reihenfolge wichtig?

2093voto

Jakub Narębski Punkte 286531

Ich erweitere, was ich in einem Kommentar geschrieben habe

Die allgemeine Regel lautet, dass Sie eine Geschichte, die Sie veröffentlicht haben, nicht umschreiben (ändern) sollten, weil jemand seine Arbeit darauf aufgebaut haben könnte. Wenn Sie die Geschichte umschreiben (ändern), würden Sie Probleme beim Zusammenführen ihrer Änderungen und bei der Aktualisierung für sie verursachen.

Die Lösung besteht also darin, eine neue Verpflichtung die macht Änderungen rückgängig die Sie loswerden wollen. Sie können dies tun mit mit einem Git rückgängig machen Befehl.

Sie haben die folgende Situation:

A <-- B  <-- C <-- D                                  <-- master <-- HEAD

(Pfeile beziehen sich hier auf die Richtung des Zeigers: die "übergeordnete" Referenz im Fall von Commits, die oberste Commit im Fall von Branch Head (Branch Ref) und der Name des Branch im Fall von HEAD Reference).

Sie müssen Folgendes erstellen:

A <-- B  <-- C <-- D <-- \[(BCD)\-1\]                   <-- master <-- HEAD

donde [(BCD)^-1] bedeutet die Übergabe, die Änderungen in den Übergaben B, C, D rückgängig macht. Die Mathematik sagt uns, dass (BCD) -1 \= D -1 C -1 B -1 So können Sie mit den folgenden Befehlen die gewünschte Situation herstellen:

$ git revert --no-commit D
$ git revert --no-commit C
$ git revert --no-commit B
$ git commit -m "the commit message for all of them"

Funktioniert für alles außer Merge Commits.


Eine alternative Lösung wäre, dass Zur Kasse Inhalt der Übergabe A, und übergeben Sie diesen Zustand. Funktioniert auch mit Merge-Commits. Hinzugefügte Dateien werden jedoch nicht gelöscht. Wenn Sie irgendwelche lokalen Änderungen haben git stash sie zuerst:

$ git checkout -f A -- . # checkout that revision over the top of local files
$ git commit -a

Dann ergibt sich die folgende Situation:

A <-- B  <-- C <-- D <-- A'                       <-- master <-- HEAD

Die Übergabe A' hat denselben Inhalt wie Übergabe A, ist aber eine andere Übergabe (Übergabemeldung, Eltern, Übergabedatum).


Alternative Lösung von Jeff Ferland, geändert von Charles Bailey baut auf der gleichen Idee auf, verwendet aber Git-Reset . Hier ist es leicht modifiziert, dieser Weg funktioniert für alles:

$ git reset --hard A
$ git reset --soft D # (or ORIG_HEAD or @{1} [previous location of HEAD]), all of which are D
$ git commit

722voto

deepdive Punkte 7699

Sauberer Weg, den ich nützlich fand

git revert --no-commit HEAD~3..
git commit -m "your message regarding reverting the multiple commits"

Dieser Befehl macht die letzten 3 Commits mit nur einem Commit rückgängig.

Außerdem wird die Geschichte nicht umgeschrieben, so dass kein Force Push erforderlich ist.

El .. trägt zur Schaffung einer Reichweite bei. Bedeutung HEAD~3.. ist dasselbe wie HEAD~3..HEAD

286voto

Victor Punkte 2719

Dazu müssen Sie lediglich die zurückkehren und geben Sie den Bereich von Commits an, die Sie rückgängig machen wollen.

In Anbetracht Ihres Beispiels müssten Sie dies tun (vorausgesetzt, Sie befinden sich auf dem Zweig "master"):

git revert master~3..master

o git revert B...D o git revert D C B

Dies erzeugt einen neuen Commit in Ihrem lokalen Verzeichnis mit dem umgekehrten Commit von B, C und D (was bedeutet, dass die Änderungen, die durch diese Commits eingeführt wurden, rückgängig gemacht werden):

A <- B <- C <- D <- BCD' <- HEAD

112voto

Jeff Ferland Punkte 17180
git reset --hard a
git reset --mixed d
git commit

Dadurch werden sie alle auf einmal rückgängig gemacht. Geben Sie eine gute Commit-Nachricht.

107voto

konyak Punkte 9408

Ähnlich wie bei Jakubs Antwort können Sie so einfach aufeinanderfolgende Commits zum Revertieren auswählen.

# revert all commits from and including B to HEAD, inclusively
$ git revert --no-commit B^..HEAD  
$ git commit -m 'message'

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X