Einführung
Die Merge-Basis zweier Commits ist ihr bester gemeinsamer Vorfahre: das Fundament, das Git für Three-Way-Merges verwendet. Die richtige Basis zu wählen ist es, was "automatische" Merges überhaupt funktionieren lässt.
Sie finden
git merge-base A B
git merge-base --all A B # alle besten gemeinsamen Vorfahren
git merge-base --octopus A B C
git merge-base --is-ancestor X Y # Exit 0 falls X Vorfahre von Y
git merge-base --fork-point main feature
Definition
Ein gemeinsamer Vorfahre C von A und B ist ein "bester" gemeinsamer Vorfahre, wenn kein anderer gemeinsamer Vorfahre von A und B ein Nachkomme von C ist. Die meisten Paare haben einen einzelnen besten gemeinsamen Vorfahren. Wenn der Graph Crisscross-Merges enthält, können mehrere existieren; das ist es, was --all meldet.
Wie Three-Way-Merge ihn nutzt
Gegeben Commits A und B mit Merge-Basis M, tut Git für jede Datei:
- Liest die Datei bei M, A und B.
- Wenn nur eine Seite geändert hat, nimm diese Seite.
- Wenn beide Seiten identisch geändert haben, nimm eine.
- Wenn beide Seiten unterschiedlich geändert haben, führe einen Three-Way-Text-Merge aus oder gib Konfliktmarker aus.
Recursive- und ort-Strategien
Wenn mehrere Merge-Basen existieren, mergt die Recursive-Strategie sie zuerst und erzeugt eine virtuelle Basis, die sie für den finalen Three-Way-Merge verwendet. Die ort-Strategie (Standard seit 2.33) tut dasselbe mit einer schnelleren, speichereffizienteren Implementierung.
git merge -s ort feature
git merge -s recursive feature
git merge -s resolve feature # nur eine Merge-Basis, keine Rekursion
Fork-Point
Für Rebase muss Git oft wissen, wo ein Topic-Branch einen Basis-Branch verlassen hat. --fork-point konsultiert das Reflog der Basis, um den jüngsten Punkt zu finden, an dem Topic und Basis Historie geteilt haben:
git rebase --fork-point main feature
git merge-base --fork-point main feature
Durchgearbeitetes Beispiel
A---B---C main
\
D---E feature
git merge-base main feature # B
Ein Merge von main in feature Three-Way-mergt mit B als Basis.
Inspizieren, warum ein Merge in Konflikt gerät
git merge-base HEAD feature
git diff <base> HEAD -- file
git diff <base> feature -- file
Dieses Diff-Paar ist genau das, was Gits Merge sieht.
Häufige Fehler
Annehmen, es gebe immer genau eine Merge-Basis; Crisscross-Historien erzeugen mehrere. --fork-point als Ersatz für --onto behandeln; sie lösen verschiedene Probleme. --strategy=ours wählen, wenn Sie --strategy-option=ours meinten; ersteres verwirft ihre Änderungen vollständig. Schließlich: Die Merge-Basis von Hand aus git log-Ausgaben neu berechnen und falsch liegen; verwenden Sie git merge-base, statt nach Augenmaß zu schätzen.