Rollback einer Git-Zusammenführung

225
develop branch
--> dashboard (working branch)

Ich verwende git merge --no-ff develop, um vorgelagerte Änderungen im Dashboard zusammenzuführen

Git-Protokoll:

commit 88113a64a21bf8a51409ee2a1321442fd08db705
Merge: 981bc20 888a557
Author: XXXX <>
Date:   Mon Jul 30 08:16:46 2012 -0500

    Merge branch 'develop' into dashboard

commit 888a5572428a372f15a52106b8d74ff910493f01
Author: root <[email protected]>
Date:   Sun Jul 29 10:49:21 2012 -0500

    fixed end date edit display to have leading 0

commit 167ad941726c876349bfa445873bdcd475eb8cd8
Author: XXXX <>
Date:   Sun Jul 29 09:13:24 2012 -0500

Die Zusammenführung hatte mehr als 50 Commits und ich frage mich, wie ich die Zusammenführung einfach zurücksetzen kann, damit das Dashboard wieder zum Status vor der Zusammenführung zurückkehrt

Der zweite Teil davon ist, wenn ich nicht zusammenführe --no-ff, bekomme ich nicht das Commit " Zweig zusammenführen", das sich zu einem Dashboard entwickelt . Wie würde ich diese Zusammenführung zurücksetzen?

cgmckeever
quelle
3
Mögliches Duplikat von " Git-Zusammenführung rückgängig machen"? .

Antworten:

320

Das Zurücksetzen eines Zusammenführungs-Commits wurde in anderen Fragen ausführlich behandelt . Wenn Sie eine Schnellvorlaufzusammenführung durchführen, die zweite, die Sie beschreiben, können Sie verwenden git reset, um zum vorherigen Status zurückzukehren:

git reset --hard <commit_before_merge>

Sie können das finden <commit_before_merge>mit git reflog, git logoder, wenn Sie die moxy fühlen (und nicht getan haben etwas anderes):git reset --hard HEAD@{1}

Christopher
quelle
6
Vielen Dank für die schnelle Antwort. Wenn Sie sich das Git-Protokoll ansehen, ist das Commit vor dem Zusammenführen 50+ Commits zurück, da die Entwicklung des Git-Merges tatsächlich alle anderen Commits einfügt. Ich denke, was ich nicht bekomme, ist, wenn ich nicht weiß, was / wo diese Zusammenführung war - wie finde ich sie? Sie erwähnen das Finden des commit_before_merge. Ich glaube, ich verstehe diesen Teil nicht
cgmckeever
4
sieht aus wie mit git reflog sieht so aus, als würde es die letzten Köpfe gut zusammenfassen und mir ermöglichen zu wissen, wohin ich zurücksetzen muss. git log scheint zu granular zu sein, um den Ort zu bestimmen, an den zurückgesetzt werden soll. Danke
cgmckeever
1
Ja, reflogein Lebensretter. HEAD@{1}beschreibt nur den zweitletzten Zustand von HEAD oder eher technisch: "Ein Verweis gefolgt vom Suffix @ mit einer Ordnungszahl, die in einem Klammerpaar eingeschlossen ist (z. B. {1}, {15}), gibt den n-ten vorherigen Wert an ref. "
Christopher
4
Was ist mit dem Zurücksetzen auf Remote? Ich sehe nicht, wie es funktionieren wird.
Anton Savelyev
2
Das ist hoffnungslos. Es zerstört alle Commits nach dem Zusammenführen.
aaa90210
151

Von hier:

http://www.christianengvall.se/undo-pushed-merge-git/

git revert -m 1 <merge commit hash>

Git Revert fügt ein neues Commit hinzu, das das angegebene Commit zurücksetzt.

Die Verwendung von -m 1 zeigt an, dass dies eine Zusammenführung ist und wir ein Rollback zum übergeordneten Commit im Hauptzweig durchführen möchten. Sie würden -m 2 verwenden, um den Entwicklungszweig anzugeben.

