Ich habe einen (großen) Commit-Baum, der mehrere Merge-Commits enthält, die ich auf einen anderen Commit umbuchen möchte. Wenn ich eine normale Rebase mache, bittet Git darum, Merge-Konflikte zu lösen. Ich wollte nicht jede Zusammenführung überprüfen, weil dies eine Menge Arbeit wäre. Nachdem Sie sich über die Option --preserve-merges informiert haben, die genau erklärt wird
Ausgehend von einem leeren Ordner erstellen wir zuerst einen Zweig mit einer Zusammenführung und einen weiteren Zweig, für den wir einen neuen Zweig erstellen.
%Vor%Wo sich master auf B bezieht, verweist Zweig auf D und tschüss-Zweig bezieht sich auf E .
%Vor%Bis zu diesem Zeitpunkt lief alles gut. Es gab einen Zusammenführungskonflikt, aber wir haben ihn gelöst. Jetzt versuchen wir, Zweig auf E umzustempeln, um mit dem folgenden Commit-Baum zu enden:
%Vor%Dies endet mit dem folgenden Fehler:
%Vor%Die Datei enthält folgenden Inhalt:
%Vor%Was mache ich falsch? Ich würde erwarten, dass git commit D verwenden kann, um den Zusammenführungskonflikt zu lösen, der beim Rebasieren auftritt.
Ich benutze Git 1.9.4.msysgit.1, welches die aktuellste Version ist.
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.
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
In Commit B enthält Hello.text
Und in Commit C enthält Hello.text
Wenn Sie jetzt versuchen, master
in branch
zusammenzufassen, indem Sie
Git meldet einen Zusammenführungskonflikt, weil er nicht herausfinden kann, ob der Inhalt von Hello.txt
nach der Zusammenführung
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.
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
Und in commit C 'enthält Hello.text
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.
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 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.
Tags und Links git git-rebase