2013-01-08 8 views
8

Ich arbeite mit einem Repository, wo vor Wochen eine Zusammenführung durchgeführt wurde, die wir gerade entdeckt haben, verwendete das --strategy=ours Flag (es sollte das Flag --strategy-option = our verwenden), also keine Änderungen an HEAD. Wir müssen jedoch die Änderungen anwenden. Git erkennt den Zweig bereits als zusammengeführt und das Commit in der Geschichte der Branche.Wie man eine Zusammenführung wieder herstellt, die Strategie = unsere verwendete?

kann diese Art von Merge nicht git revert -m ...

Was wäre der richtige Weg, das Zurücksetzen und/oder Wieder Anlegen der merge zu ändern, die Dateien mit rückgängig gemacht werden?

master A - B - E - F - G ---> L - M - N 
      \ /
topic   C - D 

Merge begeht (F) die Täter in diesem Szenario wären.

+0

Ist es sicher zu sagen, Sie wollen nicht die Geschichte neu zu schreiben, produzieren nur ein neues an der Spitze der Branche verpflichten, die in den Dateien übergeht? –

+0

Eigentlich wäre das Umschreiben der Geschichte eine vernünftige Option. Für diese Situation ist es egal, wie die Änderungen tatsächlich angewendet werden. Etwas zu beachten: Wir versuchen, eine Zusammenführung in Zweig 'Master' zu korrigieren, Master wurde Dutzende Male verzweigt, so dass die Historie in einer Zusammenführung zu anderen Zweigen propagieren kann. –

Antwort

6

Ich habe eine Lösung für dieses Problem gefunden. Es war alles in dem Brief, den Linus schrieb, um fehlerhafte Zusammenführungen rückgängig zu machen: How to revert a faulty merge. Die git merge --strategy=ours topic in unserem Fall war nicht beabsichtigt. Auch wenn es sich um eine fehlerhafte Zusammenführung handelt, kann sie nicht rückgängig gemacht werden, und nachdem sie lange gedrückt wurde, hat sie den gleichen Effekt, dass sie eine Zusammenführungsübergabe rückgängig machen kann, ohne die Zurückkehr-Festschreibung rückgängig machen zu können.

Die Lösung bestand darin, den Zweig des Themas zu überprüfen, rebase --no-ff vom ersten Commit aus auszuführen und diesen Zweig dann wieder in Master zusammenzuführen.

git checkout topic 
git rebase -i --no-ff <C> 
git checkout master 
git merge topic 

Dies hatte die Wirkung, wodurch man

fixed–topic C'–––D'––––––––––––––––––––- 
      /       \ 
master A–––B–––E–––F–––G –––> L–––M–––N–––F2 
      \ /
topic   C–––D 

Um dies zu verstehen im Detail wirklich, den letzten Teil des Briefes How to Revert a Faulty Merge mit der --no-ff rebase Option lesen Sie den Zweig neu zu erstellen.

0

eine Merge-Strategie, die besagt "behalte, was du hier hast, egal was du verschmelzest" von seiner Natur kann nicht umgekehrt werden. Überprüfen Sie das erste übergeordnete Element der Zusammenführung in einem neuen Zweig, führen Sie dann die Zusammenführung erneut durch. Rebase --auf den Rest der Commits, die Sie oben auf Ihrem ursprünglichen Merge haben, auf diesen.

UPDATE:

In Ihrem Fall, wenn Sie nicht über die Vergangenheit kümmern, können Sie G-N auf E rebase und dann nur D auf diesen neuen Master verschmelzen. Die Rebase wird trivial sein, weil F ein -ous-Merge war.

+0

BTW, ich habe meine Frage bearbeitet, um etwas klarer zu sein. - Seit der Zusammenführung wurden 69 Commits zum Master-Zweig gemacht. Ich bin besorgt über die Neuschreibung der Geschichte in diesem Fall, die möglicherweise katastrophalen Ausfall für Repositories von Mitgliedern des Teams und Fusion ihrer Zusammenführung der Rebase zurück in meine Repos könnte interessant werden. Wenn es keine vernünftigen Alternativen gibt, ist der Patch-Weg vielleicht der sicherste Weg? –

+0

Rebase und Patch ist das Gleiche am Ende. Rebase ist jedoch viel automatisierter. Denken Sie daran, Ihren Rerere einzuschalten, falls Sie neu starten müssen und Sie nicht noch einmal die gleichen Konfliktlösungen machen möchten. –

3

@ Highway des Lebens hat eine gute Antwort. Die eine Sache ist, dass die rebasierten Commits nun wie neue, unterschiedliche Commits aussehen, was in vielen Fällen unerwünscht sein kann. Ich wollte die identischen Commits ein zweites Mal zusammenführen, aber git-merge verhindert dies. Ich finde jedoch immer wieder, dass es immer möglich ist, git dazu zu bringen, das zu tun, was man will.

  1. Folgen Sie dem Highway von Anweisungen des Lebens, aber nicht direkt auf Master fusionieren:

    git checkout -b fixed-topic <D> 
    git rebase -i --no-ff <B> 
    git checkout -b re-merged master 
    git merge fixed-topic 
    

    Daraus ergibt sich:

    re-merged    ––––––––––––––––––––------R 
            /      /
    fixed–topic  C'–––D'      /
           /       /
    master  A–––B–––E–––F–––G –––> L–––M–––N–––F2 
           \ /
    topic   C–––D 
    
  2. genau Nun wird der Baum aufgebaut, wie Sie wollen -alle Dateien zeigen genau die Inhalte, die Sie wünschen. Das einzige Problem ist, dass die Eltern Ihres Merge-Commits rebasierende Kopien Ihrer ursprünglichen Commits sind, anstatt dass sie tatsächlich die ursprünglichen Commits selbst sind.Es ist einfach, dies mit git-reparent zu beheben:

    git reparent -p master -p <D> 
    

    Dieser endet mit:

    master  A–––B–––E–––F–––G –––> L–––M–––N–––F2 
           \ /      \ 
    topic   C–––D       \ 
             \       \ 
    re-merged    ---------------------------R 
    

    Eine wichtige Sache zu beachten ist, dass der Inhalt von R nicht seit dem letzten Schritt nur für die Eltern geändert .

  3. Vorspulen Master an den neuen merge commit:

    git checkout master 
    git merge re-merged 
    
  4. Schließlich können Sie mit

    git branch -d fixed-topic re-master 
    

Geschehen aufzuräumen! Jetzt ist Ihre Geschichte wie folgt aussieht, mit einem Zweig zweimal verschmolzen:

master A–––B–––E–––F–––G –––> L–––M–––N–––F2---R 
      \ /      /
topic   C–––D---------------------------- 
+0

Ich wusste nicht, dass die 'reparant'-Option eine Drittanbieterfunktion ist. Seams eine sehr gute Lösung, aber ich suchte nach dem einfacheren. –