Sturrockad
quelle
30
Beachten Sie, dass Sie den Zweig danach nicht erneut zusammenführen können, wie in den Dokumenten angegeben: "Durch das Zurücksetzen eines Zusammenführungs-Commits wird erklärt, dass Sie die durch die Zusammenführung eingebrachten Baumänderungen niemals möchten. Spätere Zusammenführungen führen daher nur eingeführte Baumänderungen ein durch Commits, die keine Vorfahren der zuvor rückgängig gemachten Zusammenführung sind. Dies kann das sein, was Sie wollen oder nicht. "
Dalibor Karlović
23
@ DaliborKarlović Diese Aussage ist etwas hart. Sie können diese Änderungen definitiv später zurückbringen. Der Trick besteht darin, das Zurücksetzen-Commit zurückzusetzen. Weitere Infos hier im Abschnitt "
Zurücksetzen
3
Leider ist der hereLink im @ Hilikus-Kommentar nicht mehr gültig. Die Site behauptet, der Inhalt sei in ein Buch verschoben worden ( git-scm.com/book/en/v2 ), aber wenn ja, ist es nicht trivial, dort zu suchen .
Jesse Chisholm
@ DaliborKarlović Ist dies der Fall mit der obigen Antwort von @Christopher?
James B
3
Das Verhängnis verschmilzt Inhalt wurde bewegt sich hier
SEK
28

Setzen Sie einfach das Zusammenführungs-Commit mit zurück git reset --hard HEAD^.

Wenn Sie --no-ff git verwenden, wird immer eine Zusammenführung erstellt, auch wenn Sie dazwischen nichts festgeschrieben haben. Ohne --no-ff führt git nur einen schnellen Vorlauf durch, was bedeutet, dass der HEAD Ihrer Zweige auf HEAD des zusammengeführten Zweigs gesetzt wird. Um dies zu beheben, suchen Sie die Commit-ID, zu der Sie zurückkehren möchten, und git reset --hard $COMMITID.

Nico Erfurth
quelle
1
Gute Lösung, wenn Sie das Commit vor dem Zusammenführen nicht kennen.
iglesiasedd
Arbeitete für mich, da ich keine Commit-ID kenne. + 1
Anant Singh --- Alive to Die
Wenn die unerwünschte Zusammenführung bereits auf Remote übertragen wurde, habe ich verwendet git push -f verwendet , um den Remote-Zweig nach dem Zurücksetzen zu aktualisieren.
Zumek
16
git revert -m 1 88113a64a21bf8a51409ee2a1321442fd08db705

Kann aber unerwartete Nebenwirkungen haben. Siehe --mainline parent-numberOption in git-scm.com/docs/git-revert

Ein brutaler, aber effektiver Weg wäre vielleicht, das linke übergeordnete Element dieses Commits auszuchecken, eine Kopie aller Dateien zu erstellen, HEADerneut auszuchecken und den gesamten Inhalt durch die alten Dateien zu ersetzen. Dann wird git Ihnen sagen, was zurückgesetzt wird und Sie erstellen Ihr eigenes Revert-Commit :)!

Jorge Orpinel
quelle
1
+1, da diese Antwort nicht wie beim Zurücksetzen mit dem Verlauf in Konflikt steht (sehr wichtig, wenn Sie bereits auf Remote geschoben haben). Aber welche unerwarteten Nebenwirkungen sollte ich erwarten?
Pedromanoel
3
Ist das die Nebenwirkung, die Sie erwähnt haben? Reverting a merge commit declares that you will never want the tree changes brought in by the merge. As a result, later merges will only bring in tree changes introduced by commits that are not ancestors of the previously reverted merge. This may or may not be what you want.
Pedromanoel
1
Sie sagen, git resetist die Lösung, erwähnen aber auch, dass es unerwartete Nebenwirkungen haben könnte. Dieser Link stammt jedoch git revertnicht von git reset:)
Mark
2
Bitte beachten Sie, dass Git Reset kein -m Flag hat. Beachten Sie auch, dass @JorgeOrpinel auf die git-revert-Dokumente verweist, nicht auf git-reset. Ich denke, er wollte git revertnicht sagengit reset
Devin Gleason Lambert
Es wurde angegeben, wie Mainline vermieden werden soll, aber Commit 1234xyz ist kein Zusammenführungsfehler .
Achal
0

Wenn Sie den Zweig zusammengeführt haben, haben Sie die Zusammenführung mithilfe einer Pull-Anforderung zurückgesetzt und diese Pull-Anforderung zum Zurücksetzen zusammengeführt.

Der einfachste Weg, den ich fühlte, war:

  1. Nehmen Sie einen neuen Zweig von Develop / Master heraus (wo Sie zusammengeführt haben).
  2. Setzen Sie das "Zurücksetzen" mit git revert -m 1 xxxxxx(wenn das Zurücksetzen über einen Zweig zusammengeführt wurde) oder mit zurückgit revert xxxxxx wenn es sich um ein einfaches Zurücksetzen handelte
  3. Der neue Zweig sollte nun die Änderungen enthalten, die Sie erneut zusammenführen möchten.
  4. Nehmen Sie Änderungen vor oder führen Sie diesen Zweig zusammen, um ihn zu entwickeln / zu beherrschen
Rohin Tak
quelle