Git Rebase - Preserve-Merges schlägt fehl

1 Antwort

22

TL; DR

Das --preserve-merges -Flag zeigt einfach git-rebase an, um zu versuchen, Merge-Commits neu zu erstellen, anstatt sie zu ignorieren. Es gibt git rebase nicht die Möglichkeit, sich daran zu erinnern, wie Zusammenführungskonflikte gelöst wurden, d. H. nicht zeichnet Konfliktlösungen für die zukünftige Verwendung auf. Was Sie dafür verwenden möchten, ist rerere .

In Ihrem Spielzeugbeispiel ist der Konflikt, der während des Rebases auftritt, genau der gleiche wie der, den Sie während des vorherigen Mischens gelöst haben. Wenn Sie rerere vor die Zusammenführung aktiviert hätten, hätten Sie diesen Konflikt während der Rebase nicht erneut lösen müssen.

Wenn Sie erwarten, dass Sie einen Zweig zusammenfügen und einen Zweig neu erstellen, sollten Sie rerere aktivieren, damit Sie in der Zukunft einen bestimmten Zusammenführungskonflikt nur einmal und nicht mehrmals lösen müssen.

Detaillierte Erklärung

Lass uns dein Spielzeugbeispiel aufschlüsseln.

%Vor%

So weit, so gut. Kurz vor dem ersten Befehl git merge sieht dein Repo wie folgt aus:

In Commit A enthält Hello.text

%Vor%

In Commit B enthält Hello.text

%Vor%

Und in Commit C enthält Hello.text

%Vor%

Wenn Sie jetzt versuchen, master in branch zusammenzufassen, indem Sie

ausführen %Vor%

Git meldet einen Zusammenführungskonflikt, weil er nicht herausfinden kann, ob der Inhalt von Hello.txt nach der Zusammenführung

sein soll %Vor%

oder

%Vor%

oder etwas anderes ...

Sie lösen diesen Konflikt auf, indem Sie den Inhalt von Hello.txt mit Hello World, Dave! überschreiben, Ihre Änderungen inszenieren und den Zusammenführungs-Commit abschließen.

%Vor%

Ihr Repo sieht jetzt so aus:

Dann führen Sie

aus %Vor%

In diesem Stadium sieht Ihr Repo wie folgt aus:

Jetzt läufst du

%Vor%

aber erleben Sie einen Konflikt. Bevor wir erklären, warum dieser Konflikt auftritt, schauen wir uns an, wie Ihr Repo aussehen würde, wenn diese Operation git-rebase erfolgreich wäre (d. H. Konfliktfrei):

Sehen wir uns jetzt an, warum Sie in Hello.txt auf den gleichen Konflikt stoßen wie bei Ihrer ersten Zusammenführung; Goodbye.txt ist in keiner Weise problematisch, hier. Eine Rebase kann tatsächlich in einer Folge elementarer Operationen ( checkout s und cherry-pick s) zerlegt werden; mehr dazu bei Ссылка . Lange Rede kurzer Sinn ... In der Mitte Ihrer Operation git rebase sieht Ihr Repo wie folgt aus:

Die Situation ist der gleich vor der ersten Zusammenführung sehr ähnlich: In commit B 'enthält Hello.text

%Vor%

Und in commit C 'enthält Hello.text

%Vor%

Dann versucht Git, Merge B 'und C' zu erzeugen, aber ein Zusammenführungskonflikt entsteht genau aus dem gleichen Grund wie der erste Zusammenführungskonflikt: Git hat keine Möglichkeit herauszufinden, ob die Dave -Zeile vor oder gehen sollte nach der World! -Zeile. Daher kommt die Rebase-Operation zum Stillstand, und Git bittet Sie, diesen Zusammenführungskonflikt zu lösen, bevor die Rebase abgeschlossen werden kann.

Was Sie dagegen tun können: Verwenden Sie rerere

Git's rerere ist hier dein Freund.

  

Der Name steht für "repeat recorded resolution", und wie der Name schon sagt, können Sie Git fragen, sich zu erinnern, wie Sie einen Hunk-Konflikt gelöst haben, damit Git das nächste Mal denselben Konflikt erkennt für dich.

     

[...] Wenn Sie einen Zweig, den Sie zusammengeführt haben, nehmen und mehrere Konflikte lösen möchten und dann stattdessen einen neuen Verweis erstellen möchten, müssen Sie wahrscheinlich nicht alle die gleichen Konflikte wiederholen.

Wenn rerere aktiviert wurde,

%Vor%

vor die Zusammenführung, dann hätte Git aufgezeichnet, wie Sie den Zusammenführungskonflikt beim Erstellen von Festschreibung D gelöst und dieselbe Auflösung angewendet haben, wenn während der nachfolgenden Umlagerung derselbe Konflikt aufgetreten ist. Der Konflikt hätte die Rebase-Operation immer noch unterbrochen, aber sie wäre automatisch gelöst worden. Alles, was Sie hätten tun müssen, ist git rebase --continue .

Es sieht jedoch so aus, als wäre rerere nicht bereits vor dem Zusammenführen aktiviert worden, was bedeutet, dass Git keine Aufzeichnung darüber gespeichert haben muss, wie Sie den Konflikt zum ersten Mal gelöst haben. An dieser Stelle können Sie entweder rerere jetzt aktivieren und alle diese Konflikte manuell erneut lösen oder das rerere-train.sh Skript (siehe auch diesen Blogeintrag ), um den vorhandenen Verlauf zu verwenden, um den rerere -Cache vorzusäen.

    
Jubobs 04.09.2014 17:06
quelle

Tags und Links