Wann würden Sie die verschiedenen Git-Merge-Strategien verwenden?

429

Auf der Manpage zu git-merge gibt es eine Reihe von Zusammenführungsstrategien, die Sie verwenden können.

  • Auflösen - Dies kann nur zwei Köpfe (dh den aktuellen Zweig und einen anderen Zweig, aus dem Sie gezogen haben) mithilfe des 3-Wege-Zusammenführungsalgorithmus auflösen. Es versucht, kreuz und quer verlaufende Mehrdeutigkeiten sorgfältig zu erkennen und gilt allgemein als sicher und schnell.

  • rekursiv - Dies kann nur zwei Köpfe mithilfe des 3-Wege-Zusammenführungsalgorithmus auflösen. Wenn es mehr als einen gemeinsamen Vorfahren gibt, der für die 3-Wege-Zusammenführung verwendet werden kann, wird ein zusammengeführter Baum der gemeinsamen Vorfahren erstellt und dieser als Referenzbaum für die 3-Wege-Zusammenführung verwendet. Es wurde berichtet, dass dies zu weniger Zusammenführungskonflikten führt, ohne dass es zu Fehlzusammenführungen durch Tests kommt, die mit tatsächlichen Zusammenführungs-Commits aus dem Entwicklungsverlauf des Linux 2.6-Kernels durchgeführt wurden. Darüber hinaus können Zusammenführungen mit Umbenennungen erkannt und verarbeitet werden. Dies ist die Standard-Zusammenführungsstrategie beim Ziehen oder Zusammenführen eines Zweigs.

  • octopus - Hiermit werden mehr als zwei Köpfe gelöst, es wird jedoch keine komplexe Zusammenführung durchgeführt, für die eine manuelle Auflösung erforderlich ist. Es soll in erster Linie zum Bündeln von Themenzweigköpfen verwendet werden. Dies ist die Standard-Zusammenführungsstrategie, wenn mehr als ein Zweig gezogen oder zusammengeführt wird.

  • Unsere - Dies löst eine beliebige Anzahl von Köpfen auf, aber das Ergebnis der Zusammenführung ist immer der aktuelle Zweigkopf. Es soll verwendet werden, um die alte Entwicklungsgeschichte der Seitenzweige zu ersetzen.

  • Teilbaum - Dies ist eine modifizierte rekursive Strategie. Wenn beim Zusammenführen der Bäume A und B B einem Teilbaum von A entspricht, wird B zuerst an die Baumstruktur von A angepasst, anstatt die Bäume auf derselben Ebene zu lesen. Diese Anpassung wird auch am gemeinsamen Ahnenbaum vorgenommen.

Wann sollte ich etwas anderes als die Standardeinstellung angeben? Für welche Szenarien ist jedes am besten geeignet?

Otto
quelle

Antworten:

305

Ich bin nicht mit Entschlossenheit vertraut, aber ich habe die anderen benutzt:

Rekursiv

Rekursiv ist die Standardeinstellung für Zusammenführungen ohne schnellen Vorlauf. Damit sind wir alle vertraut.

Tintenfisch

Ich habe Octopus verwendet, als ich mehrere Bäume hatte, die zusammengeführt werden mussten. Sie sehen dies in größeren Projekten, in denen viele Branchen unabhängig voneinander entwickelt wurden und alles bereit ist, sich zu einem einzigen Kopf zusammenzuschließen.

Ein Octopus-Zweig führt mehrere Köpfe in einem Commit zusammen, solange dies sauber möglich ist.

Stellen Sie sich zur Veranschaulichung vor, Sie haben ein Projekt mit einem Master und dann drei Zweigen, die zusammengeführt werden sollen (nennen Sie sie a, b und c).

Eine Reihe von rekursiven Zusammenführungen würde folgendermaßen aussehen (beachten Sie, dass die erste Zusammenführung ein schneller Vorlauf war, da ich keine Rekursion erzwungen habe):

Reihe von rekursiven Zusammenführungen

Eine einzelne Octopus-Zusammenführung würde jedoch folgendermaßen aussehen:

commit ae632e99ba0ccd0e9e06d09e8647659220d043b9
Merge: f51262e... c9ce629... aa0f25d...

Octopus verschmelzen

Unsere

Unsere == Ich möchte einen anderen Kopf einziehen, aber alle Änderungen, die dieser Kopf einführt, wegwerfen.

Dadurch bleibt die Geschichte eines Zweigs ohne die Auswirkungen des Zweigs erhalten.

(Lesen Sie: Es werden nicht einmal die Änderungen zwischen diesen Zweigen betrachtet. Die Zweige werden nur zusammengeführt und nichts wird mit den Dateien gemacht. Wenn Sie in dem anderen Zweig zusammenführen möchten und jedes Mal die Frage "Unsere Dateiversion oder deren Version "können Sie verwenden git merge -X ours)

Teilbaum

Teilbaum ist nützlich, wenn Sie ein anderes Projekt in ein Unterverzeichnis Ihres aktuellen Projekts einbinden möchten. Nützlich, wenn Sie eine Bibliothek haben, die Sie nicht als Submodul aufnehmen möchten.

Dustin
quelle
1
Der einzige wirkliche Vorteil von Ocotopus besteht also darin, die Anzahl der Zusammenführungs-Commits im Baum zu reduzieren.
Otto
60
Sie müssen keine Octopus- Zusammenführungsstrategie angeben : Sie wird automatisch verwendet, wenn Sie mehr als zwei Zweige zusammenführen ( git merge A B ...).
Jakub Narębski
Entschuldigen Sie, dass Sie nicht zum Thema gehören, aber mit welchem ​​Tool haben Sie diese Screenshots erstellt? Es sieht aus wie eine wirklich tolle / hübsche Visualisierung der Branchengeschichte ...
Bernd Haug
4
Gitg für diejenigen unter Linux-Umgebung.
Akash Agrawal
2
Dieser Hinweis mit -X oursist fantastisch, hat mir nur eine Stunde Arbeit erspart.
Michael
49

