Gibt es eine "ihre" Version von "git merge -s our"?

876

Wenn git mergeich den Themenzweig "B" mit "A" zusammenführe, treten Konflikte auf. Ich weiß, dass alle Konflikte mit der Version in "B" gelöst werden können.

Ich bin mir bewusst git merge -s ours. Aber was ich will, ist so etwas wie git merge -s theirs.

Warum existiert es nicht? Wie kann ich nach der widersprüchlichen Zusammenführung mit vorhandenen gitBefehlen das gleiche Ergebnis erzielen ? ( git checkoutjede nicht zusammengeführte Datei von B)

UPDATE: Die "Lösung", nur etwas aus Zweig A (dem Merge-Commit-Punkt zur B-Version des Baums) zu verwerfen, ist nicht das, wonach ich suche.

Elmarco
quelle
1
Siehe auch diese Antwort: stackoverflow.com/questions/928646/… - Es ist trivial, das Beispiel zu ändern, um Version B anstelle von A zu verwenden.
Robie Basak
8
Unter dem Befehl SO answer git finden Sie Informationen zum Erstellen eines Zweigs wie einen anderen für alle derzeit möglichen Simulationsmöglichkeitengit merge -s their .
VonC
4
Sie suchen also nicht wirklich nach einem git merge -s theirs(was mit git merge -s oursund einem temporären Zweig leicht zu erreichen ist ), da wir die Änderungen des Zusammenführungszweigs völlig ignorieren ...
Nicolò Martini
21
@Torek - tut das Git Devs wirklich es findet , dass Offensive zu schaffen , theirsum zusätzlich ours??? Dies ist ein Symptom für eines der allgemeinen Engineering- und Designprobleme in Git: Inkonsistenz.
JWW
3
@jww Das Problem hier ist nicht, dass "git merge -s our" anstößig ist, sondern dass es kontraintuitiv ist. Sie können der Frage des OP entnehmen, dass eine solche Funktion, wenn sie hinzugefügt würde, versehentlich verwendet würde, wenn er tatsächlich eine "git merge -s rekursive -X ihre" tun möchte. Es ist üblich, einen anderen Zweig zusammenzuführen, der Konflikte mit der Version des anderen Zweigs überschreibt, aber das vollständige Überschreiben des aktuellen Zweigs mit einem anderen Zweig, bei dem die Änderungen des aktuellen Zweigs vollständig verworfen werden, ist wirklich ein Ausnahmefall.
ThomazMoura

Antworten:

1019

Fügen Sie die -XOption hinzu theirs. Zum Beispiel:

git checkout branchA
git merge -X theirs branchB

Alles wird auf die gewünschte Weise zusammengeführt.

Ich habe nur Probleme gesehen, wenn Dateien aus branchB gelöscht wurden. Sie erscheinen als Konflikte, wenn etwas anderes als Git die Entfernung durchgeführt hat.

Die Lösung ist einfach. Führen Sie einfach git rmden Namen aller gelöschten Dateien aus:

git rm {DELETED-FILE-NAME}

Danach -X theirssollte das wie erwartet funktionieren.

Das eigentliche Entfernen mit dem git rmBefehl verhindert natürlich, dass der Konflikt überhaupt erst auftritt.


Hinweis : Es gibt auch eine längere Formularoption.

Um es zu verwenden, ersetzen Sie:

-X theirs

mit:

