So machen Sie eine Git-Zusammenführung rückgängig, behalten aber die Historie

8

Unser Repository hat einen Master-Zweig, aber es scheint, als hätte einer unserer Kollegen einen Master-Zweig mit einer anderen Historie. Gestern hat er seinen Meister zum Hauptmeister verschmolzen und gedrängt. So haben heute einige von uns bereits gezogen und angefangen zu arbeiten. Als wir das Problem erkannt hatten, waren schon ein paar Stunden Arbeit vorbei ...

Also meine Frage ist, wie kann ich seine Zusammenführung rückgängig machen, aber die Code-Änderungen noch heute machen? Die linke Seite ist unser aktueller Zustand, die rechte Seite ist die, für die ich fotografiere. Soll ich mich neu lehnen? oder gibt es eine Möglichkeit, eine Zusammenführung rückgängig zu machen? Was ist der beste Ansatz hier?

Bearbeiten 1: Ich glaube nicht, dass dies ein Duplikat von ist wurde schon gepusht , weil das Commit zum Ursprung gepusht wurde, und ich habe andere Commits nachdem der Fehler gemacht wurde und ich möchte die Geschichte bewahren.

Edit 2: Ich habe versucht, Rebase, Problem ist, dass der Rookie in seinem Master-Zweig für die letzten 2 Wochen verschmelzt ... Also selbst wenn ich zurückversetze ich werde nicht die neue "Timeline" los, die er erstellt. .. Ich habe keine Probleme, Geschichte neu zu schreiben, solange ich seine Zeitlinie los werde ...

Bearbeiten 3:

Am Ende habe ich eine Version des Repositorys gefunden, die unberührt geblieben ist und die Änderungen nach dem Vorfall beantwortet hat ...

    
Mac 27.10.2015, 17:02
quelle

2 Antworten

2

Ich kann drei Optionen sehen: Zurücksetzen der Zusammenführung, Neuausrichtung oder Filterung.

Zurückkehren

Die "richtige" Lösung ist, wie andere befürwortet haben, die Zusammenführung rückgängig zu machen - das bedeutet, dass Sie nicht "Geschichte neu schreiben", was allgemein als eine gute Sache angesehen wird, nicht zuletzt deshalb, weil alle anderen daran arbeiten Der Code muss sich nicht mit der Änderung der Historie befassen.

Sie können jedoch nicht git revert verwenden, wie es ist, weil es nicht weiß, welcher Zweig des Verlaufs beibehalten werden soll. Die Lösung besteht darin, Git das zusätzliche bisschen Information zu geben:

%Vor%

Das -m 2 gibt an, dass Sie das zweite Elternelement behalten möchten, d. h. dasjenige, das Commit C enthält; Wechseln Sie für die Alternative zu -m 1 .

Eine Warnung: Wenn Sie diesen anderen Zweig jemals in Ihren Hauptzweig einbinden wollen, werden Sie Ärger bekommen, weil Git denkt, dass sich der Zweig bereits im Hauptzweig befindet. Es gibt mehrere Lösungen dafür, aber die einfachste (IMO) besteht darin, den Rücksprung auf einen Abzweig vom Master zu setzen und ihn, zusammen mit dem Master, in diesen anderen Zweig zu verschmelzen. Dieser Zweig wird wahrscheinlich wie jede Version des Meisters aussehen, an der er abgelegt wurde. An diesem Punkt können Sie die Rückstellung rückgängig machen, und alles wird in Ordnung sein, wenn Sie in Zukunft zusammenführen.

Rebasing

Rebasing ist wahrscheinlich die einfachste Option: git rebase <sha-of-B> master --onto <sha-of-C> .

Dies verschiebt alle Commits von B bis master auf C. Der Haken ist, dass es den Merge-Verlauf "linearisiert". Der Zusammenführungsverlauf im Image ist sehr einfach, aber das kann ein Problem sein, wenn Sie den Verlauf beibehalten möchten oder wenn Sie dies in einem komplizierteren Repository tun.

Das hat auch den Haken, dass es "Geschichte umschreibt", und alle anderen, die dieses Repository verwenden, werden feststellen, dass sie an einem komplett anderen Code-Zweig arbeiten als an dem, der zurückgesetzt wurde, da jede Änderung ab C einen verschiedene sha1 Hash.

Filtern

Wenn Sie git filter-branch verwenden, können Sie genau das erhalten, wonach Sie in Ihrem Bild suchen, d. h. den Merge-Verlauf beibehalten, aber es ist die komplizierteste Option und beinhaltet immer noch das Umschreiben des Verlaufs.

Sie möchten git filter-branch verwenden, um Ihre Commits zu filtern, um alles außer dem einen duff zu behalten. Dies ist so komplex, dass ich nicht versuche, Anweisungen zu schreiben; Sie müssten --commit-filter kombinieren, um die problematische Zusammenführung zu entfernen, und --tree-filter , um die Änderungen der Zusammenführung rückgängig zu machen.

Filterreduktion

Okay, hier ist eine vierte Methode, die ich der Vollständigkeit halber einschließe. Sie könnten einfach C auschecken und dann manuell jede der Änderungen, die Sie in Ihrem Master-Zweig haben möchten, einzeln auswählen und zusammenführen.

Weiter lesen

me_and 27.10.2015, 18:19
quelle
1

Was ich tun würde, wäre eine Umkehrung, bei der Sie einfach nach der Umkehrung der Deltas suchen, die Sie gerade in diesen Merge-Commit eingebunden haben, und dann diesen Commit durchführen.

Ziehen Sie das Zurücksetzen-Commit auf Ihre C-Verzweigung, dann stellen Sie das Commit auf C-Branch wieder her und übernehmen Sie das Commit. Doppeltes Negativ wird aufgehoben, Sie speichern Ihren gesamten Verlauf und wenn Sie wieder zusammenführen, haben Sie die Ergebnisse, nach denen Sie suchen.

Git Extensions haben eine Funktion zum Zurücksetzen, die das sehr einfach macht.

    
Sean Morse 27.10.2015 17:09
quelle

Tags und Links