Gegeben sei ein Git-Repo mit zwei Branches master
und feature
. Beim Rebasing des Feature-Zweigs über dem Master mit rebase master
Sagen wir diese Datei a.txt
enthält einen Konflikt, der gelöst werden muss, bevor die Neubasierung fortgesetzt werden kann.
Ich weiß, dass ich den Konflikt in drei Schritten lösen kann:
- offen
a.txt
in meinem Editor den Konflikt manuell lösen
- Anruf
git add a.txt
um git mitzuteilen, dass ich den Konflikt manuell gelöst habe
- Anruf
git rebase --continue
Bewegen Sie die Rebase nach vorne
Gibt es eine Möglichkeit, Schritt 1 zu vermeiden, indem Sie git mitteilen, dass ich die Version der Datei aus dem Master-Branch oder die Version der Datei aus dem Feature-Branch haben möchte, ohne die Schritte 1 und 2 oben ausführen zu müssen?
Ja. Tatsächlich gibt es mehr als einen Weg, dies zu tun.
Die Befehle rebase und merge (und übrigens auch Cherry-Pick) haben alle das gleiche strategy
und -X
Flags, die an die zugrunde liegende Git-Merge-Maschinerie übergeben werden. Für die recursive
Strategie, -Xours
und -Xtheirs
Wählen Sie die eine oder die andere “Seite” von Dateien aus, wenn eine Datei, die in beiden Zweigen geändert wurde, zusammengeführt wird.
Oder – das ist ganz anders – in den Fällen beim Merge hört bei einem Konflikt aufkönnen Sie verwenden git checkout
mit dem --ours
oder --theirs
Flaggen, um die Version von der einen oder anderen Seite auszuwählen. (Sie können dies mit anderen Befehlen tun; hier bleibe ich dabei --ours
und --theirs
da diese mit den Argumenten der Befehle übereinstimmen, die die Zusammenführungsmaschinerie verwenden.)
Dies ist natürlich anders, da Sie die Auswahl ändern können:
$ git checkout main
Switched to branch 'main'
$ git merge branch
... conflicts in files A and B ...
$ git checkout --ours -- A # takes main:A
$ git checkout --theirs -- B # takes branch:B
Beachten Sie, dass dies ganz anders ist als die „unsere Strategie” (das Obige zeigt die “recursive
Strategie mit der ours
Option”). Mit der Option “unsere Strategie“, passiert etwas völlig anderes. Beginnen wir ohne es und führen die gleiche Zusammenführung noch einmal durch:
$ git checkout main && git merge branch
... conflicts ...
$ git checkout --ours -- A B # take main:A and main:B
Nehmen wir an, es gibt eine dritte Datei, C
, kann dieser Git alleine zusammenführen. Wenn Sie das oben Gesagte tun, wird git zusammengeführt C
und du nimmst main:A
und main:B
. Wenn Sie verwenden würden git merge --strategy=ours branch
aber Git würde nehmen main:A
, main:B
und main:C
. Es würde die verwerfen branch:C
Änderungen, anstatt sie automatisch zusammenzuführen.
Ich habe verwendet git merge
oben, weil es dafür sorgt, dass die “unseren” und “ihren” Sachen “richtig funktionieren”. Ich mag jedoch die Art und Weise, wie Git diese benennt, nicht, denn wenn Sie eine Rebase durchführen, wird die Ours/Theirs-Version vertauscht, da die Rebase funktioniert, indem Sie zum “anderen” Zweig wechseln und eine Reihe von Cherry-Picks durchführen. Das ist:
$ git checkout mine; git rebase theirs
funktioniert darunter, indem Sie das (sehr) grobe Äquivalent von:
$ git checkout theirs; git cherry-pick theirs..mine
und dann danach die Verzweigungsetiketten so verschieben, dass diese verzweigt sind theirs
bewegt sich eigentlich nicht. (Es ist nicht annähernd so schlimm intern 🙂 aber es schafft es zu machen --ours
bedeuten “ihre” und --theirs
bedeutet “unser”, was ziemlich schlecht ist extern.)
Sie können Folgendes verwenden:
git checkout --ours -- path/to/file
Oder:
git checkout --theirs -- path/to/file
…während einer Zusammenführung oder Neubasierung, um eine bestimmte Version einer widersprüchlichen Datei auszuwählen; weil rebasing ist Ein bisschen komisch, --theirs
in diesem Fall wäre feature
‘s Version, --ours
wäre master
‘s.
Ich glaube, dass das, wonach Sie suchen, alle drei Schritte loswerden wird
git rebase master -X theirs
die automatisch Konflikte zugunsten von lösen wird feature
(der aktuell ausgecheckte Zweig), oder
git rebase master -X ours
Der Sinn von ours
und theirs
ist als Argument für eine Rebasierung kontraintuitiv, wie in der Beschreibung der Option at angegeben http://git-scm.com/docs/git-rebase