--strategy-option=theirs
Alan W. Smith
quelle
6
Siehe eine andere Antwort unten für eine bessere Lösung (Paul Pladijs) für die ursprüngliche Frage.
Malcolm
204
Es ist anzumerken, dass dies nicht dasselbe ist wie "Zusammenführungsstrategie theirs". -Xtheirs ist die Strategie Option auf rekursive angewendet Strategie . Dies bedeutet, dass die rekursive Strategie immer noch alles zusammenführt, was sie kann, und nur im Falle von Konflikten auf "ihre" Logik zurückgreift. Während dies in den meisten Fällen wie oben beschrieben ist, ist dies nicht dasselbe wie "Nehmen Sie einfach alles aus Zweig B wie es ist". Es führt stattdessen sowieso die eigentliche Zusammenführung durch.
Timur
2
Es funktioniert auch mit anderen Befehlen. Ich habe gerade einen 'git cherry-pick sha1 -X ihnen' gemacht. Vielen Dank!
Max Hohenegger
48
Dies ist eine schreckliche Antwort, weil sie richtig aussieht, aber tatsächlich falsch ist. "git merge -X Theirs" macht nicht das, was "Git Merge -s Theirs" tun würde. Der aktuelle Zweig wird nicht durch den Inhalt des zusammengeführten Zweigs ersetzt. Es bevorzugt "ihre" Änderungen, aber nur im Konfliktfall. Daher kann sich das resultierende Commit stark von dem Zweig "ihrer" unterscheiden. Dies war nicht das, was das Fragenplakat im Sinn hatte.
Ivan Krivyakov
7
@ user3338098: Ja, du hast recht. Ich habe die Frage noch einmal gelesen und sie ist auch nicht so gut. Leider ist die Hauptursache für die Verwirrung nicht die Antwort und nicht einmal die Frage. Es ist die Designentscheidung der Git-Autoren, einer Zusammenführungsstrategie den gleichen Namen "uns" und einer Option der Zusammenführungsstrategie "rekursiv" den gleichen Namen zu geben. Die Verwirrung in diesem Fall ist praktisch unvermeidlich.
Ivan Krivyakov
218

Eine mögliche und getestete Lösung zum Zusammenführen von branchB mit unserem ausgecheckten branchA:

# 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 zu automatisieren, können Sie es mit branchA und branchB als Argumenten in ein Skript einbinden.

Diese Lösung behält das erste und zweite übergeordnete Element des Zusammenführungs-Commits bei, genau wie Sie es erwarten würden git merge -s theirs branchB.

Paul Pladijs
quelle
F: Warum brauchen Sie branchTEMP? Könntest du nicht einfach git reset --soft branchA?
cdunn2001
4
@ cdunn2001: Irgendwie dachte ich das Gleiche, aber nein. Beachten Sie, dass git reset --hardÄnderungen, auf die festgeschrieben wird, branchAdarauf verweisen .
Tsuyoshi Ito
5
Es tut mir leid, eine dumme Frage zu stellen, aber warum ist diese Methode besser als die -xtheirs? Was sind die Vor- und Nachteile
chrispepper1989
9
@ chrispepper1989 -x Ihre Auswirkungen betreffen nur Konflikte . Wenn ein Teil von uns sauber angewendet werden kann, gelangt er zur resultierenden Zusammenführung. In diesem Fall erhalten wir, wie der letzte Befehl zeigt, eine Zusammenführung, die mit branchB vollkommen identisch ist, unabhängig davon, ob es Konflikte gegeben hätte oder nicht.
Onkel Zeiv
2
@UncleZeiv, danke für die Erklärung. Wenn Sie also im Grunde genommen ein "ihre" ausführen, bleiben widersprüchliche Änderungen und Dateien erhalten, die zu int-Code führen, der nicht mit dem gezogenen Code identisch ist.
chrispepper1989
89

In älteren Versionen von git konnten Sie die Zusammenführungsstrategie "ihrer" verwenden:

git pull --strategy=theirs remote_branch

Dies wurde jedoch inzwischen entfernt, wie in dieser Nachricht von Junio ​​Hamano (dem Git-Betreuer) erläutert . Wie im Link angegeben, würden Sie stattdessen Folgendes tun:

git fetch origin
git reset --hard origin

Beachten Sie jedoch, dass dies anders ist als eine tatsächliche Zusammenführung. Ihre Lösung ist wahrscheinlich die Option, nach der Sie wirklich suchen.