Tatsächlich sind die einzigen zwei Strategien, die Sie wählen möchten, unsere, wenn Sie Änderungen, die durch die Verzweigung vorgenommen wurden, aufgeben möchten, aber die Verzweigung im Verlauf behalten möchten, und Teilbaum, wenn Sie ein unabhängiges Projekt in das Unterverzeichnis des Superprojekts zusammenführen (wie 'git-gui' in '). Git 'Repository).

Octopus Merge wird automatisch verwendet, wenn mehr als zwei Zweige zusammengeführt werden. Die Lösung erfolgt hier hauptsächlich aus historischen Gründen und wenn Sie von rekursiven Eckfällen für Zusammenführungsstrategien betroffen sind.

Jakub Narębski
quelle
Ich musste 'Auflösen' anstelle der Standardeinstellung 'Rekursiv' für eine Zweikopf-Zusammenführung wählen, die schwerwiegende Git-Write-Tree-Fehler aufwies. Die Strategie "Auflösen" wurde sauber zusammengeführt. Möglicherweise hat dies damit zu tun, dass viele Dateien in dem zusammengeführten Zweig verschoben wurden.
thaddeusmt
@ thaddeusmt: Interessant. Könnten Sie bitte, wenn möglich, einen Fehlerbericht über diesen Fehler der "rekursiven" Zusammenführungsstrategie für die Git-Mailingliste veröffentlichen? Danke im Voraus.
Jakub Narębski
@ JakubNarębski Ich bin mir nicht sicher, wie ich genug Informationen zusammenbringen würde, um einen aussagekräftigen Fehlerbericht einzureichen. Ich bin ein n00b mit Git, sorry. Wie ich in meiner Antwort hier erwähne ( stackoverflow.com/a/10636464/164439 ), hat meine Vermutung damit zu tun, dass ich Änderungen in beiden Zweigen dupliziert habe und "Auflösen" die doppelten Änderungen besser überspringt.
thaddeusmt
@ JakubNarębski jetzt können Sie auch ihre auswählen , was laut dem Handbuch "das Gegenteil von uns" ist . Ihre wird nicht automatisch für Sie ausgewählt. Mögen Sie Ihre Antwort leicht aktualisieren und ihre Option hinzufügen
SebNag
3
@SebTu: Es gibt keine theirsZusammenführungsstrategie (das heißt --strategy=theirs), aber es gibt eine theirsOption für die Standard- recursiveZusammenführungsstrategie (das heißt --strategy=recursive --strategy-option=theirsoder nur -Xtheirs).
Jakub Narębski
23

Zusammenführungsstrategie "Auflösen" und "Rekursiv"

Rekursiv ist die aktuelle Standardstrategie mit zwei Köpfen, aber nach einigem Suchen habe ich endlich einige Informationen über die Zusammenführungsstrategie "Auflösen" gefunden.

Entnommen aus O'Reillys Buch Versionskontrolle mit Git ( Amazon ) (umschrieben):

Ursprünglich war "Auflösen" die Standardstrategie für Git-Zusammenführungen.

In Cross-Cross-Merge-Situationen, in denen es mehr als eine mögliche Merge-Basis gibt, funktioniert die Auflösungsstrategie folgendermaßen: Wählen Sie eine der möglichen Merge-Basen aus und hoffen Sie auf das Beste. Das ist eigentlich nicht so schlimm wie es sich anhört. Es stellt sich oft heraus, dass die Benutzer an verschiedenen Teilen des Codes gearbeitet haben. In diesem Fall erkennt Git, dass einige bereits vorhandene Änderungen erneut zusammengeführt werden, und überspringt die doppelten Änderungen, um den Konflikt zu vermeiden. Wenn es sich um geringfügige Änderungen handelt, die zu Konflikten führen, sollte der Konflikt für den Entwickler zumindest leicht zu handhaben sein.

Ich habe erfolgreich Bäume mit "Auflösung" zusammengeführt, die mit der standardmäßigen rekursiven Strategie fehlgeschlagen sind. Ich habe fatal: git write-tree failed to write a treeFehler bekommen und dank dieses Blogposts ( Spiegel ) habe ich "-s lösen" versucht, was funktioniert hat. Ich bin mir immer noch nicht ganz sicher, warum ... aber ich denke, das lag daran, dass ich in beiden Bäumen doppelte Änderungen vorgenommen habe und sie ordnungsgemäß "übersprungen" habe.

thaddeusmt
quelle
Ich verwende die 3-Wege-Zusammenführung (p4merge) und hatte Konflikte in die .BASE-Datei geschrieben, als die rekursive Zusammenführung fehlschlug. In diesem Fall hat es geholfen, auf die Lösungsstrategie zurückzugreifen.
Mrzl
-2

Da die obigen Antworten nicht alle Strategiedetails anzeigen. Zum Beispiel fehlt einig Antwort Details über die Import - resolveOption und die , recursivedie viele Unter Optionen haben wie ours, theirs, patience, renormalizeetc.

Daher würde ich empfehlen, die offizielle gitDokumentation zu besuchen, in der alle möglichen Funktionen erläutert werden:

https://git-scm.com/docs/merge-strategies

Rene B.
quelle