Gibt es eine "Ihre" version von "git merge -s ours"?
Frage
Beim Zusammenführen Thema Zweig "B" in "A" verwenden git merge
, Ich bekomme einige Konflikte.Ich weiß, alle Konflikte behoben werden können, mit der version "B".
Ich bin mir bewusst, git merge -s ours
.Aber was ich will, ist etwas wie git merge -s theirs
.
Warum nicht existieren?Wie kann ich das gleiche Ergebnis erzielen, nachdem der Konflikt Zusammenführen mit den bestehenden git
Befehle?(git checkout
jede nicht zusammengeführte Datei aus B)
UPDATE:Die "Lösung" der gerade zu verwerfen, etwas vom Zweig Ein (der merge-commit-Punkt B-version des Baum) ist, nicht das, was ich Suche.
Lösung
Fügen Sie die -X
Option theirs
. Zum Beispiel:
git checkout branchA
git merge -X theirs branchB
Alles wird in der gewünschten Weise zusammenführen.
Das einzige, was ich Ursache Probleme gesehen habe, ist, wenn Dateien aus branchB gelöscht wurden. Sie zeigen sich als Konflikte, wenn etwas anderes als git die Entfernung hat.
Die Lösung ist einfach. Führen Sie einfach git rm
mit dem Namen von Dateien, die gelöscht wurden:
git rm {DELETED-FILE-NAME}
Danach sollten die -X theirs
wie erwartet.
Natürlich die tatsächliche Entfernung mit dem git rm
Befehl tun wird, den Konflikt geschieht in erster Linie verhindern.
Hinweis : Eine längere Form Option existiert auch. Um es zu nutzen, ersetzen:
-X theirs
mit:
--strategy-option=theirs
Andere Tipps
Eine mögliche und geprüfte Lösung für die branchB in unseren abgemeldeten branchA verschmelzenden:
# in case branchA is not our current branch
git checkout branchA
# make merge commit but without conflicts!!
# the contents of 'ours' will be discarded later
git merge -s ours branchB
# make temporary branch to merged commit
git branch branchTEMP
# get contents of working tree and index to the one of branchB
git reset --hard branchB
# reset to our merged commit but
# keep contents of working tree and index
git reset --soft branchTEMP
# change the contents of the merged commit
# with the contents of branchB
git commit --amend
# get rid off our temporary branch
git branch -D branchTEMP
# verify that the merge commit contains only contents of branchB
git diff HEAD branchB
Um es automatisieren Sie es in ein Skript mit branchA und branchB als Argumente wickeln kann.
Diese Lösung bewahrt die erste und zweite Elternteil der Zusammenführung verpflichten, so wie Sie von git merge -s theirs branchB
erwartet.
Ältere Versionen von git erlaubt Sie zu verwenden die "ihrigen" merge-Strategie:
git pull --strategy=theirs remote_branch
Aber das wurde seitdem entfernt, wie bereits erläutert, die in dieser Meldung durch Junio Hamano (die Git-Betreuer).Wie bereits in den link, stattdessen würden Sie dies tun:
git fetch origin
git reset --hard origin
Beachten Sie aber, dass dies anders ist, als eine tatsächliche Zusammenführen.Ihre Lösung ist wahrscheinlich die option, die Sie wirklich suchen.
habe ich die Antwort von Paul Pladijs da jetzt. Ich fand heraus, Sie tun können, ein „normales“ verschmelzen, Konflikte auftreten, so können Sie tun
git checkout --theirs <file>
, um den Konflikt zu lösen, indem die Revision aus dem anderen Zweig verwenden. Wenn Sie diese Datei für jeden tun, haben Sie das gleiche Verhalten wie Sie es erwarten würde
git merge <branch> -s theirs
Wie auch immer, ist die Anstrengung mehr, als es mit der merge-Strategie sein würde! (Dies wurde mit git Version getestet 1.8.0)
Es ist nicht ganz klar, was Ihr gewünschtes Ergebnis ist, so gibt es einige Verwirrung über die „richtige“ Art und Weise davon in den Antworten und ihre Kommentare zu tun. Ich versuche, einen Überblick zu geben und sehen Sie die folgenden drei Möglichkeiten:
Versuchen und für Konflikte mit B fusionieren
Dies ist nicht die "ihre Version für git merge -s ours
", sondern die "ihre Version für git merge -X ours
" (was für git merge -s recursive -X ours
kurz ist):
git checkout branchA
# also uses -s recursive implicitly
git merge -X theirs branchB
Dies ist, was z.B. Alan W. Smith Antwort der Fall ist.
verwenden, um Inhalte von B nur
Dies erzeugt eine Zusammenführung für beide Zweige begehen, sondern verwirft alle Änderungen von branchA
und hält nur den Inhalt von branchB
.
# Get the content you want to keep.
# If you want to keep branchB at the current commit, you can add --detached,
# else it will be advanced to the merge commit in the next step.
git checkout branchB
# Do the merge an keep current (our) content from branchB we just checked out.
git merge -s ours branchA
# Set branchA to current commit and check it out.
git checkout -B branchA
Beachten Sie, dass die Zusammenführung ersten Elternteil verpflichtet ist nun, dass aus branchB
und nur den zweiten von branchA
ist. Dies ist, was z.B. Gandalf458 Antwort der Fall ist.
verwenden, um Inhalte von B nur und hält richtiger Mutterauftrag
Dies ist die eigentliche „ihre Version für git merge -s ours
“. Es hat den gleichen Inhalt wie in der Option vor (das heißt nur, dass von branchB
), aber die Reihenfolge der Eltern korrekt ist, das heißt der erste Elternteil stammt aus branchA
und den zweiten von branchB
.
git checkout branchA
# Do a merge commit. The content of this commit does not matter,
# so use a strategy that never fails.
# Note: This advances branchA.
git merge -s ours branchB
# Change working tree and index to desired content.
# --detach ensures branchB will not move when doing the reset in the next step.
git checkout --detach branchB
# Move HEAD to branchA without changing contents of working tree and index.
git reset --soft branchA
# 'attach' HEAD to branchA.
# This ensures branchA will move when doing 'commit --amend'.
git checkout branchA
# Change content of merge commit to current index (i.e. content of branchB).
git commit --amend -C HEAD
Dies ist, was Paul Pladijs Antwort hat (ohne einen temporären Zweig erforderlich).
ich mein Problem gelöst mit
git checkout -m old
git checkout -b new B
git merge -s ours old
Wenn Sie auf Zweig A sind zu tun:
git merge -s recursive -X theirs B
Getestet auf git Version 1.7.8
Beim Thema Zweig "B" in "A" Verschmelzung git merge verwenden, erhalte ich einige Konflikte. I> wissen alle Konflikte gelöst werden können, die Version in "B" verwendet wird.
Ich bin mir bewusst, git merge es unserer. Aber was ich will, ist so etwas wie git merge> es sich.
Ich gehe davon aus, dass Sie einen Zweig erstellt aus dem Master-und wollen nun wieder in Master fusionieren, eine der alten Sachen in Master überschreiben. Das ist genau das, was ich tun wollte, als ich auf diesen Beitrag kam.
Sie genau, was Sie tun wollen, außer dem einen Zweig in den anderen ersten verschmelzen. Ich habe gerade diese, und es hat super funktioniert.
git checkout Branch
git merge master -s ours
Dann Kasse Master und fusionieren Ihre Niederlassung in ihr (es wird glatt jetzt gehen):
git checkout master
git merge Branch
wirklich richtig eine Zusammenführung zu tun, die Fertig Eingabe von dem Zweig Sie verschmelzen Sie tun können,
git merge --strategy=ours ref-to-be-merged
git diff --binary ref-to-be-merged | git apply --reverse --index
git commit --amend
Es wird keine Konflikte in jedem Szenario sein, die ich kenne, keine zusätzlichen Zweige machen müssen, und es verhält sich wie ein normaler merge begehen.
Dies spielt nicht schön mit Submodule jedoch.
Finden Junio Hamano ' s weithin zitiert Antwort:wenn du gehst, um Sie zu verwerfen verpflichtet, die Inhalte, einfach zu verwerfen, die begeht, oder jedenfalls halten Sie es außerhalb der Haupt-Geschichte.Warum die Mühe, alle in der Zukunft Lesen von commit-Nachrichten aus verpflichtet, die nichts zu bieten haben?
Manchmal sind es aber auch die administrativen Anforderungen, oder vielleicht einige andere Grund.Für solche Situationen, wo Sie wirklich zu erfassen verpflichtet, die nichts beitragen, Sie wollen:
(Bearbeiten:wow, Tat ich, um das falsch vor.Dieser arbeitet.)
git update-ref HEAD $(
git commit-tree -m 'completely superseding with branchB content' \
-p HEAD -p branchB branchB:
)
git reset --hard
Warum nicht existieren?
Während ich schon erwähnt, in "git-Befehl für die Herstellung einer wie der andere Zweig"wie zu simulieren git merge -s theirs
, beachten Sie , dass Git 2.15 (Q4 2017) ist nun klarer:
In der Dokumentation"
-X<option>
"für fusioniert war irreführend geschrieben zu vermuten, dass "-s theirs
"existiert, was nicht der Fall ist.
Finden commit c25d98b (25 Sep 2017) von Junio C Hamano (gitster
).
(Zusammengefasst von Junio C Hamano -- gitster
-- in commit 4da3e23, 28 Sep 2017)
merge-Strategien:vermeiden, was bedeutet, dass "
-s theirs
"bestehtDie Beschreibung
-Xours
merge-option hat ein parenthetical note das sagt dem Leser, dass es sehr unterschiedliche von-s ours
, das ist richtig, aber die Beschreibung-Xtheirs
folgt, dass es achtlos sagt: "das ist das Gegenteil vonours
", Angabe eines falschen Eindruck, dass die Leser auch die müssen gewarnt werden, dass es sehr anders-s theirs
, die in Wirklichkeit gar nicht gibt.
-Xtheirs
ist ein Strategie option angewendet, um rekursive Strategie.Dies bedeutet, dass die rekursive Strategie wird noch immer Zusammenführen alles, was es kann und wird nur fallen, zurück zu sein "theirs
"die Logik im Falle von Konflikten.
Diese Debatte für die Relevanz oder nicht theirs
merge-Strategie zurück geholt wurde vor kurzem in diesem Sept.2017-thread.
Es erkennt älter (2008) - threads
Kurz gesagt, die bisherige Diskussion kann zusammengefasst werden zu "wollen wir nicht '
-s theirs
'denn es regt die falsche workflow".
Es erwähnt die alias:
mtheirs = !sh -c 'git merge -s ours --no-commit $1 && git read-tree -m -u $1' -
Yaroslav Halchenko versucht zu befürworten, der einmal mehr, dass die Strategie, aber Junio C.Hamano fügt:
Der Grund, warum die unseren und die ihrigen sind nicht symmetrisch ist, weil du du bist und nicht Sie---Kontrolle und Eigentümerschaft von unserer Geschichte und Ihre Geschichte ist nicht symmetrisch.
Wenn Sie entscheiden, dass Ihre Geschichte ist die Hauptlinie, Sie würde lieber gönnen möchten, Ihre Entwicklung als ein Seitenzweig und machen Sie einen Seriendruck in, dass Richtung, d.h.die ersten Eltern der resultierende merge ist ein commit auf Ihre Geschichte und die zweite Elternteil ist die Letzte schlechte einer Ihrer Geschichte.So würden Sie am Ende mit "
checkout their-history && merge -s ours your-history
"zu halten Sie die erste-elternschaft sinnvoll.Und an diesem Punkt, die Verwendung von "
-s ours
"ist nicht mehr ein workaround für das fehlen des "-s theirs
".
Es ist die richtige Teil Sie die gewünschte Semantik, d.h.aus der Sicht der überlebenden kanonische Geschichte Linie, die Sie beibehalten möchten, was es getan hat, zunichte, was sich die andere Linie der Geschichte machte.
Dies verwendet git Plumbing Befehl read-Baum, sondern sorgt für einen kürzeren Gesamtarbeitsablauf.
git checkout <base-branch>
git merge --no-commit -s ours <their-branch>
git read-tree -u --reset <their-branch>
git commit
# Check your work!
git diff <their-branch>
Dies wird fusionieren Ihre newBranch in bestehenden baseBranch
git checkout <baseBranch> // this will checkout baseBranch
git merge -s ours <newBranch> // this will simple merge newBranch in baseBranch
git rm -rf . // this will remove all non references files from baseBranch (deleted in newBranch)
git checkout newBranch -- . //this will replace all conflicted files in baseBranch
Ich denke, was Sie wirklich wollen, ist:
git checkout -B mergeBranch branchB
git merge -s ours branchA
git checkout branchA
git merge mergeBranch
git branch -D mergeBranch
Das scheint ungeschickt, aber es sollte funktionieren. Die einzige, wirklich Ich mag nicht über diese Lösung die git Geschichte ist verwirrend sein ... Aber zumindest wird die Geschichte vollständig erhalten bleiben und Sie werden nicht etwas Besonderes für gelöschte Dateien tun müssen.
Das äquivalent (die Mutter Ordnung zu halten) auf 'GIT fusioniert es ihre branchB'
!!! Stellen Sie sicher, dass Sie in einem sauberen Zustand sind !!!
Haben die Zusammenführung:
git commit-tree -m "take theirs" -p HEAD -p branchB 'branchB^{tree}'
git reset --hard 36daf519952 # is the output of the prev command
Was wir getan haben? Wir haben ein neues begehen, welche zwei Eltern unsere und ihre und die Contnet des begehen ist branchB - ihre
Genauer gesagt:
git commit-tree -m "take theirs" -p HEAD -p 'SOURCE^{commit}' 'SOURCE^{tree}'
Diese Antwort wurde von Paul Pladijs gegeben. Ich nahm nur seine Befehle und machte einen git alias für die Bequemlichkeit.
Bearbeiten Sie Ihre .gitconfig und fügen Sie den folgenden:
[alias]
mergetheirs = "!git merge -s ours \"$1\" && git branch temp_THEIRS && git reset --hard \"$1\" && git reset --soft temp_THEIRS && git commit --amend && git branch -D temp_THEIRS"
Dann können Sie "git es ihre A merge", indem Sie:
git checkout B (optional, just making sure we're on branch B)
git mergetheirs A
Ich habe gerade vor kurzem für zwei getrennte Repositories tun dies benötigt, die eine gemeinsame Geschichte. Ich begann mit:
-
Org/repository1 master
-
Org/repository2 master
Ich wollte alle Änderungen von repository2 master
auf repository1 master
angewendet werden, um alle Änderungen zu akzeptieren, dass repository2 würde. In git Hinsicht, diese sollte eine Strategie namens -s theirs
sein, aber es existiert nicht. Seien Sie vorsichtig, weil -X theirs
wie es genannt wird, wäre das, was Sie wollen, aber es ist nicht die gleiche (es sagt auch so in der Manpage).
So wie ich dieses Problem gelöst war repository2
zu gehen und eine Niederlassung repo1-merge
zu machen. In diesem Zweig, lief ich git pull git@gitlab.com:Org/repository1 -s ours
und es verschmilzt ohne Probleme in Ordnung. Ich schiebe sie dann auf die Fernbedienung.
Dann gehe ich zurück zu repository1
und eine Niederlassung repo2-merge
zu machen. In diesem Zweig betreibe ich git pull git@gitlab.com:Org/repository2 repo1-merge
, die sich mit Fragen abgeschlossen wird.
Schließlich würde benötigen Sie entweder einen Merge Anfrage in repository1
auszustellen, um es den neuen Master zu machen, oder es nur als Zweig halten.
Eine einfache und intuitive (meiner Meinung nach) zweistufigen Art und Weise, es zu tun ist
git checkout branchB .
git commit -m "Picked up the content from branchB"
gefolgt von
git merge -s ours branchB
(die die beiden Zweige als fusionierte markiert)
Der einzige Nachteil ist, dass es keine Dateien zu entfernen, die in branchB von Ihrem aktuellen Zweig gelöscht wurden. Ein einfaches diff zwischen den beiden Zweigen wird danach zeigen, ob es irgendwelche solche Dateien.
auch Dieser Ansatz macht es aus dem Revisionsprotokoll klar danach, was getan wurde -. Und was sollte