Pat Notz
quelle
7
Ich verstehe Junio ​​Hamanos Erklärung überhaupt nicht. Wie ist git reset --hard origineine Lösung für eine Zusammenführung ihres Stils? Wenn ich BranchB in BranchA zusammenführen wollte (wie in der Antwort von Alan W. Smith), wie würde ich das mit der resetMethode machen?
James McMahon
3
@ James McMahon: Junio ​​C Hamano geht es nicht darum, git reset --hardeine Verschmelzung im "ihre" -Stil durchzuführen . Erstellt natürlich git reset --hardkein Merge-Commit oder Commit für diese Angelegenheit. Sein Punkt ist, dass wir keine Zusammenführung verwenden sollten , um irgendetwas in HEAD durch etwas anderes zu ersetzen. Ich stimme jedoch nicht unbedingt zu.
Tsuyoshi Ito
11
Es ist eine Schande, dass das theirsentfernt wurde, weil die Begründung unvollständig war. Es hat nicht die Fälle berücksichtigt, in denen der Code gut ist. Es ist nur so, dass der Upstream auf einer anderen philosophischen Basis aufrechterhalten wird. In diesem Sinne ist er also "schlecht", also möchte man beide mit dem Upstream auf dem Laufenden bleiben, aber Gleichzeitig behalten Sie Ihre guten Code-Korrekturen bei [git & msysgit haben dies einige dieser "Konflikte" aufgrund der unterschiedlichen Philosophien ihrer Zielplattform]
Philip Oakley
1
Es fehlt auch der Anwendungsfall, an dem ich gerade festhalte, wo ich einen Zweig mit jemand anderem teile und wir beide gleichzeitig Änderungen (an verschiedenen Dateien) vorantreiben. Also möchte ich alle alten Versionen, die ich lokal habe, überfallen und stattdessen seine neueren verwenden. Er möchte dasselbe für die Dateien tun, die ich aktualisiert habe. Es gibt nichts zurückzusetzen. Und die Lösung zum Auschecken jeder einzelnen Datei ist nicht praktikabel, wenn es sich um ~ 20 Dateien handelt.
szeitlin
2
Ich verstehe die Philosophie wirklich nicht. Ich habe es nur verwendet, theirsweil ich versehentlich einige Dateien in zwei separaten Zweigen geändert hatte und die Änderungen von einem verwerfen wollte, ohne dies für jede Datei manuell tun zu müssen.
Sudo
65

Es ist nicht ganz klar, was Ihr gewünschtes Ergebnis ist, daher gibt es einige Verwirrung über die "richtige" Vorgehensweise in den Antworten und ihren Kommentaren. Ich versuche einen Überblick zu geben und sehe die folgenden drei Optionen:

Versuchen Sie, B zusammenzuführen und B für Konflikte zu verwenden

Dies ist nicht die "ihre Version für git merge -s ours", sondern die "ihre Version für git merge -X ours" (kurz für git merge -s recursive -X ours):

git checkout branchA
# also uses -s recursive implicitly
git merge -X theirs branchB

Dies ist, was zB die Antwort von Alan W. Smith tut.

Verwenden Sie nur Inhalte von B.

Dadurch wird ein Zusammenführungs-Commit für beide Zweige erstellt, alle Änderungen werden jedoch verworfen branchAund nur der Inhalt wird beibehalten 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 bei der Zusammenführung das erste übergeordnete Element jetzt das von branchBund nur das zweite von ist branchA. Dies ist, was zB die Antwort von Gandalf458 tut.

Verwenden Sie nur Inhalte von B und behalten Sie die korrekte übergeordnete Reihenfolge bei

Dies ist die echte "ihre Version für git merge -s ours". Es hat den gleichen Inhalt wie in der vorherigen Option (dh nur den von branchB), aber die Reihenfolge der Eltern ist korrekt, dh der erste Elternteil kommt von branchAund der zweite 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 die Antwort von Paul Pladijs (ohne dass eine vorübergehende Verzweigung erforderlich ist).

