Was ist der beste (und sicherste) Weg, um einen Git-Zweig mit dem Master zusammenzuführen?

2103

Ein neuer Zweig von masterwird erstellt, wir nennen es test.

Es gibt mehrere Entwickler, die sich entweder zu masteranderen Zweigen verpflichten oder diese erstellen und später zusammenführen master.

Nehmen wir an, die Arbeit testdauert mehrere Tage und Sie möchten ständig über die darin enthaltenen testCommits informiert werden master.

Ich tun würde , git pull origin masteraus test.

Frage 1: Ist das der richtige Ansatz? Andere Entwickler hätten leicht an denselben Dateien arbeiten können wie ich übrigens.


Meine Arbeit testist erledigt und ich bin bereit, sie wieder zusammenzuführen master. Hier sind die zwei Möglichkeiten, die ich mir vorstellen kann:

EIN:

git checkout test
git pull origin master
git push origin test
git checkout master
git pull origin test 

B:

git checkout test
git pull origin master
git checkout master
git merge test

Ich verwende es nicht, --rebaseda Rebase nach meinem Verständnis die Änderungen abruft masterund meine darüber stapelt, sodass Änderungen, die von anderen Personen vorgenommen wurden, überschrieben werden können.

Frage 2: Welche dieser beiden Methoden ist richtig? Was ist der Unterschied dort?

Das Ziel bei all dem ist es, meinen testZweig über die Ereignisse masterauf dem masterLaufenden zu halten, und später könnte ich sie wieder zusammenführen , um die Zeitachse so linear wie möglich zu halten.

moe
quelle
18
nein .. rebase nie überschreiben, sondern nur versuchen, eine sauberere Geschichte zu erreichen. durch
erneutes Anbringen
7
Rebase überschreibt Ihre Commits nicht. Es macht Ihre Commits rückgängig, wendet die Commits im Hauptzweig auf Ihren Testzweig an und wendet Ihre Commits dann wieder auf den Test an.
Zundi

Antworten:

2992

Wie würde ich das machen?

git checkout master
git pull origin master
git merge test
git push origin master

Wenn ich einen lokalen Zweig von einem entfernten Zweig habe, kann ich andere Zweige als diesen nicht mit dem entfernten zusammenführen. Außerdem würde ich meine Änderungen nicht pushen, bis ich mit dem, was ich pushen möchte, zufrieden bin und ich würde überhaupt keine Dinge pushen, die nur für mich und mein lokales Repository sind. In Ihrer Beschreibung scheint das testnur für Sie zu sein? Also kein Grund, es zu veröffentlichen.

git versucht immer, deine und andere Veränderungen zu respektieren, und das wird auch so sein --rebase. Ich glaube nicht, dass ich es angemessen erklären kann, also schauen Sie sich das Git-Buch an - Rebasing oder git-ready: Einführung in die Neugründung für eine kleine Beschreibung. Es ist eine ziemlich coole Funktion

KingCrunch
quelle
2
git merge testgibt mir fatal: 'test' does not point to a commit. Ich muss nach dem Festschreibungspunkt im git logTestzweig suchen , zurück zum Hauptzweig wechseln und dann tun git merge 0f37d3154abbf52a4cbbbb5109f08af6a7567234.
Duncanmoo
17
@ Duncanmoo Nun, natürlich testmuss der Zweig existieren. Natürlich können Sie stattdessen den Commit-Hash verwenden, aber normalerweise ist es einfacher, den Zweignamen zu verwenden. Intern wird nur der Hash des HEADZweigs abgerufen .
KingCrunch
44
@shanyangqu Um die neuesten Änderungen von der Fernbedienung zu erhalten. Wenn Sie alleine und nur mit einem System arbeiten, gibt es kein Problem. Wenn jedoch Änderungen von einem anderen System (wahrscheinlich von einem anderen Entwickler) übertragen werden, tritt ein Konflikt auf, sobald Sie versuchen, die Zusammenführung zurückzuschieben (4. Schritt). Die einzige Lösung besteht jetzt darin, Ihren lokalen Master mit dem Fernbedienungsmaster zusammenzuführen, was zu einem ziemlich hässlichen Zusammenführungs-Commit "Zusammengeführter Master in Ursprung / Master" führt. Es ist also immer eine gute Idee, vor dem Zusammenschluss einen Pull zu machen
KingCrunch
7
"In Ihrer Beschreibung scheint dieser Test nur für Sie zu sein? Also kein Grund, ihn zu veröffentlichen." Möglicherweise möchten Sie Ihren lokalen Zweig auf einen Server übertragen, wenn dieser Server beispielsweise eine Sicherung gegen einen Ausfall Ihres lokalen Laufwerks bereitstellt oder wenn Sie keine andere Möglichkeit haben, eine Sicherung durchzuführen.
Eric
5
"... Außerdem würde ich meine Änderungen nicht pushen, bis ich mit dem, was ich pushen möchte, zufrieden bin ..." Warum nicht pushen , um Ihren Code zu sichern, falls Ihre lokalen Computer ausfallen und tagelange Anstrengungen unternommen werden sind weg?
Rich Stone
400

