Warum verschmelze ich "Remote-Tracking-Zweig" Ursprung / Entwicklung "mit" Entwicklung "?

125

Ich bin der einzige in meiner Organisation, der sich mit der folgenden Nachricht verpflichtet:

Führen Sie den Remote-Tracking-Zweig "Ursprung / Entwicklung" zu "Entwickeln" zusammen

Ich bin mir nicht sicher, was ich tue, um sie zu verursachen, aber ich würde gerne aufhören.

Welchen Befehl gebe ich aus, um dieses Commit zu erstellen, und welchen Befehl sollte ich verwenden, um es nicht zu erzeugen?

Jordan Feldstein
quelle
1
Die Antwort von Richard Hansen ist in Ordnung. Aber ich denke, es könnte für Anfänger verwirrend sein. Meine Lösung besteht darin, weiterhin Pull-Rebase zu verwenden, aber um die Gefahr zu vermeiden, verwahre ich meine Änderungen vor dem Pull. Dann, nach dem Ziehen, wende ich es an. Ich löse Konflikte. Endlich kann ich mich verpflichten & pushen.
Johnjohn
Funktioniert git pull --autostash --rebasefür Sie @Johnjohn?
Sourcedelica

Antworten:

206

git pullerstellt wahrscheinlich das Commit. Wenn Sie ein lokales Commit durchführen und dann ausführen, git pullnachdem jemand anderes ein Commit in das Repository verschoben hat, lädt Git das Commit des anderen Entwicklers herunter und führt es dann in Ihrem lokalen Zweig zusammen.

So vermeiden Sie diese Zusammenführungsverpflichtungen in Zukunft

Sie könnten git pull --rebasedies verhindern, um dies in Zukunft zu verhindern, aber das erneute Basieren birgt seine Gefahren, und ich empfehle, es pullinsgesamt zu vermeiden .

Stattdessen ermutige ich Sie, diesem Verwendungsmuster zu folgen:

# download the latest commits
git remote update -p

# update the local branch
git merge --ff-only @{u}

# if the above fails with a complaint that the local branch has
# diverged:
git rebase -p @{u}

Erläuterung

  • git remote update -pLädt alle Commits in die Remote-Repositorys herunter und aktualisiert die Remote-Tracking-Zweige (z origin/master. B. ). Es berührt NICHT Ihr Arbeitsverzeichnis, Ihren Index oder Ihre lokalen Zweige.

    Das -pArgument Pflaumen löschte vorgelagerte Zweige. Wenn der fooZweig im originRepository gelöscht git remote update -pwird , wird Ihre origin/fooReferenz automatisch gelöscht .

  • git merge --ff-only @{u}weist Git an, den Upstream-Zweig (das @{u}Argument) in Ihrem lokalen Zweig zusammenzuführen, jedoch nur, wenn Ihr lokaler Zweig schnell zum Upstream-Zweig weitergeleitet werden kann (mit anderen Worten, wenn er nicht auseinander gegangen ist).

  • git rebase -p @{u}Verschiebt effektiv die Commits, die Sie gemacht haben, aber noch nicht auf den Upstream-Zweig verschoben haben, wodurch die Notwendigkeit entfällt, die albernen Merge-Commits zu erstellen, die Sie vermeiden möchten. Dies verbessert die Linearität des Entwicklungsverlaufs und erleichtert die Überprüfung.

    Die -pOption weist Git an, Zusammenführungen beizubehalten. Dies verhindert, dass Git die neu basierten Commits linearisiert. Dies ist wichtig, wenn Sie beispielsweise einen Feature-Zweig in zusammengeführt haben master. Ohne würde -pjedes Commit für den Feature-Zweig masterim Rahmen der Linearisierung von dupliziert git rebase. Dies würde die Überprüfung der Entwicklungshistorie erschweren und nicht einfacher machen.

    Achtung : git rebaseMöglicherweise tun Sie nicht das, was Sie erwarten. Überprüfen Sie daher die Ergebnisse, bevor Sie Druck ausüben. Beispielsweise:

    git log --graph --oneline --decorate --date-order --color --boundary @{u}..
    

Ich bevorzuge diesen Ansatz git pull --rebaseaus folgenden Gründen:

  • Sie können die eingehenden Upstream-Commits anzeigen, bevor Sie Ihren Verlauf ändern, um sie einzubeziehen.
  • Sie können die Option -p( --preserve-merges) an übergeben, git rebasefalls Sie eine absichtliche Zusammenführung erneut durchführen müssen (z. B. die Zusammenführung eines bereits übertragenen Feature-Zweigs in master).

Kurzform: git upstattgit pull

Um dies zu vereinfachen, empfehle ich, einen Alias ​​mit dem Namen up:

git config --global alias.up '!git remote update -p; git merge --ff-only @{u}'

Jetzt müssen Sie nur noch Folgendes ausführen, um Ihre Niederlassung auf den neuesten Stand zu bringen:

git up

statt git pull. Wenn Sie eine Fehlermeldung erhalten, weil Ihr lokaler Zweig vom vorgelagerten Zweig abgewichen ist, ist dies Ihr Stichwort für eine Neubasis.

Warum nicht git pull --rebase?