siegi
quelle
Eine sauberere Version von Option 3:git checkout branchA; git merge -s ours --no-commit branchB; git read-tree -um @ branchB; git commit
Bis
@jthill: Während deine Version prägnanter ist, verwendet sie auch den Low-Level-Befehl ("plumbing") read-tree, an den der durchschnittliche Git-Benutzer möglicherweise nicht gewöhnt ist (zumindest bin ich das nicht ;-)). Die Lösungen in der Antwort verwenden nur die Befehle auf hoher Ebene ("Porzellan"), die die meisten Git-Benutzer kennen sollten. Ich bevorzuge sie, aber trotzdem danke für deine Version!
Siegi
Können Sie den vorletzten Schritt erklären (Kasse branchA)? Es scheint, als sollte es nicht da sein.
Patrick
@Patrick, dieser Schritt ist erforderlich. Wenn Sie es überspringen, erhalten Sie das gleiche Commit, aber es gibt keinen Zweig, der auf dieses Commit verweist. Sobald Sie also zu einem anderen Commit / Zweig wechseln, geht das Commit, das Sie mit dem letzten Befehl ( …commit --amend…) ausgeführt haben, "verloren". Ich plane, dieser Antwort einige grafische Erklärungen hinzuzufügen, sobald ich Zeit dazu habe… ;-)
siegi
62

Ich habe seitdem die Antwort von Paul Pladijs verwendet. Ich habe herausgefunden, dass Sie eine "normale" Zusammenführung durchführen können, Konflikte auftreten, also tun Sie es

git checkout --theirs <file>

um den Konflikt mithilfe der Revision aus dem anderen Zweig zu lösen. Wenn Sie dies für jede Datei tun, haben Sie das gleiche Verhalten, das Sie erwarten würden

git merge <branch> -s theirs

Auf jeden Fall ist der Aufwand größer als bei der Merge-Strategie! (Dies wurde mit Git Version 1.8.0 getestet)

musicmatze
quelle
1
wäre toll, wenn die Liste der Dateien abgerufen werden könnte. Zum Beispiel git ls-files --modified | xargs git addwollte ich dies tun, um auf beiden Seiten zusammenzuführen: /
andho
Tatsächlich gibt git die auf beiden Seiten hinzugefügten Dateien mit zurück, git ls-files --modifieddaher denke ich, dass dies auch eine praktikable Lösung ist.
Andho
1
Danke, dass du das auch hinzugefügt hast. Meistens wird es nicht Datei für Datei benötigt. Außerdem zeigt der Git-Status ganz unten "Unmerged Paths" an. Um die Liste der ungelösten Pfade zu erhalten, verwende ich diesen Alias:git config --global alias.unresolved '!git status --short|egrep "^([DAU])\1"'
Melvyn
Was bedeutet -Xund was ist der Unterschied zwischen -Xund -s? kann kein Dokument finden.
Lei Yang
21

Ich habe mein Problem mit gelöst

git checkout -m old
git checkout -b new B
git merge -s ours old
Elmarco
quelle
ein Zweig "B" von "alten" Zweig
Elmarco
13

Beim Zusammenführen des Themenzweigs "B" in "A" mit Git Merge treten einige Konflikte auf. Ich weiß, dass alle Konflikte mit der Version in "B" gelöst werden können.

Ich bin mir unserer Zusammenführung bewusst. Aber was ich will, ist so etwas wie Git Merge.

Ich gehe davon aus, dass Sie einen Zweig von Master erstellt haben und nun wieder zu Master verschmelzen möchten, um alle alten Dinge in Master zu überschreiben. Genau das wollte ich tun, als ich auf diesen Beitrag stieß.

Tun Sie genau das, was Sie tun möchten, außer dass Sie zuerst den einen Zweig in den anderen zusammenführen. Ich habe das einfach gemacht und es hat großartig funktioniert.

git checkout Branch
git merge master -s ours

Dann checkout master und füge deinen Zweig darin zusammen (es wird jetzt reibungslos gehen):