Dies ist eine sehr praktische Frage, aber alle obigen Antworten sind nicht praktisch.

Mögen

git checkout master
git pull origin master
git merge test
git push origin master

Dieser Ansatz hat zwei Probleme :

  1. Es ist unsicher, da wir nicht wissen, ob es Konflikte zwischen Testzweig und Hauptzweig gibt.

  2. Es würde alle Test-Commits zu einem Merge-Commit für den Master "zusammenpressen". Das heißt, auf dem Hauptzweig können nicht alle Änderungsprotokolle des Testzweigs angezeigt werden.

Wenn wir also vermuten, dass es zu Konflikten kommen könnte, können wir folgende Git-Operationen durchführen:

git checkout test
git pull 
git checkout master
git pull
git merge --no-ff --no-commit test

Testen Sie mergevorher commit, vermeiden Sie ein schnelles Festschreiben durch --no-ff,

Wenn ein Konflikt auftritt, können wir git statusDetails zu den Konflikten überprüfen und versuchen, sie zu lösen

git status

Sobald wir die Konflikte gelöst haben oder wenn es keinen Konflikt gibt, sind wir commitund pushsie

git commit -m 'merge test branch'
git push

Auf diese Weise geht jedoch der im Testzweig protokollierte Änderungsverlauf verloren, und es würde für andere Entwickler schwierig sein, den Verlauf des Projekts zu verstehen.

Die beste Methode ist also, dass wir rebasestatt verwenden müssen merge(nehmen wir an, wenn wir in dieser Zeit die Verzweigungskonflikte gelöst haben).

Im Folgenden finden Sie ein einfaches Beispiel für erweiterte Vorgänge unter http://git-scm.com/book/en/v2/Git-Branching-Rebasing

git checkout master
git pull
git checkout test
git pull
git rebase -i master
git checkout master
git merge test

Ja, wenn Sie das Obermaterial fertig haben, werden alle Commits des Testzweigs auf den Kopf des Hauptzweigs verschoben. Der Hauptvorteil der Neubasierung besteht darin, dass Sie eine lineare und viel sauberere Projekthistorie erhalten.

Das einzige, was Sie vermeiden müssen, ist: Verwenden Sie es niemals rebasein öffentlichen Zweigen wie dem Hauptzweig.

Führen Sie niemals Operationen wie die folgenden aus:

git checkout master
git rebase -i test

Details zu https://www.atlassian.com/git/tutorials/merging-vs-rebasing/the-golden-rule-of-rebasing

Blinddarm:

