Git entfernen Merge Commit aus dem Verlauf

94

Meine Git-Geschichte sieht so aus:

Git Geschichte

Ich möchte die lila Commits zu einem einzigen zusammenfassen. Ich möchte sie nie wieder in meinem Festschreibungsprotokoll sehen.

Ich habe versucht, ein zu machen git rebase -i 1, aber obwohl 1es sich auf dem blauen Zweig befindet (siehe Bild), sehe ich immer noch jedes Commit auf meinem lila Zweig.

Wie kann ich den lila Zweig (aus dem Festschreibungsprotokoll) vollständig entfernen?

Benjamin Toueg
quelle
Wird Ihr Repo irgendwohin geschoben, wo andere Leute es herausgezogen haben?
Schleis
Beide Niederlassungen sind rein lokal.
Benjamin Toueg

Antworten:

100

Auf git rebase -i <sha before the branches diverged>diese Weise können Sie das Zusammenführungs-Commit entfernen und das Protokoll besteht aus einer einzelnen Zeile, wie Sie möchten. Sie können auch alle Commits löschen, die Sie nicht mehr möchten. Der Grund, warum Ihre Rebase nicht funktionierte, war, dass Sie nicht weit genug zurückgingen.

WARNUNG: Sie schreiben dabei den Verlauf neu. Wenn Sie dies mit Änderungen tun, die auf ein Remote-Repo übertragen wurden, treten Probleme auf. Ich empfehle, dies nur mit lokalen Commits zu tun.

Schleis
quelle
4
Selbst wenn ich einen Sha wähle, bevor die Zweige auseinander gegangen sind, sehe ich alle Commits des lila Zweigs -_-
Benjamin Toueg
1
Ja, dann löschst du sie im Editor, der sie erstellt, git rebaseund sie werden entfernt.
Schleis
4
Das Löschen der Commits führte dazu, dass alle Änderungen an der Zusammenführung verloren gingen. Aber ich habe einen Soft-Reset durchgeführt und konnte etwas ganz so haben, wie ich es wollte (Bestellung entspricht nicht den ursprünglichen Erwartungen).
Benjamin Toueg
2
Diese Antwort ist im Detail unvollständig. Von welchem ​​Zweig aus initiieren Sie die Rebase?
grgry
2
Ziemlich sicher, dass Sie die Commits nicht "entfernen" möchten. 'Entfernen' ist keine Option in Rebase, aber Löschen ist. Wenn Sie ein Commit löschen, verlieren Sie die eingeführten Änderungen. Sie möchten die Commits quetschen.
Thecoshman
69

Beginnend mit dem Repo im Originalzustand

Ursprüngliche Repo-Geschichte

So entfernen Sie das Zusammenführungs-Commit und quetschen den Zweig zu einem einzigen Commit in der Hauptzeile

Squashed Commits, kein Merge Commit

Verwenden Sie diese Befehle (ersetzen Sie 5 und 1 durch die SHAs der entsprechenden Commits):

git checkout 5
git reset --soft 1
git commit --amend -m '1 2 3 4 5'
git rebase HEAD master

So behalten Sie ein Merge-Commit bei, aber quetschen Sie die Branch-Commits zu einem:

Squashed Commits, beibehaltenes Merge Commit

Verwenden Sie diese Befehle (ersetzen Sie 5, 1 und C durch die SHAs der entsprechenden Commits):

git checkout -b tempbranch 5
git reset --soft 1
git commit --amend -m '1 2 3 4 5'
git checkout C
git merge --no-ff tempbranch
git rebase HEAD master

So entfernen Sie das Zusammenführungs-Commit und ersetzen es durch einzelne Commits aus dem Zweig

Zweig in Hauptleitung verschoben, kein Zusammenführungs-Commit

Tun Sie dies einfach (ersetzen Sie 5 durch die SHA des entsprechenden Commits):

git rebase 5 master

Und schließlich, um den Zweig vollständig zu entfernen