git checkout master
git merge Branch
Gandalf458
quelle
1
Vielen Dank. Dies sollte die akzeptierte Antwort sein, bei weitem die einfachste und richtigste. Wenn Ihr Zweig hinter dem Master zurückliegt oder mit diesem in Konflikt steht, ist es der Zweigjob, der zusammengeführt wird und alles funktioniert, bevor alles wieder zum Master zusammengeführt wird.
StackHola
Das hat super funktioniert, danke.
Kodie Grantham
12

Wenn Sie sich in Zweig A befinden, tun Sie Folgendes:

git merge -s recursive -X theirs B

Getestet auf Git Version 1.7.8

rafalmag
quelle
8

Um eine Zusammenführung wirklich richtig durchzuführen, die nur Eingaben von dem Zweig enthält, den Sie zusammenführen, können Sie dies tun

git merge --strategy=ours ref-to-be-merged

git diff --binary ref-to-be-merged | git apply --reverse --index

git commit --amend

In keinem mir bekannten Szenario gibt es Konflikte, Sie müssen keine zusätzlichen Zweige erstellen und es verhält sich wie ein normales Zusammenführungs-Commit.

Dies spielt jedoch mit Submodulen nicht gut.

thoutbeckers
quelle
Was macht der -R hier?
P. Myer Nore
Auf diese Weise verlieren Sie den Verlauf von Dateien, die "verschoben und geändert" wurden. Habe ich recht?
Elysch
1
Das -R ist --reverse, ich habe die Antwort damit aktualisiert, um selbstdokumentierender zu sein.
Elijah Lynn
Dies scheint nicht zu funktionieren, wenn die Dateien, die Sie zusammenführen möchten, im eingehenden Zweig gelöscht werden.
LösenJ
7

Warum existiert es nicht?

Während ich in " git-Befehl zum Erstellen eines Zweigs wie eines anderen " erwähne, wie simuliert werden soll git merge -s theirs, ist zu beachten, dass Git 2.15 (Q4 2017) jetzt klarer ist:

Die Dokumentation für ' -X<option>' für Zusammenführungen wurde irreführend geschrieben, um darauf hinzuweisen, dass " -s theirs" existiert, was nicht der Fall ist.

Siehe Commit c25d98b (25. September 2017) von Junio ​​C Hamano ( gitster) .
(Zusammengeführt von Junio ​​C Hamano - gitster- in Commit 4da3e23 , 28. September 2017)

Zusammenführungsstrategien: Vermeiden Sie, dass " -s theirs" existiert

Die Beschreibung der -XoursZusammenführungsoption enthält eine Anmerkung in Klammern, die den Lesern mitteilt, dass sie sich stark von -s oursder korrekten unterscheidet. Die Beschreibung -Xtheirsfolgt jedoch nachlässig: "Dies ist das Gegenteil von ours", was einen falschen Eindruck vermittelt, den die Leser ebenfalls benötigen gewarnt zu werden, dass es sich sehr von dem unterscheidet -s theirs, was in Wirklichkeit gar nicht existiert.

-Xtheirsist eine Strategieoption, die auf eine rekursive Strategie angewendet wird. Dies bedeutet, dass die rekursive Strategie immer noch alles zusammenführt, was sie kann, und nur theirsim Falle von Konflikten auf die Logik zurückgreift .

Diese Debatte über die Relevanz oder Nicht-Relevanz einer theirsFusionsstrategie wurde kürzlich in diesem Thread vom September 2017 zurückgebracht .
Es erkennt ältere (2008) Threads an

Kurz gesagt, die vorherige Diskussion kann zu "Wir wollen nicht" zusammengefasst werden -s theirs, da dies den falschen Workflow fördert.

Es erwähnt den Alias:

mtheirs = !sh -c 'git merge -s ours --no-commit $1 && git read-tree -m -u $1' -

Jaroslaw Halchenko versucht erneut, sich für diese Strategie einzusetzen, aber Junio ​​C. Hamano fügt hinzu :

Der Grund, warum unsere und ihre nicht symmetrisch sind, ist, dass Sie Sie sind und nicht sie - die Kontrolle und das Eigentum an unserer Geschichte und ihrer Geschichte ist nicht symmetrisch.