John Yin
quelle
4
Ich bin damit einverstanden, dass der Testzweig für die spätere Zusammenführung mit dem Master neu basiert wird. Sogar die anderen Antworten sind richtig, dies wird die Geschichte der Änderungen des Verzweigungstests im Kopf des Masters behalten, da der Autor "Sie erhalten einen Liner und ein viel saubereres Projekt" erwähnt, was der Zweck des Versionskontrollsystems ist.
Le0diaz
16
Die Aussage "Es ist kein sicherer Weg, weil wir nicht wissen, ob es Konflikte zwischen Testzweig und Hauptzweig gibt" ist nicht wahr: Man kann die Zusammenführung immer abbrechen. Und selbst wenn es keine Konflikte gibt, können Sie das letzte lokale Commit immer rückgängig machen, solange es nicht gepusht wird. Ohne das richtige Verständnis von Git mögen einige Dinge etwas beängstigend oder unklar erscheinen, aber "unsicher" ist in keiner Weise falsch. Bitte achten Sie darauf, andere nicht mit falschen Informationen zu verwechseln.
Paul van Leeuwen
4
stimmen mit @PaulvanLeeuwen, wenn Sie fusionieren GIT den Testzweig in Master, werden Sie über Konflikte benachrichtigt, und das ist , wo Sie in Schritt werden und die Änderungen zusammenführen. Sobald Sie fertig sind, werden Sie die Zusammenführung festschreiben und zurückschieben. Wenn Sie es bereuen oder nicht richtig zusammenführen können, können Sie Ihre Arbeit jederzeit verwerfen und erneut vom Master abrufen. Es ist also definitiv nicht unsicher.
Juan
3
warum -i neu gründen?
MushyPeas
8
Das Wiederherstellen ist von Natur aus unsicherer als das Zusammenführen. Es ist falsch, eine Neuausrichtung als sicherere Option für das Zusammenführen vorzuschlagen. Rebasing ist eine gültige Strategie, bringt jedoch weitere Einschränkungen mit sich, auf die der Benutzer achten sollte.
Ikke
90

Weder eine Neueinstellung noch eine Zusammenführung sollten Änderungen überschreiben (es sei denn, Sie entscheiden sich bei der Lösung eines Konflikts dafür).

Der übliche Ansatz bei der Entwicklung ist

git checkout master
git pull
git checkout test
git log master.. # if you're curious
git merge origin/test # to update your local test from the fetch in the pull earlier

Wenn Sie bereit sind, wieder zum Master zu wechseln,

git checkout master
git log ..test # if you're curious
git merge test
git push

Wenn Sie sich Sorgen machen, etwas bei der Zusammenführung zu brechen, git merge --abortist es für Sie da.

Push und dann Pull als Mittel zum Zusammenführen zu verwenden, ist dumm. Ich bin mir auch nicht sicher, warum Sie den Test zum Ursprung bringen.

Raylu
quelle
1
Dieser Prozess erhöht die Anzahl der Festschreibungen. Jedes Mal, wenn Sie zwischen Zweigen wechseln, müssen Sie Ihren Zweig festschreiben.
iBug
2
Was? Wollen Sie damit sagen, dass sich die Anzahl der Commits bei jedem Zweigwechsel erhöht? Oder sagen Sie, dass Sie jedes Mal, wenn Sie die Filiale wechseln, "Ihre Filiale festschreiben" müssen? Das erste ist falsch und ich bin mir nicht sicher, was das zweite bedeutet.
Raylu
Vor dem Auschecken müssen Sie einen Zweig festschreiben. das ist was ich sage
iBug
11
Sie nicht: das ist (eines der Dinge) git stashist für.
Msanford
1
Oder Sie können Ihr letztes Commit (in der lokalen Niederlassung) ändern und es vor dem Pushing zum perfekten machen.
Whihathac
42

Ich würde zuerst den zu verschmelzenden Zweig so sauber wie möglich machen. Führen Sie Ihre Tests aus und stellen Sie sicher, dass der Status Ihren Wünschen entspricht. Bereinigen Sie die neuen Commits mit Git Squash .

Neben der Antwort von KingCrunches empfehle ich die Verwendung

git checkout master
git pull origin master
git merge --squash test
git commit
git push origin master

Möglicherweise haben Sie in der anderen Verzweigung viele Festschreibungen vorgenommen. Dies sollte nur eine Festschreibung in der Hauptverzweigung sein. Um den Commit-Verlauf so sauber wie möglich zu halten, möchten Sie möglicherweise alle Ihre Commits aus dem Testzweig in einem Commit im Master-Zweig zusammenfassen (siehe auch: Git: Squash oder nicht Squash? ). Dann können Sie die Commit-Nachricht auch in etwas sehr Ausdrucksstarkes umschreiben. Etwas, das leicht zu lesen und zu verstehen ist, ohne sich in den Code zu vertiefen.

