1360 Stimmen

Master-Zweig und 'origin/master' sind auseinandergelaufen, wie kann man die Zweige wieder auseinanderlaufen lassen?

Irgendwie ist mein master und mein origin/master Zweig haben sich auseinanderentwickelt.
Ich möchte eigentlich nicht, dass sie sich auseinanderentwickeln.

Wie kann ich diese Unterschiede sehen und zusammenführen sie?

4 Stimmen

Was meinen Sie mit abweichend? Stellen Sie Ihren Master neu ein? nach Sie schieben es?

51 Stimmen

Ich erhalte die Meldung "Your branch and 'origin/master' have diverged, # and have 1 and 1 different commit(s) each, respectively".

0 Stimmen

Ich habe meine Antwort aktualisiert, um diese "abweichende" Warnmeldung zu berücksichtigen.

1332voto

VonC Punkte 1117238

Sie können Überprüfung der Unterschiede mit einem:

git log HEAD..origin/master

vor Ziehen (fetch + merge) (siehe auch "Wie bringt man Git dazu, immer von einem bestimmten Zweig zu ziehen?" )


Wenn Sie eine Nachricht wie diese erhalten:

"Ihr Zweig und 'origin/master' sind auseinandergeklafft, # und haben jeweils 1 bzw. 1 verschiedene Commit(s)."

prüfen Sie, ob Sie muss aktualisiert werden origin . Wenn origin auf dem neuesten Stand ist, dann wurden einige Commits nach origin aus einem anderen Repo, während Sie Ihre eigenen Commits lokal vorgenommen haben.

... o ---- o ---- A ---- B  origin/master (upstream work)
                   \
                    C  master (your work)

Sie haben Commit C auf Commit A aufgebaut, weil das die letzte Arbeit war, die Sie zu diesem Zeitpunkt von Upstream geholt hatten.

Bevor Sie jedoch versucht haben, zum Ursprung zurückzukehren, hat jemand anderes die Übergabe an B veranlasst.
Die Entwicklungsgeschichte hat sich in verschiedene Richtungen entwickelt.

Sie können dann zusammenführen oder neu basieren. Siehe Pro Git: Git-Verzweigung - Rebasing für Einzelheiten.

Zusammenführen

Verwenden Sie den Befehl git merge:

$ git merge origin/master

Dies weist Git an, die Änderungen aus origin/master in Ihre Arbeit ein und erstellen Sie eine Zusammenführungsübergabe.
Das Diagramm der Geschichte sieht nun wie folgt aus:

... o ---- o ---- A ---- B  origin/master (upstream work)
                   \      \
                    C ---- M  master (your work)

Die neue Zusammenführung, Commit M, hat zwei Elternteile, die jeweils einen Entwicklungspfad repräsentieren, der zu dem in diesem Commit gespeicherten Inhalt geführt hat.

Beachten Sie, dass die Geschichte hinter M nun nicht mehr linear ist.

Rebase

Verwenden Sie den Befehl git rebase:

$ git rebase origin/master

Dies weist Git an, Commit C (Ihre Arbeit) so wiederzugeben, als ob Sie es auf Commit B statt auf A aufgebaut hätten.
CVS- und Subversion-Benutzer legen routinemäßig ihre lokalen Änderungen auf die Upstream-Arbeiten um, wenn sie vor der Übergabe aktualisieren.
Git trennt lediglich explizit zwischen den Schritten Commit und Rebase.

Das Diagramm der Geschichte sieht nun wie folgt aus:

... o ---- o ---- A ---- B  origin/master (upstream work)
                          \
                           C'  master (your work)

Commit C' ist ein neuer Commit, der mit dem Befehl git rebase erstellt wurde.
Es unterscheidet sich von C in zweierlei Hinsicht:

  1. Sie hat eine andere Geschichte: B anstelle von A.
  2. Sein Inhalt berücksichtigt die Änderungen in B und C; er ist derselbe wie M aus dem Zusammenführungsbeispiel.

Beachten Sie, dass die Geschichte hinter C' immer noch linear ist.
Wir haben uns (vorerst) dafür entschieden, nur eine lineare Geschichte in cmake.org/cmake.git .
Dieser Ansatz bewahrt den bisher verwendeten CVS-basierten Arbeitsablauf und kann den Übergang erleichtern.
Ein Versuch, C' in unser Repository zu pushen, wird funktionieren (vorausgesetzt, Sie haben die entsprechenden Rechte und niemand hat gepusht, während Sie rebasiert haben).

Der git pull-Befehl bietet eine Kurzformel, mit der man sich vom Ursprung holen und die lokale Arbeit darauf neu basieren kann:

$ git pull --rebase

Damit werden die oben genannten Schritte "fetch" und "rebase" in einem einzigen Befehl zusammengefasst.

7 Stimmen

Ich fand dies bei der Suche nach dem gleichen Problem, können Sie erklären, warum "git reset --hard HEAD" das Problem nicht behoben hat?

22 Stimmen

@Neth: weil es sich nicht um abgestufte Änderungen handelt (d.h. Änderungen, die im Index vorhanden sind, aber noch nicht übertragen wurden), sondern um lokale Zusagen (die sich von den Commits auf der Remote unterscheidet). git reset --hard HEAD würde nur alle lokalen indizierten nicht bestätigten Änderungen entfernen und nichts tun, um die Unterschiede zwischen lokalen und entfernten Änderungen auszugleichen. verpflichtet sich . Nur ein Merge oder ein Rebase bringt die beiden Commits (den lokalen und den entfernten) zusammen.

4 Stimmen

Wow, danke für diese großartige Antwort. Wir hatten versehentlich einen "git pull" ohne "--rebase" durchgeführt, und "git rebase origin/master" war genau die richtige Lösung!

