2016-04-18 17 views
2

Dies ist ein bisschen lang, aber ich denke, es kann ein interessantes Problem sein.Git Merge vs Rebase - Auflösung von Konflikten

Wir haben gerade erst begonnen, git in unserem Unternehmen zu verwenden, trotz der vielen Zurückhaltung einiger Leute, die es anfingen, es in kleinen Projekten einzusetzen, und jetzt verwenden wir es tatsächlich relevantere Projekte.

Ich versuche immer eine Rebase vor der Zusammenführung zu machen, aber erst vor kurzem haben wir ein Problem mit diesem Ansatz gefunden.

Imagine Sie haben eine Datei F und Sie haben die folgende git Geschichte:

(master)  F -- F''1 
       \ 
(feature)  \- F'1 -- ... -- F'X 

Nun, wenn Sie ein Fütterungsmaterial des Zweiges tun und auf den ersten Konflikt zu lösen, halten Sie tatsächlich Änderungen von F '' 1 und F'1 müssen Sie X Konflikte für die Datei F manuell auflösen, da git sie nicht automatisch auflösen kann. Im Gegensatz dazu, wenn Sie nur eine Zusammenführung durchgeführt haben (ohne Umbasieren), müssten Sie nur einen ("großen") Konflikt lösen. Das hat mich dazu gebracht, den tatsächlichen Wert von Rebasing in Frage zu stellen, da dies eine wirklich mühsame Arbeit sein kann.

Fehle ich etwas oder ist das so, wie es ist? Wenn Sie 30 Commits über eine Datei haben, müssen Sie jedes Commit durchlaufen und jeden Konflikt manuell lösen. Gibt es einen geeigneteren Weg, um mit dieser Situation umzugehen?

Es tut mir leid, wenn ich nicht sehr gut erklärt habe, aber Sie können versuchen, die Schritte, die ich erwähnt habe, in einem Dummy-Repository zu replizieren, und ich denke, Sie bekommen, was mich nervt.

+0

Wie wäre es mit der Annahme von toreks Antwort? –

Antwort

5

Sie haben Recht: Sie müssen Konflikte immer wieder auflösen, normalerweise auf die gleiche Weise.

Es gibt jedoch einen Automatisierungsknopf dafür, git rerere genannt. Das drei re es steht für re Verwendung re corded re Lösung.

Die Art und Weise dies funktioniert, ist, dass jedes Mal, wenn Sie einen Konflikt treffen, und wenn Sie git add die Version behoben, git spart sowohl den ursprünglichen Konflikt (minus die Zeilennummern) und die Auflösung in einigen Dateien (eigentlich nur innerhalb der Blob-Objekte Repository). Vor dem Bekanntgeben eines Konflikts überprüft der Zusammenführungscode dann, ob der ursprüngliche Konflikt bereits mit einer Auflösung verknüpft ist. Wenn dies der Fall ist, wird die Konfliktregion durch diese Auflösung ersetzt.

Da die Zeilennummern vor dem Aufzeichnen des Konflikts abgeschnitten werden, wird der wiederkehrende Konflikt häufig - wenn auch nicht immer - behandelt. (Es schlägt fehl, wenn sich der Umgebungskontext ändert, da dies die Hash-ID des Konflikt-/Auflösungspaares ändert.)

Es ist ein wenig gefährlich, da manchmal ein Konflikt, der gleich aussieht, aber weit entfernt in einer Datei vorkommt, ist nicht wirklich der gleiche Konflikt (dies passiert meist mit Template-y-Code). Da jeder Konflikt und jede Auflösung aufgezeichnet wird, können Sie viele Auflösungen sammeln und falsche Übereinstimmungen erhalten. Git versucht damit umzugehen, indem er aufgezeichnete Auflösungen innerhalb von 60 Tagen abarbeitet (und ungelöste Konflikte innerhalb von nur 15 Tagen).

Sie müssen aktivieren, bevor Sie den ersten Konflikt erstellen, und ihn aktiviert lassen, wenn die Auflösung git add angezeigt wird. Das ist ein bisschen nervig, da du oft (wahrscheinlich, ich) entdeckt habe, dass ich früher aktiviert haben sollte, und jetzt ist es zu spät.Ich war versucht, ein Skript zu schreiben, das eine frühere Zusammenführung oder Umbenennung, die ich bereits gelöst habe, unter Verwendung meiner vorhandenen Auflösung wiederholt, um in eine erneute Wiedergabe zu münden, um die rerere Engine zu primen. (Der eindeutige Name für dieses Skript ist git-rererere ... :-))

+0

Ich habe dieses Problem oft behandelt und ich versuchte immer den folgenden Ansatz. Nehmen wir an, ich habe 30 Commits in meiner Branche und sobald meine Pull Request überprüft wurde und es gut ist zu gehen. Der letzte Teil ist das Rebase mit dem Master. Zuerst zerquetsche ich meine 30 commits of feature branch in einen commit und re-base dann mit dem master branch auf diese Weise, ich musste nicht alle Konflikte immer wieder auflösen. –

+0

"Sie müssen rerere aktivieren, bevor Sie den ersten Konflikt erstellen ..."> Warum nicht 'git config --global rerere.enabled true'? –

+1

@MuhammadShoaib: so effektiv zerstören Sie die ganze Geschichte, groß –