edit: Das könnte dich interessieren

Auf GitHub mache ich am Ende Folgendes für einen Feature-Zweig mybranch:

Holen Sie sich das Neueste vom Ursprung

$ git checkout master
$ git pull origin master

Suchen Sie den Merge-Basis-Hash:

$ git merge-base mybranch master
c193ea5e11f5699ae1f58b5b7029d1097395196f

$ git checkout mybranch
$ git rebase -i c193ea5e11f5699ae1f58b5b7029d1097395196f

Stellen Sie jetzt sicher, dass nur der erste ist pick, der Rest ist s:

pick 00f1e76 Add first draft of the Pflichtenheft
s d1c84b6 Update to two class problem
s 7486cd8 Explain steps better

Als nächstes wählen Sie eine sehr gute Commit-Nachricht und drücken Sie auf GitHub. Stellen Sie dann die Pull-Anfrage.

Nach dem Zusammenführen der Pull-Anforderung können Sie sie lokal löschen:

$ git branch -d mybranch

und auf GitHub

$ git push origin :mybranch
Martin Thoma
quelle
"Das sollte nur ein Commit in der Hauptniederlassung sein ", also nicht unbedingt; Sie können wekk wollen die Geschichte behalten
Cocowalla
Sicher. Aber dann quetschen Sie einfach nicht die Commits
Martin Thoma
Ich denke - First-Parent scheint die beste Lösung zu sein. davidchudzicki.com/posts/first-parent
bkribbs
7

Alter Thread, aber ich habe meinen Weg nicht gefunden . Dies kann für jemanden von Nutzen sein, der mit Rebase arbeitet und alle Commits aus einem (Feature-) Zweig über Master zusammenführen möchte. Wenn unterwegs ein Konflikt vorliegt, können Sie diesen für jedes Commit lösen. Sie behalten während des Vorgangs die volle Kontrolle und können jederzeit abbrechen.

Holen Sie sich Master und Branch auf den neuesten Stand:

git checkout master
git pull --rebase origin master
git checkout <branch_name>
git pull --rebase origin <branch_name>

Zweig über Master zusammenführen:

git checkout <branch_name>
git rebase master

Optional: Wenn Sie während der Rebase auf Konflikte stoßen:

Lösen Sie zunächst den Konflikt in der Datei. Dann:

git add .
git rebase --continue

Schieben Sie Ihren neu basierten Zweig:

git push origin <branch_name>

Jetzt haben Sie zwei Möglichkeiten:

  • A) Erstellen Sie einen PR (zB auf GitHub) und führen Sie ihn dort über die Benutzeroberfläche zusammen
  • B) Gehen Sie zurück in die Befehlszeile und führen Sie den Zweig zum Master zusammen
git checkout master
git merge --no-ff <branch_name>
git push origin master

Erledigt.

Robin Wieruch
quelle
6

Dies ist der Workflow, den ich bei meiner Arbeit mit dem Team verwende. Das Szenario ist wie von Ihnen beschrieben. Erstens, wenn ich mit der Arbeit fertig testbin, stelle ich die Basis mit dem Master wieder her, um alles einzuziehen, was während der Zeit, in der ich an der testVerzweigung gearbeitet habe, dem Master hinzugefügt wurde .

git pull -r upstream master

Dadurch werden die Änderungen an Master übertragen, seit Sie die gegabelt haben test Zweig und angewendet haben. Anschließend werden die Änderungen angewendet, die Sie vorgenommen haben, um "über" den aktuellen Status des Masters zu testen. Hier kann es zu Konflikten kommen, wenn die anderen Personen Änderungen an denselben Dateien vorgenommen haben, die Sie im Test bearbeitet haben. Wenn dies der Fall ist, müssen Sie diese manuell beheben und festschreiben. Sobald Sie dies getan haben, können Sie problemlos zum Hauptzweig wechseln und testproblemlos zusammenführen.

