385 Stimmen

Wie kann ich in Git einen Zweig mit einem anderen Zweig "überschreiben", anstatt ihn "zusammenzuführen"?

Ich habe zwei Zweige, email y staging . staging ist die neueste und ich brauche die alten Änderungen nicht mehr in email Zweig, aber ich möchte sie nicht löschen.

Ich möchte also einfach den gesamten Inhalt von staging in email so dass sie beide auf dieselbe Übergabe verweisen. Ist das möglich?

313voto

knittl Punkte 214432

Sie können die unsere" Fusionsstrategie :

$ git checkout staging
$ git merge -s ours email # Merge branches, but use our (=staging) branch head
$ git checkout email
$ git merge staging

EDIT 2020-07-30:

Ich habe ein wenig mehr über diese Frage und mögliche Lösungen nachgedacht. Wenn Sie die Merge-Eltern unbedingt in der richtigen Reihenfolge benötigen, diese Aktion mit einem einzigen Befehlszeilenaufruf durchführen müssen und Ihnen die Ausführung von Klempnerbefehlen nichts ausmacht, können Sie Folgendes tun:

$ git checkout A
$ git merge --ff-only $(git commit-tree -m "Throw away branch 'A'" -p A -p B B^{tree})

Dies wirkt im Grunde wie die (nicht existierende) merge -s theirs Strategie. Die daraus resultierende Historie finden Sie in der plumbing Zweig des Demo-Repositorys

Nicht sehr lesbar und nicht so leicht zu merken wie die -s ours Schalter, aber er erfüllt seinen Zweck. Der resultierende Baum ist wieder derselbe wie der Zweig B:

$ git rev-parse A^{tree} B^{tree} HEAD^{tree}
3859ea064e85b2291d189e798bfa1bff87f51f3e
0389f8f2a3e560b639d82597a7bc5489a4c96d44
0389f8f2a3e560b639d82597a7bc5489a4c96d44

BEARBEITEN 2020-07-29:

Es scheint eine große Verwirrung darüber zu geben, was der Unterschied zwischen -s ours y -X ours (letzteres ist gleichbedeutend mit -s recursive --strategy-option ours ) ist. Hier ist ein kleines Beispiel, das die beiden Ergebnisse der beiden Methoden zeigt. Ich empfehle auch die Lektüre der Fragen und Antworten von (Git Merging) Wann sollte man die Strategie "ours", die Option "ours" und die Option "theirs" verwenden?

Legen Sie zunächst ein Repository mit 2 Zweigen und 3 Commits an (1 Basis-Commit und 1 Commit pro Zweig). Sie finden das Beispiel-Repository auf GitHub

$ git init
$ echo 'original' | tee file1 file2 file3
$ git commit -m 'initial commit'
$ git branch A
$ git branch B
$ git checkout A
$ echo 'A' > file1
$ git commit -m 'change on branch A' file1
$ git checkout B
$ echo 'B' > file2
$ git commit -m 'change on branch B' file2

Versuchen wir nun die Strategieoption (es spielt keine Rolle, ob wir für diese Erklärung ihre oder unsere eigenen Daten verwenden):

$ git merge -X ours A
$ cat file*
A
B
original

Wir enden mit einer zusammenführen der Inhalte beider Zweige (Zweig "strategy-option" im Beispielrepo). Vergleichen Sie dies mit der Verwendung der Fusionsstrategie (führen Sie Ihr Repository neu ein oder setzen Sie den Zweig zurück, bevor Sie die nächsten Schritte ausführen):

$ git merge -s ours A
$ cat file*
original
B
original

Das Ergebnis ist ganz anders (Zweig "merge-strategy" im Beispielrepo). Mit der Strategieoption erhalten wir ein Zusammenführungsergebnis beider Zweige, mit der Strategie verwerfen wir alle Änderungen, die im anderen Zweig vorgenommen wurden.

Sie werden auch bemerken, dass die von der Zusammenführungsstrategie erzeugte Übergabe genau auf denselben Baum verweist wie die letzte Übergabe "unseres" Zweigs, während die Strategie-Option einen neuen, vorher nicht gesehenen Baum erzeugt hat:

$ git rev-parse A^{tree} B^{tree} merge-strategy^{tree} strategy-option^{tree}
3859ea064e85b2291d189e798bfa1bff87f51f3e
0389f8f2a3e560b639d82597a7bc5489a4c96d44
0389f8f2a3e560b639d82597a7bc5489a4c96d44
5b09d34a37a183723b409d25268c8cb4d073206e

OP fragte in der Tat nach "Ich brauche die alten Änderungen im [ ]-Zweig nicht mehr" und "Ich möchte also einfach den gesamten Inhalt von [A] nach [B] verschieben", was mit einer Strategieoption nicht möglich ist. Die Verwendung der 'ours' Merge-Strategie ist eine Möglichkeit von vielen, aber wahrscheinlich die einfachste (andere Möglichkeiten sind die Verwendung von Low-Level-Befehlen von Git wie write-tree y commit-tree ).

133voto

Sylvain Defresne Punkte 39987

Wenn Sie nur wollen, dass die beiden Zweige "E-Mail" und "Staging" gleich sind, können Sie den Zweig "E-Mail" markieren und dann den Zweig "E-Mail" auf den Zweig "Staging" zurücksetzen:

$ git checkout email
$ git tag old-email-branch
$ git reset --hard staging

Sie können auch den "Staging"-Zweig auf den "E-Mail"-Zweig zurücksetzen. Das Ergebnis wird jedoch die Änderung der beiden Zweige enthalten.

127voto

Brugolo Punkte 4165

Ich habe mehrere Antworten gesehen, und das ist das einzige Verfahren, mit dem ich das ohne Konflikte beheben konnte.

Wenn Sie alle Änderungen von branch_new in branch_old haben wollen, dann:

git checkout branch_new
git merge -s ours branch_old
git checkout branch_old
git merge branch_new

Wenn Sie diese vier Befehle angewendet haben, können Sie den alten Zweig ohne Probleme pushen

75voto

Shyam Habarakada Punkte 14267

Die anderen Antworten gaben mir zwar die richtigen Hinweise, aber sie halfen nicht vollständig weiter.

Bei mir hat das folgendermaßen funktioniert:

$ git checkout email
$ git tag old-email-branch # This is optional
$ git reset --hard staging
$
$ # Using a custom commit message for the merge below
$ git merge -m 'Merge -s our where _ours_ is the branch staging' -s ours origin/email
$ git push origin email

Ohne den vierten Schritt des Zusammenführens mit unserer Strategie wird der Push als nicht-schnelles Update betrachtet und (von GitHub) abgelehnt.

65voto

jsarma Punkte 1274

Wenn es Ihnen wie mir geht und Sie sich nicht mit dem Zusammenführen beschäftigen wollen, können Sie die oben genannten Schritte durchführen, nur dass Sie statt "Zusammenführen" "Erzwingen" verwenden, da dies einen störenden Papierpfad im Protokoll erzeugt:

git checkout email
git reset --hard staging
git push origin email --force

Hinweis: Dies ist nur dann sinnvoll, wenn Sie das Material in der E-Mail WIRKLICH nie wieder sehen wollen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X