Sobald Sie entschieden haben, dass ihre Historie die Hauptlinie ist, möchten Sie Ihre Entwicklungslinie lieber als Nebenzweig behandeln und eine Zusammenführung in diese Richtung vornehmen, dh das erste übergeordnete Element der resultierenden Zusammenführung ist eine Festschreibung für ihre Historie und die zweite Eltern sind die letzten schlechten in Ihrer Geschichte. Sie würden also " checkout their-history && merge -s ours your-history" verwenden, um die Erstelternschaft vernünftig zu halten.

Und zu diesem Zeitpunkt ist die Verwendung von " -s ours" keine Problemumgehung mehr, da " -s theirs" fehlt .
Es ist ein angemessener Teil der gewünschten Semantik, dh aus der Sicht der überlebenden kanonischen Geschichtslinie möchten Sie das, was sie getan hat, beibehalten und das, was die andere Geschichtslinie getan hat, zunichte machen .

Junio ​​fügt hinzu, wie von Mike Beaton kommentiert :

git merge -s ours <their-ref>effektiv sagt "Mark Commits, die in <their-ref>ihrem Zweig gemacht wurden, als Commits, die dauerhaft ignoriert werden sollen";
und dies ist wichtig, denn wenn Sie später aus späteren Zuständen ihres Zweigs zusammenführen, werden deren spätere Änderungen übernommen, ohne dass die ignorierten Änderungen jemals übernommen werden .

VonC
quelle
1
Dies ist eine nützliche Antwort, aber es wird kein wichtiger Punkt erwähnt, den ich gerade aus Junio ​​C. Hamanos Antwort verstanden habe: git merge -s ours <their-ref>Effektiv heißt es: "Markieren Sie Commits, die bis zu <Ihr-Ref> in ihrem Zweig erstellt wurden, als Commits, die dauerhaft ignoriert werden sollen." '; und dies ist wichtig, weil, wenn Sie später aus späteren Zuständen ihres Zweigs zusammenführen, ihre späteren Änderungen übernommen werden, ohne dass die ignorierten Änderungen jemals übernommen werden.
MikeBeaton
1
@ MikeBeaton Danke. Ich habe Ihren Kommentar zur besseren Sichtbarkeit in die Antwort aufgenommen.
VonC
5

Siehe Junio ​​Hamanos häufig zitierte Antwort : Wenn Sie festgeschriebene Inhalte verwerfen möchten, verwerfen Sie einfach die Festschreibungen oder halten Sie sie auf jeden Fall aus der Hauptgeschichte heraus. Warum sollte man in Zukunft alle belästigen, Commit-Nachrichten von Commits zu lesen, die nichts zu bieten haben?

Aber manchmal gibt es administrative Anforderungen oder vielleicht einen anderen Grund. Für Situationen, in denen Sie wirklich Commits aufzeichnen müssen, die nichts beitragen, möchten Sie:

(edit: wow, habe ich es geschafft, das vorher falsch zu verstehen. Dieses funktioniert.)

git update-ref HEAD $(
        git commit-tree -m 'completely superseding with branchB content' \
                        -p HEAD -p branchB    branchB:
)
git reset --hard
jthill
quelle
3

Dieser verwendet einen Lesebaum für den Git-Installationsbefehl, sorgt jedoch für einen kürzeren Gesamtworkflow.

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>
Michael R.
quelle
0

Dadurch wird Ihre neue Branche in der vorhandenen Basisbranche zusammengeführt

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
Pawan Maheshwari
quelle
Ich würde vorschlagen git commit --amend, am Ende Ihres Beispiels etwas hinzuzufügen , oder Benutzer sehen möglicherweise das Zusammenführungs-Commit mit git logund gehen davon aus, dass der Vorgang abgeschlossen ist.
Michael R
0