djheru
quelle
3
git checkout master
git pull origin master
# Merge branch test into master
git merge test

Wenn die Datei nach dem Zusammenführen geändert wird, wird beim Zusammenführen der Fehler "Konflikt lösen" angezeigt.

Dann müssen Sie zuerst alle Ihre Konflikte lösen, dann müssen Sie erneut alle Ihre Änderungen festschreiben und dann pushen

git push origin master

Dies ist besser, wenn Sie Änderungen im Testzweig vorgenommen haben, da er wusste, welche Änderungen er vorgenommen hat.

Vinay Sikarwar
quelle
3

Ich würde die Rebase-Methode verwenden. Meistens, weil es Ihren Fall semantisch perfekt widerspiegelt, dh. Was Sie tun möchten, ist, den Status Ihres aktuellen Zweigs zu aktualisieren und so zu tun, als ob er auf dem neuesten basiert.

Also, ohne auch nur auszuchecken master, würde ich:

git fetch origin
git rebase -i origin/master
# ...solve possible conflicts here

Nur das Abrufen vom Ursprung aktualisiert natürlich nicht Ihren lokalen Status master(da keine Zusammenführung durchgeführt wird), aber es ist für unseren Zweck vollkommen in Ordnung - wir möchten das Umschalten vermeiden, um Zeit zu sparen.

user776686
quelle
2

Die Antwort von @ KingCrunch sollte in vielen Fällen funktionieren. Ein Problem, das auftreten kann, ist, dass Sie sich möglicherweise auf einem anderen Computer befinden, der das Neueste aus dem Test ziehen muss. Daher empfehle ich, zuerst den Test zu ziehen. Die Revision sieht folgendermaßen aus:

git checkout test
git pull
git checkout master
git pull origin master
git merge test
git push origin master
cgnorthcutt
quelle
0

Sie müssen den Zweig zum Ziehen auschecken lassen, da das Ziehen das Zusammenführen mit dem Master bedeutet und Sie einen Arbeitsbaum zum Zusammenführen benötigen.

git checkout master
git pull

Keine Notwendigkeit, zuerst auszuchecken; rebase macht mit zwei Argumenten das Richtige

git rebase master test  

git checkout master
git merge test

git push schiebt standardmäßig alle Zweige, die hier und auf der Fernbedienung vorhanden sind

git push
git checkout test
Masoud Mokhtari
quelle
0

Da der Titel "Best way" lautet, halte ich es für eine gute Idee, die Strategie der Geduldzusammenführung in Betracht zu ziehen .

Von: https://git-scm.com/docs/merge-strategies

Mit dieser Option verbringt 'Merge-Recursive' etwas mehr Zeit, um Fehlzusammenschlüsse zu vermeiden, die manchmal aufgrund unwichtiger übereinstimmender Linien auftreten (z. B. geschweifte Klammern aus unterschiedlichen Funktionen). Verwenden Sie diese Option, wenn die zusammenzuführenden Zweige stark voneinander abweichen. Siehe auch git-diff [1] --patience.

Verwendungszweck:

git fetch
git merge -s recursive -X patience origin/master

Git Alias

Ich benutze dafür immer einen Alias, zB einmal ausführen:

 git config --global alias.pmerge 'merge -s recursive -X patience'

Jetzt könnten Sie tun:

git fetch
git pmerge origin/master
julianisch
quelle
0

Dies ist von GitLab: Folgen Sie einfach den Anweisungen:

Geben Sie hier die Bildbeschreibung ein

shdr
quelle
0

Ich werde gemäß Entwicklungs- und Feature-Zweigen antworten.

Wenn Sie sich im Feature-Zweig befinden und ihn mit Develop aktualisieren müssen, verwenden Sie die folgenden Befehle: Git Checkout Develop Git Pull Git Checkout Feature / XYZ Git Merge Develop

Jetzt wird Ihre Funktion mit der Entwicklung aktualisiert. Sie können Ihre Änderungen übernehmen.

Omkar
quelle