Zweig vollständig entfernt

Verwenden Sie diesen Befehl (ersetzen Sie C und D durch die SHAs der entsprechenden Commits):

git rebase --onto C D~ master
Allen Luce
quelle
für den git rebase 5 masterFall, warum ist es nicht "ABC 1 2 3 4 5 D ..." bestellen?
Roy
1
Dieser Befehl nimmt die Commits, mit denen er masternichts gemeinsam hat, 5und legt sie darauf 5. Das Commit bei Cist nicht Teil der Linie von 5, es ist das erste, auf das verschoben wird 5.
Allen Luce
2
Wenn Sie mit "ABC 1 2 3 4 5 D ..." enden möchten, können Sie Folgendes tun:git rebase C 5; git rebase 5 master
Allen Luce
16

So entfernen Sie einfach ein Merge-Commit

Wenn Sie lediglich ein Merge-Commit (2) entfernen möchten, damit es so aussieht, als wäre es nie passiert, lautet der Befehl einfach wie folgt

git rebase --onto <sha of 1> <sha of 2> <blue branch>

Und jetzt ist der lila Zweig überhaupt nicht mehr im Commit-Protokoll von Blau und Sie haben wieder zwei separate Zweige. Sie können das Purpur dann unabhängig voneinander quetschen und alle anderen gewünschten Manipulationen vornehmen, ohne dass das Zusammenführen festgeschrieben wird.

Labyrinth
quelle
Von allen Antworten finde ich dies sowohl am einfachsten als auch am einfachsten. Danke dir.
Roshambo
15

Es gibt zwei Möglichkeiten, dies basierend auf Ihren Wünschen anzugehen:

Lösung 1 : Entfernen Sie lila Commits, um den Verlauf beizubehalten (falls Sie einen Rollback durchführen möchten).

git revert -m 1 <SHA of merge>

-m 1 Gibt an, welche übergeordnete Zeile ausgewählt werden soll

Lila Commits sind weiterhin in der Geschichte vorhanden. Da Sie jedoch zurückgesetzt haben, wird kein Code aus diesen Commits angezeigt.


Lösung 2 : Entfernen Sie lila Commits vollständig (störende Änderung, wenn Repo geteilt wird)

git rebase -i <SHA before branching out>

und löschen (Linien entfernen), die lila Commits entsprechen.

Dies wäre weniger schwierig, wenn nach dem Zusammenführen keine Commits vorgenommen würden. Zusätzliche Commits erhöhen die Wahrscheinlichkeit von Konflikten während revert/rebase.

prem
quelle
Das klingt nicht richtig. Abgesehen von der Tatsache, dass es schwierig ist zu sagen, was das Originalplakat überhaupt mit den lila Commits machen wollte, ist es in Ordnung, wenn Sie die Zusammenführung zurücksetzen, einen umgekehrten Patch der Änderungen von diesem Commit durchzuführen und es als hinzuzufügen ein weiteres Commit, das die lila Commits aufhebt. Es ist wie 1 - 1 = 0. Wenn Sie dann die lila Commits erneut löschen, lassen Sie den zurückgesetzten Patch zurück, es sei denn, Sie setzen dies ebenfalls zurück. Wenn Sie dies nicht tun, ist es so, als würden Sie sich -1auf Ihren Verlauf beziehen, nicht 0, sodass Sie Änderungen hinterlassen, die Sie nicht möchten.
@ Cupcake, zur Verfügung gestellt wurden zwei getrennte Antworten. Ich habe die Antwort überarbeitet, um weniger verwirrend zu sein: P
Prem
AFAIK das ist nicht das, was das OP verlangt. Er möchte die Änderungen behalten, aber das Rauschen aus seinem Protokoll entfernen. Dafür muss er die Commits quetschen, durch Löschen werden die Änderungen entfernt.
Thecoshman
Es sieht so aus, als ob die ursprüngliche Frage umformuliert wurde. Diese Antwort ist nicht für OP-Probleme.
Prem