Ich denke, was Sie eigentlich 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. Der einzige Gedanke, den ich an dieser Lösung wirklich nicht mag, ist, dass der Git-Verlauf verwirrend sein wird ... Aber zumindest bleibt der Verlauf vollständig erhalten und Sie müssen für gelöschte Dateien nichts Besonderes tun.

briemers
quelle
0

Das Äquivalent (das die übergeordnete Reihenfolge beibehält) zu 'git merge -s itss branchB'

Vor dem Zusammenführen:Geben Sie hier die Bildbeschreibung ein

!!! Stellen Sie sicher, dass Sie in einem sauberen Zustand sind !!!

Führen Sie die Zusammenführung durch:

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 gemacht haben ? Wir haben ein neues Commit erstellt, das zwei Eltern von uns und von ihnen haben, und das Contnet des Commits ist branchB - von ihnen

Nach dem Zusammenführen:Geben Sie hier die Bildbeschreibung ein

Etwas präziser:

git commit-tree -m "take theirs" -p HEAD -p 'SOURCE^{commit}' 'SOURCE^{tree}'
Boaz Nahum
quelle
0

Diese Antwort wurde von Paul Pladijs gegeben. Ich habe nur seine Befehle angenommen und der Einfachheit halber einen Git-Alias ​​erstellt.

Bearbeiten Sie Ihre .gitconfig und fügen Sie Folgendes hinzu:

[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 merge -s its A" ausführen, indem Sie Folgendes ausführen:

git checkout B (optional, just making sure we're on branch B)
git mergetheirs A
Brain2000
quelle
-1

Ich musste dies erst kürzlich für zwei separate Repositorys tun, die einen gemeinsamen Verlauf haben. Ich begann mit:

  • Org/repository1 master
  • Org/repository2 master

Ich wollte, dass alle Änderungen von repository2 masterangewendet werden, repository1 masterund akzeptierte alle Änderungen, die Repository2 vornehmen würde. In gits Worten sollte dies eine Strategie sein, die -s theirsABER nicht existiert. Seien Sie vorsichtig, denn der -X theirsName lautet so, wie Sie es möchten, aber er ist NICHT derselbe (auf der Manpage steht dies sogar).

Ich habe das gelöst, indem repository2ich zu einem neuen Zweig gegangen bin repo1-merge. In diesem Zweig bin ich gelaufen git pull [email protected]:Org/repository1 -s oursund es geht ohne Probleme gut zusammen. Ich schiebe es dann auf die Fernbedienung.

Dann gehe ich zurück zu repository1und mache einen neuen Zweig repo2-merge. In diesem Zweig führe ich aus, git pull [email protected]:Org/repository2 repo1-mergewas mit Problemen abgeschlossen wird.

Schließlich müssten Sie entweder eine Zusammenführungsanforderung ausgeben repository1, um sie zum neuen Master zu machen, oder sie einfach als Zweig behalten.

Trann
quelle
-2

Eine einfache und intuitive (meiner Meinung nach) zweistufige Methode ist dies

git checkout branchB .
git commit -m "Picked up the content from branchB"

gefolgt von

git merge -s ours branchB

(was die beiden Zweige als zusammengeführt markiert)

Der einzige Nachteil ist, dass keine Dateien entfernt werden, die in Zweig B aus Ihrem aktuellen Zweig gelöscht wurden. Ein einfacher Unterschied zwischen den beiden Zweigen zeigt anschließend an, ob solche Dateien vorhanden sind.

Dieser Ansatz macht auch aus dem späteren Revisionsprotokoll deutlich, was getan wurde - und was beabsichtigt war.

Ruben
quelle
Dies mag für die ursprüngliche Frage richtig sein, das OP hat die Frage jedoch 2008 so aktualisiert, dass diese Antwort falsch ist.
user3338098
1
@ user3338098 Ja, so schade, dass sie den irreführenden Titel verlassen und nur ein nicht so sichtbares Update am Ende des Fragenkörpers geklatscht haben ... weil diese Antworten die Titelfrage richtig beantworten.
RomainValeri
Ich stimme @RomainValeri
AppleCiderGuy