Bei der Versionsverwaltung mit Git liefert ein normaler Merge schon genug Konfliktpotenzial. Darüber hinaus gibt es aber natürlich auch noch Sonderfälle, samt verwirrender Namensgebung. Ein Überblick über verschiedene Merge-Möglichkeiten.
Der Merge ist essenzieller Bestandteil der Versionsverwaltung, kann aber zu Konflikten führen.
(Bild: Git / Lang)
Die Einstiegshürden in Git sind relativ hoch, aber wenn die Basics einmal sitzen, geht die grundsätzliche Arbeit – also vor allem Speichern und Hochladen – ziemlich flott von der Hand. Doch dann kommen weitere Mitstreiter, weitere Branches und fast zwangsläufig auch die ersten Konflikte.
Ein normaler, alltäglicher Merge sieht dabei meist in etwa so aus: Auf einem Branch namens etwa „feature-branch-01“ wird ein Feature entwickelt und dann aus dem Hauptzweig heraus in diesen überführt/verschmolzen. Dabei werden Änderungen automatisch akzeptiert, sofern sie nicht im Konflikt zum Bestand stehen. Beispiel: Eine neu angelegte Datei würde schlicht übernommen. Eine Änderung einer bestehenden Zeile einer bestehenden Datei würde hingegen zu einem Konflikt führen, der manuell gelöst werden muss.
Was aber, wenn mehrere Feature- oder sonstige Branches übernommen werden sollen? Was, wenn im Zweifelsfall doch lieber die eigenen Änderungen bevorzugt werden sollen? So etwas in 200 Merge-Konflikten manuell zu beheben, kostet immens Zeit und Nerven. Oder wie sieht es aus, wenn ein Mitarbeiter Mist gebaut, Dutzende Commits plötzlich überflüssig sind, der Branch aber später noch benötigt wird?
Für derlei Fälle bietet Git unterschiedliche Merge-Strategien – einige häufiger, andere seltener sinnvoll. Die Standardstrategie hat sich übrigens vor nicht einmal zwei Jahren geändert, von „recursive“ zu „ort“ – einer gemäß typischem Entwicklerhumor kreierten Abkürzung für „Ostensibly Recursive‘s Twin“. Was also tut dieser angebliche Zwilling?
ort
Der Standard-3-Wege-Merge funktioniert im Konfliktfall ziemlich simpel: Wurde eine Zeile im fremden Branch sowie im aktuellen Branch unterschiedlich editiert, schreibt git beide Varianten in die Datei, markiert sie deutlich als Konflikt und wartet. Nutzer müssen diese Markierungen dann entfernen, sich für den gewünschten Inhalt entscheiden und die Datei dann wieder hinzufügen.
Nun kann es aber sein, dass im fremden Branch andere Regeln beispielsweise für Zeilenenden gelten, etwa andere Umbrüche. Derartige Dinge sollten freilich keine Konflikte verursachen. Git kann solche Whitespace-Problemchen ignorieren:
Die Angabe der ort-Strategie ist im Übrigen überflüssig, da Standard, hier nur zu Verdeutlichung. Die ort-Option „ignore-cr-at-eol“ sorgt dafür, dass cr-Zeilenenden nicht für Konflikte sorgen. Weitere Optionen: ignore-space-change, ignore-all-space, ignore-space-at-eol.
Solche Eigenschaften werden häufig über die Git-Funktion „gitattributes“ festgelegt. Damit lassen sich Pfad-basiert Check-in- und Check-out-Regeln für Dateien im Repo bestimmen. Sofern es hier Unterschiede gibt, lassen sich diese während eines Merge komplett übernehmen beziehungsweise ignorieren:
Soweit zu „belangloseren“ Standards. Spannender: Bisweilen ist beim Merge auch klar, dass bei etwaigen Konflikten immer die eigenen (ours) den fremden (theirs) Änderungen vorzuziehen sind. Und auch das muss nicht etliche Male manuell erledigt werden:
…, um jeweils die fremden Änderungen zu übernehmen und eigene zu überschreiben. Dass mit diesen Optionen schnell viel Unheil angerichtet werden kann, sollte klar sein.
Recursive
Der frühere Standard „recursive“ funktioniert fast genauso wie „ort“ und verträgt auch dieselben Optionen. „ort“ ist lediglich eine komplette Neuauflage dieser Strategie, arbeitet intern allerdings präziser und vor allem deutlich schneller. Dennoch verträgt „recursive“ weitere Optionen: Über „diff-algorithm=“ lassen sich andere Diff-Algorithmen wählen und über „no-renames“ lässt sich die Umbenennungserkennung deaktivieren. Die ort-Strategie nutzt hier die Git-Konfiguration und andere Defaults.
Resolve
Die resolve-Strategie arbeitet auf den ersten Blick im Grunde wie auch die vorigen Strategien. Ohne eine langwierige Abhandlung über die intern genutzten Algorithmen zur Konfliktlösung beziehungsweise -bestimmung zu verfassen, lässt sich hier eigentlich nur etwas vereinfachend beschreiben: Wenn ein Commit beim Merge mehrere mögliche Vorgänger hat, über unterschiedliche Branches, würde „recursive“ intern wieder und wieder mergen, bis ein Konflikt zum Lösen übrigbleibt. „resolve“ hingegen würde im Grunde einfach auf gut Glück die (vermeintlich) beste Variante wählen.
Stand: 08.12.2025
Es ist für uns eine Selbstverständlichkeit, dass wir verantwortungsvoll mit Ihren personenbezogenen Daten umgehen. Sofern wir personenbezogene Daten von Ihnen erheben, verarbeiten wir diese unter Beachtung der geltenden Datenschutzvorschriften. Detaillierte Informationen finden Sie in unserer Datenschutzerklärung.
Einwilligung in die Verwendung von Daten zu Werbezwecken
Ich bin damit einverstanden, dass die Vogel IT-Medien GmbH, Max-Josef-Metzger-Straße 21, 86157 Augsburg, einschließlich aller mit ihr im Sinne der §§ 15 ff. AktG verbundenen Unternehmen (im weiteren: Vogel Communications Group) meine E-Mail-Adresse für die Zusendung von Newslettern und Werbung nutzt. Auflistungen der jeweils zugehörigen Unternehmen können hier abgerufen werden.
Der Newsletterinhalt erstreckt sich dabei auf Produkte und Dienstleistungen aller zuvor genannten Unternehmen, darunter beispielsweise Fachzeitschriften und Fachbücher, Veranstaltungen und Messen sowie veranstaltungsbezogene Produkte und Dienstleistungen, Print- und Digital-Mediaangebote und Services wie weitere (redaktionelle) Newsletter, Gewinnspiele, Lead-Kampagnen, Marktforschung im Online- und Offline-Bereich, fachspezifische Webportale und E-Learning-Angebote. Wenn auch meine persönliche Telefonnummer erhoben wurde, darf diese für die Unterbreitung von Angeboten der vorgenannten Produkte und Dienstleistungen der vorgenannten Unternehmen und Marktforschung genutzt werden.
Meine Einwilligung umfasst zudem die Verarbeitung meiner E-Mail-Adresse und Telefonnummer für den Datenabgleich zu Marketingzwecken mit ausgewählten Werbepartnern wie z.B. LinkedIN, Google und Meta. Hierfür darf die Vogel Communications Group die genannten Daten gehasht an Werbepartner übermitteln, die diese Daten dann nutzen, um feststellen zu können, ob ich ebenfalls Mitglied auf den besagten Werbepartnerportalen bin. Die Vogel Communications Group nutzt diese Funktion zu Zwecken des Retargeting (Upselling, Crossselling und Kundenbindung), der Generierung von sog. Lookalike Audiences zur Neukundengewinnung und als Ausschlussgrundlage für laufende Werbekampagnen. Weitere Informationen kann ich dem Abschnitt „Datenabgleich zu Marketingzwecken“ in der Datenschutzerklärung entnehmen.
Falls ich im Internet auf Portalen der Vogel Communications Group einschließlich deren mit ihr im Sinne der §§ 15 ff. AktG verbundenen Unternehmen geschützte Inhalte abrufe, muss ich mich mit weiteren Daten für den Zugang zu diesen Inhalten registrieren. Im Gegenzug für diesen gebührenlosen Zugang zu redaktionellen Inhalten dürfen meine Daten im Sinne dieser Einwilligung für die hier genannten Zwecke verwendet werden. Dies gilt nicht für den Datenabgleich zu Marketingzwecken.
Recht auf Widerruf
Mir ist bewusst, dass ich diese Einwilligung jederzeit für die Zukunft widerrufen kann. Durch meinen Widerruf wird die Rechtmäßigkeit der aufgrund meiner Einwilligung bis zum Widerruf erfolgten Verarbeitung nicht berührt. Um meinen Widerruf zu erklären, kann ich als eine Möglichkeit das unter https://contact.vogel.de abrufbare Kontaktformular nutzen. Sofern ich einzelne von mir abonnierte Newsletter nicht mehr erhalten möchte, kann ich darüber hinaus auch den am Ende eines Newsletters eingebundenen Abmeldelink anklicken. Weitere Informationen zu meinem Widerrufsrecht und dessen Ausübung sowie zu den Folgen meines Widerrufs finde ich in der Datenschutzerklärung.
Diese Strategie könnte gegebenenfalls für weniger Arbeit sorgen, ist aber abhängig von der jeweiligen Git-Version und schlicht ein wenig mehr „Black Box“. Und ja, „resolve“ ist ein wenig verwirrend, zumal es eher selten explizit genutzt wird und die Suche nach Details extrem schwierig ist – schlicht, weil auch alle anderen Strategien „resolven“ … Hier prallen Eigenname und Standard-Verb aufeinander.
Octopus
Der schöne Name Octopus meint natürlich, dass mehrere Branches verschmolzen werden, nicht bloß zwei:
Gedacht ist diese Variante allerdings nur für das Zusammenführen gänzlich unterschiedlicher Branches – bei Konflikten streikt dieses Prozedere.
Ours
Manchmal möchte man meinen, Git verwirre absichtlich. Die „ours“-Strategie ist etwas völlig anderes als die „ours“-Option der „ort“-Strategie. Ein …
git merge --strategy=ours nutzloser-branch-1
… ignoriert alle Änderungen auf „nutzloser-branch-1“ und behauptet einfach, der Merge sei vollzogen. Dazu mal ein Beispiel, das ein Entwickler hier eingebracht hat: Zwei Kollegen arbeiten (vielleicht unwissentlich) an ein und demselben Feature oder ein Kollege baut auf einem Branch schlicht und ergreifend Mist.
Erfolgte diese Entwicklung auf einem eigens angelegten Branch, würde man diesen einfach löschen oder ignorieren. Wird der Branch aber noch benötigt, ließe sich die unerwünschte Arbeit mit dieser Strategie fix „weg-ignorieren“. Werden dann wieder sinnvolle Änderungen auf diesem Branch durchgeführt, kann er wieder gemergt werden – die ignorierten Änderungen bemerkt der Ziel-Branch dann gar nicht mehr.
Subtree
Die „subtree“-Strategie ist eine „ort“-Variante, bei der der zu mergende Git-Baum in ein Unterverzeichnis geschmolzen werden kann. Auf diese Weise ließe sich beispielsweise eine Bibliothek von Dritten in das eigene Repo bringen. Sinnvoll ist solch ein „Repo im Repo“ vor allem dann, wenn Sie selbst nicht in diese Code-Basis pushen.
Das Prozedere für die initiale Einrichtung ist etwas komplexer. Um es ein wenig simpler zu gestalten, wird hier ein ganz konkretes, existierendes GitHub-Repo (yarfORk) als Subtree eingebunden. Genauer: Zunächst wird das yarfORk-Repo als eigner Branch namens „meinsubtree“ angelegt und dann in ein Unterverzeichnis „meinsubtreedir“ im Master-Branch eingelesen – dann werden Änderungen im yarfORk-Repo gepullt, bevor dann endlich die Subtree-Merge-Strategie ausgeführt wird:
Der „read-tree“-Befehl bugsiert den meinsubtree-Branch in den per „prefix“ angegebenen Unterordner im Master-Branch – mit dem folgenden Commit wird die Einrichtung abgeschlossen.
In den Zeilen 7 bis 9 wird lediglich in den subtree-Branch gewechselt, eine Aktualisierung durchgeführt und wieder zurück in den Master-Branch gewechselt.
Nun sind die Änderungen im Sub-Projekt zwar im zugehörigen Branch vorhanden, nicht aber im Unterverzeichnis im Master-Branch – und genau das erledigt natürlich der Merge-Befehl. Wichtig ist hierbei, per „squash“ zu verhindern, dass die gesamte Historie des Sub-Projekts ebenfalls germergt wird – in der Regel dürfte das zumindest nicht erwünscht sein. Und da Haupt- und Subprojekt keine gemeinsame Historie haben, muss dies über „allow-unrelated-histories“ explizit genehmigt werden.
Wenn Sie von all diesen Merge-Strategien und -Optionen nur eine Sache mitnehmen können, wäre die Empfehlung wohl die X-Option „ours“ für ganz normale ort-Merges – vermutlich die häufigste Arbeitserleichterung. Übrigens kennen Sie diese Variante vermutlich von größeren Linux-Updates: Auch hier wird oft gefragt, wie bestehende (Config-)Dateien gehandhabt werden sollen, wenn es lokale/eigene Änderungen gibt – und vermutlich werden Sie dort etwas wie „Yes to all“ auswählen. Und genau das macht auch „merge -s ort -Xours“.