Ich möchte kein visuelles Zusammenführungswerkzeug, und ich möchte auch nicht die in Konflikt stehende Datei anzeigen und manuell zwischen HEAD (mir) und der importierten Änderung (deren) wählen müssen. Die meiste Zeit möchte ich entweder alle oder alle meine Änderungen haben. Dies ist im Allgemeinen darauf zurückzuführen, dass meine Änderung die Anforderungen erfüllt hat und durch Ziehen zu mir zurückkehrt, aber möglicherweise an verschiedenen Stellen geringfügig geändert wird.
Gibt es ein Kommandozeilen-Tool, das die Konfliktmarkierungen entfernt und auf die eine oder andere Art und Weise auswählt, wie ich es gewählt habe? Oder eine Reihe von Git-Befehlen, die ich mir jeweils selbst geben kann.
# accept mine
alias am="some_sequence;of;commands"
alias at="some_other_sequence;of;commands"
Das zu tun ist ziemlich nervig. Für 'akzeptiere meine' habe ich versucht:
[email protected] ~/linus $ git merge test-branch
Auto-merging Makefile
CONFLICT (content): Merge conflict in Makefile
Automatic merge failed; fix conflicts and then commit the result.
[email protected] ~/linus $ git checkout Makefile
error: path 'Makefile' is unmerged
[email protected] ~/linus $ git reset --hard HEAD Makefile
fatal: Cannot do hard reset with paths.
Wie soll ich diese Änderungsmarker loswerden?
Ich kann:
git reset HEAD Makefile; rm Makefile; git checkout Makefile
Aber das scheint ziemlich rund, es muss einen besseren Weg geben. Und zum jetzigen Zeitpunkt bin ich mir nicht sicher, ob git überhaupt glaubt, dass die Fusion stattgefunden hat, also denke ich nicht, dass dies notwendigerweise überhaupt funktioniert.
In die andere Richtung zu gehen, „ihre anzunehmen“, ist ebenso chaotisch. Der einzige Weg, wie ich es herausfinden kann, ist:
git show test-branch:Makefile > Makefile; git add Makefile;
Dies gibt mir auch eine durcheinandergebrachte Commit-Nachricht, die zweimal Conflicts: Makefile enthält.
Kann jemand bitte darauf hinweisen, wie die beiden oben genannten Aktionen auf einfachere Weise durchgeführt werden können? Vielen Dank
Die Lösung ist sehr einfach. git checkout <filename>
versucht, die Datei aus dem Index auszuchecken, und schlägt daher beim Zusammenführen fehl.
Was Sie tun müssen, ist (d. H. Auschecken eines Festschreiben):
Zum Auschecken Ihrer eigenen Version Sie können eine von:
git checkout HEAD -- <filename>
oder
git checkout --ours -- <filename>
oder
git show :2:<filename> > <filename> # (stage 2 is ours)
Zum Auschecken der anderen Version Sie können eines von:
git checkout test-branch -- <filename>
oder
git checkout --theirs -- <filename>
oder
git show :3:<filename> > <filename> # (stage 3 is theirs)
Sie müssten auch 'add' ausführen, um es als gelöst zu markieren:
git add <filename>
Versuche dies:
Um ihre Änderungen zu akzeptieren: git merge --strategy-option theirs
Um deine zu akzeptieren: git merge --strategy-option ours
Basierend auf der Antwort von Jakub können Sie die folgenden Git-Aliase zur Vereinfachung konfigurieren:
accept-ours = "!f() { git checkout --ours -- \"${@:-.}\"; git add -u \"${@:-.}\"; }; f"
accept-theirs = "!f() { git checkout --theirs -- \"${@:-.}\"; git add -u \"${@:-.}\"; }; f"
Sie können optional einen oder mehrere Dateipfade zum Auflösen verwenden und standardmäßig alles im aktuellen Verzeichnis auflösen, wenn keine angegeben sind.
Fügen Sie sie dem Abschnitt [alias]
Ihres ~/.gitconfig
Hinzu oder führen Sie sie aus
git config --global alias.accept-ours '!f() { git checkout --ours -- "${@:-.}"; git add -u "${@:-.}"; }; f'
git config --global alias.accept-theirs '!f() { git checkout --theirs -- "${@:-.}"; git add -u "${@:-.}"; }; f'
Basierend auf der Antwort von kynan sind hier die gleichen Aliase, die so geändert wurden, dass sie Leerzeichen und anfängliche Gedankenstriche in Dateinamen verarbeiten können:
accept-ours = "!f() { [ -z \"[email protected]\" ] && set - '.'; git checkout --ours -- \"[email protected]\"; git add -u -- \"[email protected]\"; }; f"
accept-theirs = "!f() { [ -z \"[email protected]\" ] && set - '.'; git checkout --theirs -- \"[email protected]\"; git add -u -- \"[email protected]\"; }; f"
Die ideale Situation zum Lösen von Konflikten ist, wenn Sie im Voraus wissen, auf welche Weise Sie sie lösen möchten, und die Optionen -Xours
Oder -Xtheirs
Für rekursive Zusammenführungsstrategien übergeben können. Draußen sehe ich drei Szenarien:
Um diese drei Szenarien zu lösen, können Sie Ihrer .gitconfig
- Datei (oder einer entsprechenden Datei) die folgenden Zeilen hinzufügen:
[merge]
conflictstyle = diff3
[mergetool.getours]
cmd = git-checkout --ours ${MERGED}
trustExitCode = true
[mergetool.mergeours]
cmd = git-merge-file --ours ${LOCAL} ${BASE} ${REMOTE} -p > ${MERGED}
trustExitCode = true
[mergetool.keepours]
cmd = sed -I '' -e '/^<<<<<<</d' -e '/^|||||||/,/^>>>>>>>/d' ${MERGED}
trustExitCode = true
[mergetool.gettheirs]
cmd = git-checkout --theirs ${MERGED}
trustExitCode = true
[mergetool.mergetheirs]
cmd = git-merge-file --theirs ${LOCAL} ${BASE} ${REMOTE} -p > ${MERGED}
trustExitCode = true
[mergetool.keeptheirs]
cmd = sed -I '' -e '/^<<<<<<</,/^=======/d' -e '/^>>>>>>>/d' ${MERGED}
trustExitCode = true
Das Tool get(ours|theirs)
behält nur die jeweilige Version der Datei bei und verwirft alle Änderungen von der anderen Version (es findet also keine Zusammenführung statt).
Das Tool merge(ours|theirs)
führt die Drei-Wege-Zusammenführung aus der lokalen, der Basis- und der Remoteversion der Datei erneut durch und löst Konflikte in der angegebenen Richtung. Dies hat einige Einschränkungen, insbesondere: Es werden die Diff-Optionen ignoriert, die an den Merge-Befehl übergeben wurden (z. B. Algorithmus- und Whitespace-Behandlung). Führt die Zusammenführung sauber von den Originaldateien aus (so dass alle manuellen Änderungen an der Datei verworfen werden, die gut oder schlecht sein können); und hat den Vorteil, dass es nicht durch Diff-Marker verwechselt werden kann, die in der Datei enthalten sein sollen.
Das Werkzeug keep(ours|theirs)
bearbeitet einfach die Diff-Marken und eingeschlossenen Abschnitte und erkennt sie durch regulären Ausdruck. Dies hat den Vorteil, dass die Diff-Optionen aus dem Merge-Befehl erhalten bleiben und Sie einige Konflikte manuell lösen und den Rest automatisch lösen können. Dies hat den Nachteil, dass andere Konfliktmarkierungen in der Datei verwirrt werden können.
Diese werden alle durch Ausführen von git mergetool -t (get|merge|keep)(ours|theirs) [<filename>]
verwendet, wobei, wenn <filename>
Nicht angegeben wird, alle in Konflikt stehenden Dateien verarbeitet werden.
Wenn Sie wissen, dass es keine Diff-Marker gibt, die den regulären Ausdruck verwirren, sind die keep*
- Varianten des Befehls im Allgemeinen die mächtigsten. Wenn Sie die Option mergetool.keepBackup
Nicht setzen oder auf true setzen, können Sie nach dem Zusammenführen die Datei *.orig
Mit dem Ergebnis des Zusammenführens vergleichen, um zu überprüfen, ob dies sinnvoll ist. Als Beispiel führe ich nach dem mergetool
Folgendes aus, um die Änderungen vor dem Festschreiben zu überprüfen:
for f in `find . -name '*.orig'`; do vimdiff $f ${f%.orig}; done
Hinweis: Wenn merge.conflictstyle
Nicht diff3
Ist, muss das /^|||||||/
- Muster in der sed
-Regel /^=======/
stattdessen.