1188voto

skiphoppy Punkte 89474

Ich hatte dieses Problem und bin ratlos, was es verursacht hat, auch nachdem ich die obigen Antworten gelesen habe. Meine Lösung war zu tun

git reset --hard origin/master

Das setzt dann einfach meine (lokale) Kopie von master (von der ich annehme, dass sie verkorkst ist) auf den korrekten Punkt zurück, der durch (remote) origin/master repräsentiert wird.

WARNUNG : Sie verlieren alle Änderungen, die noch nicht an origin/master .

46 Stimmen

Ja, es fühlt sich ein bisschen wie die Dummy-Option an, aber wenn es keine wirkliche Gefahr gibt und Sie hier für eine schnelle Lösung sind - das funktioniert (für mich jedenfalls)

13 Stimmen

Dies setzt voraus, dass Sie sich zuvor auf dem Master-Zweig befinden ("git checkout master").

0 Stimmen

Hallo skiphoppy, danke für den Tipp. Ich stimme PandaWood zu (nicht böse gemeint), dass es ein bisschen wie ein Dummy Option scheint. Aber wenn ich das sage, bin ich nicht so erfahren mit den fortgeschrittenen Aspekten von Git.

71voto

asitmoharna Punkte 1366
git pull --rebase origin/master 

ist ein einziger Befehl, der Ihnen die meiste Zeit helfen kann.

Bearbeiten: Zieht die Commits vom Origin/Master und wendet Ihre Änderungen auf den neu gezogenen Zweigverlauf an.

123 Stimmen

Bitte geben Sie an, was der Befehl bewirkt, sonst könnten die Leute ihn ausführen und am Ende alles vermasseln

3 Stimmen

Wenn es keine Probleme gibt, sollten Sie am Ende Ihren Master haben, der alle Änderungen von origin/master enthält, und alle Ihre lokalen Übertragungen werden auf ihn übertragen. Scheint mir gut zu sein.

8 Stimmen

Es sei denn, es gibt wirkliche Unterschiede und man muss die Umstrukturierung abbrechen.

54voto

Rishi Kulshreshtha Punkte 1283

Ich glaube, das hätte mir helfen sollen:

git reset --hard origin/master

Aber das tat es nicht, irgendwie bekam ich die gleiche Meldung & sobald ich die Änderungen aus dem entfernten Zweig zog, traten die Konflikte auf. Da ich mir sicher war, dass ich meinen bestehenden lokalen Zweig überhaupt nicht benötige und nur eine exakte Kopie der master Verzweigung aus der Ferne, daher habe ich mir diese Lösung einfallen lassen:

  • Auschecken in einen neuen Zweig, zum Beispiel git checkout -b placeholder-branch . Hinweis: Dieser Zweig kann später gelöscht werden.
  • git branch -D master Ich habe dies getan, weil ich sicher war, dass mein lokaler Zweig kaputt ist und ich dies eigentlich nicht brauche, ich brauche nur eine frische Kopie von der entfernten Instanz.
  • git checkout --track origin/master & Sie sind fertig, jetzt können Sie die placeholder-branch mit git branch -D

41voto

paneer_tikka Punkte 5853

Ich befand mich in dieser Situation, als ich versuchte neu gründen einen Zweig, der einen entfernten Zweig verfolgte, und ich versuchte, ihn auf Master umzubasieren. Wenn Sie in diesem Szenario versuchen, ein Rebase durchzuführen, werden Sie höchstwahrscheinlich feststellen, dass Ihr Zweig divergiert und das kann zu einem Chaos führen, das nichts für Git-Nomaden ist!

Angenommen, Sie befinden sich auf dem Zweig my_remote_tracking_branch, der von master abgezweigt wurde

$ git status

# Auf dem Zweig my_remote_tracking_branch

nichts zu übertragen (Arbeitsverzeichnis sauber)

Und jetzt versuchen Sie, von master as zu rebasen:

git rebase master

STOPPEN Sie JETZT und ersparen Sie sich Ärger! Verwenden Sie stattdessen merge as:

git merge master

Ja, Sie werden zusätzliche Commits in Ihrem Zweig haben. Aber wenn Sie keine Lust auf "un-divergierende" Zweige haben, ist dies ein viel reibungsloserer Arbeitsablauf als ein Rebasing. Siehe dieser Blog für eine viel ausführlichere Erklärung.

Ist Ihre Zweigstelle hingegen nur eine . Zweig (d.h. noch nicht in einen Remote-Zweig verschoben), sollten Sie auf jeden Fall einen Rebase durchführen (und Ihr Zweig wird nicht divergieren in diesem Fall).

Wenn Sie dies jetzt lesen, weil Sie bereits sont in einem "divergenten" Szenario aufgrund eines solchen Rebase, können Sie zum letzten Commit vom Ursprung zurückkehren (d.h. in einen nicht divergenten Zustand), indem Sie

git reset --hard origin/my_remote_tracking_branch

6 Stimmen

Als Faustregel gilt die Verwendung von rebase wenn der Zweig, den Sie umbasieren, noch nicht veröffentlicht (und von anderen Personen verwendet) wurde. Andernfalls, verwenden Sie merge . Wenn Sie bereits veröffentlichte (und benutzte) Zweige rebasieren, müssen Sie eine Verschwörung koordinieren, um die Geschichte aller Entwickler, die Ihren Zweig benutzt haben, neu zu schreiben.

1 Stimmen

Leider habe ich diese Nachricht nicht gelesen, bevor ich die git rebase master ...

0 Stimmen

Wenn ich git rebase master während auf Zweig 'foobar' dann technisch foobar ist diverged von Ursprung/foobar, bis ich ein git push -f tun, richtig?

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