Laufen git pull --rebaseist gleichbedeutend mit Laufen git fetchgefolgt von Laufen git rebase. Dadurch wird versucht, einen schnellen Vorlauf zu den neuen Upstream-Commits durchzuführen. Wenn dies jedoch nicht möglich ist, werden Ihre lokalen Commits auf die neuen Upstream-Commits zurückgesetzt. Dies ist normalerweise in Ordnung, aber seien Sie vorsichtig:

  • Rebase ist ein fortgeschrittenes Thema, und Sie sollten die Auswirkungen verstehen, bevor Sie Rebase verwenden.
  • git pull --rebasegibt Ihnen keine Gelegenheit, die Commits zu prüfen, bevor Sie sie einbeziehen. Je nachdem , was geändert stromaufwärts, dann ist es durchaus möglich , dass Fütterungsmaterial ist die falsche Operation-a rebase --onto, merge, reset, oder push -fkönnte als eine einfache besser geeignet sein rebase.
  • Es ist (derzeit) nicht möglich, --preserve-mergesan die Rebase-Operation zu übergeben, daher wird jede absichtliche Zusammenführung eines Feature-Zweigs linearisiert, wodurch alle Commits des Feature-Zweigs wiedergegeben (und somit dupliziert) werden.

"Fixieren" eines vorhandenen Zusammenführungs-Commits, das von erstellt wurde git pull

Wenn Sie ein von erstelltes Zusammenführungs-Commit noch nicht gepusht haben git pull, können Sie das Zusammenführungs-Commit neu festlegen. Angenommen, Sie haben keine absichtlichen Zusammenführungen vorgenommen (z. B. Zusammenführen eines bereits übertragenen Feature-Zweigs mit Ihrem aktuellen Zweig), sollte dies wie folgt geschehen:

git rebase @{u}

Die obige Befehl teilt Git alle Nicht-merge auszuwählen begeht erreichbar von HEAD(der aktuelle commit), minus alle die Festschreibungen erreichbar von @{u}(was eine Abkürzung für „stromaufwärtigen Zweig“ ist, das heißt, origin/masterwenn HEADist master), Wiedergabe (Kirsche-pick ) sie über dem Upstream-Zweig und verschieben dann die aktuelle Zweigreferenz, um auf das Ergebnis der Wiedergabe der Commits zu verweisen. Dadurch werden die Nicht-Merge-Commits effektiv auf das letzte Upstream-Commit verschoben, wodurch die durch verursachte Zusammenführung entfällt git pull.

Wenn Sie ein absichtliches Zusammenführungs-Commit haben, möchten Sie es nicht ausführen, git rebase @{u}da es alles aus dem anderen Zweig wiedergibt. Der Umgang mit diesem Fall ist wesentlich komplizierter, weshalb es gut ist, ihn zu verwenden git upund git pullinsgesamt zu vermeiden . Sie müssen wahrscheinlich verwenden reset, um die von pullund erstellte Zusammenführung rückgängig zu machen git rebase -p @{u}. Das -pArgument git rebase, dass es für mich nicht zuverlässig funktioniert hat, muss möglicherweise verwendet werden reset, um die absichtliche Zusammenführung rückgängig zu machen, Ihren lokalen Zweig auf zu aktualisieren @{u}und dann die absichtliche Zusammenführung zu wiederholen (was bei vielen haarigen Zusammenführungen schmerzhaft ist Konflikte).

Richard Hansen
quelle
+1 für die Erörterung von --preserve-merges, außer dass Sie dies in den Befehlen, die Sie ihm gesagt haben, nicht ausgeführt haben, also -1 dafür.
Seth Robertson
@ Seth: Danke für den Kommentar; Ich habe die Antwort aktualisiert, um sie zu empfehlen -p. Ich habe es vorher vermieden, es zu empfehlen, weil es nicht sehr oft benötigt wird und sein Verhalten nicht gut dokumentiert ist.
Richard Hansen
3
Was ist der Unterschied zwischen git remote update -pund git fetch?
eckes
3
@eckes: git remote update -pist das gleiche wie git fetch --all -p. Ich habe mir angewöhnt, git remote update -pzurück zu verwenden, wenn fetchich keine -pOption hatte.
Richard Hansen
1
@ user1914692: Sobald die Zusammenführung abgeschlossen ist, aktualisiert Git den lokalen Zweig so, dass er auf das neu erstellte Zusammenführungs-Commit verweist, nicht auf dasselbe Commit wie der Remote-Zweig. Dieses neue Zusammenführungs-Commit ist das Problem, insbesondere wenn es gepusht wird.
Richard Hansen
18
git fetch
git rebase origin/master

Das sollte es tun. Oder wenn Sie weiterhin Pull verwenden möchten

git pull --rebase

Sie können diesen Zweig auch in Ihrer Konfiguration so einrichten, dass er automatisch neu basiert, oder für alle anderen zukünftigen Tracking-Zweige, die Sie erstellen, automatisch so eingerichtet werden. Dann können Sie wieder nur mit verwenden

git pull

Mehr dazu im Abschnitt "Mit Rebase ziehen statt zusammenführen" auf dieser Seite:

http://mislav.uniqpath.com/2010/07/git-tips/

Adam Dymitruk
quelle