Beginnend mit git 1.9 / 2.0 Q1 2014 müssen Sie nicht Ihre vorherigen Zweig Ursprung markieren , bevor sie auf dem neu geschrieben Upstream - Zweig Rebasing, wie sie in der Aristoteles Pagaltzis ‚s Antwort :
Siehe begehen 07d406b und begehen d96855f :
Nach der Arbeit an dem mit erstellten topicZweig git checkout -b topic origin/masterwurde der Verlauf des Fernverfolgungszweigs origin/mastermöglicherweise zurückgespult und neu erstellt, was zu einem Verlauf dieser Form führte:
o---B1
/
---o---o---B2--o---o---o---B (origin/master)
\
B3
\
Derived (topic)
wo origin/masterfrüher auf Commits gezeigt B3wurde B2, B1und jetzt zeigt es auf B, und Ihr topicZweig wurde darüber gestartet, als es noch origin/masterwar B3.
In diesem Modus wird das Reflog von origin/masterto B3als Gabelpunkt verwendet, sodass das topicüber dem aktualisierten Wert neu basiert werden kannorigin/master durch:
$ fork_point=$(git merge-base --fork-point origin/master topic)
$ git rebase --onto origin/master $fork_point topic
Deshalb hat der git merge-baseBefehl eine neue Option:
--fork-point::
Suchen Sie den Punkt, an dem sich ein Zweig (oder ein Verlauf, zu dem er führt <commit>) von einem anderen Zweig (oder einer Referenz) gegabelt hat <ref>.
Dies sucht nicht nur nach dem gemeinsamen Vorfahren der beiden Commits, sondern berücksichtigt auch das Reflog von, um <ref>zu sehen, ob die Geschichte, die dazu geführt <commit>hat, aus einer früheren Inkarnation des Zweigs hervorgegangen ist<ref> .
Der git pull --rebaseBefehl " " berechnet den Gabelpunkt des Zweigs, der neu basiert, unter Verwendung der Reflog-Einträge des baseZweigs "(normalerweise ein Zweig mit Fernverfolgung ), auf dem die Arbeit des Zweigs basiert, um den Fall zu bewältigen, in dem die" Basis " Zweig wurde zurückgespult und wieder aufgebaut.
Zum Beispiel, wenn die Geschichte wie folgt aussah:
- Die aktuelle Spitze des "
base" -Zweigs befindet sich bei B, aber beim früheren Abrufen wurde festgestellt, dass die Spitze früher war B3und dann B2und dann, B1
bevor zum aktuellen Commit gelangt wurde, und
- Der Zweig, der auf der neuesten "Basis" neu basiert, basiert auf Commit
B3.
es versucht , zu finden , B3indem Sie durch die Ausgabe von „ git rev-list --reflog base“ (dh B, B1, B2, B3) , bis sie eine Festschreibung feststellt , dass ein Vorfahre der aktuellen Spitze ist „ Derived (topic)“.
Intern haben wir das get_merge_bases_many(), was dies mit einem Schlag berechnen kann.
Wir möchten eine Zusammenführungsbasis zwischen Derivedund ein fiktives Zusammenführungs-Commit, das sich aus der Zusammenführung aller historischen Tipps von " base (origin/master)" ergibt .
Wenn ein solches Commit vorhanden ist, sollten wir ein einzelnes Ergebnis erhalten, das genau mit einem der Reflog-Einträge von " base" übereinstimmt .
Git 2.1 (Q3 2014) wird diese Funktion noch robuster machen: siehe Commit 1e0dacd von John Keeping ( johnkeeping)
Behandeln Sie das Szenario mit der folgenden Topologie korrekt:
C --- D --- E <- dev
/
B <- master@{1}
/
o --- B' --- C* --- D* <- master
wo:
B'ist eine feste Version davon B, die nicht mit dem Patch identisch ist B;
C*und D*sind pflaster identisch Cund Djeweils und Konflikt textuell , wenn in der falschen Reihenfolge angewandt wird ;
Ehängt textlich ab von D.
Das korrekte Ergebnis git rebase master devist , dass Bwie die gabelPunkt identifiziert wird devund master, so dass C, D, Esind die Festschreibungen , dass Bedarf an wiedergegeben werden master; aber Cund Dsind patch-identisch mit C*und D*und können so gelöscht werden, so dass das Endergebnis ist:
o --- B' --- C* --- D* --- E <- dev
Wenn der Gabelpunkt nicht identifiziert wird, führt die Auswahl Beines Zweigs, der enthält, B'zu einem Konflikt. Wenn die patchidentischen Commits nicht korrekt identifiziert werden, führt die Auswahl Ceines Zweigs, der D(oder gleichwertig D*) enthält, zu einem Konflikt.
Der " --fork-point" Modus von " git rebase" ging zurück, als der Befehl in der Ära 2.20 in C neu geschrieben wurde, was mit Git 2.27 (Q2 2020) korrigiert wurde.
Siehe Commit f08132f (09. Dezember 2019) von Junio C Hamano ( gitster) .
(Zusammengeführt von Junio C Hamano - gitster- in Commit fb4175b , 27. März 2020)
rebase: --fork-pointRegressionsfix
Abgemeldet von: Alex Torok [jc: Überarbeitete das Update und verwendete Alex 'Tests] Abgemeldet
von: Junio C Hamano
" git rebase --fork-point master" funktionierte früher in Ordnung, wie es intern " git merge-base --fork-point" genannt wurde. Das wusste, wie man mit einem kurzen Referenznamen umgeht und ihn auf den vollständigen Referenznamen dwim, bevor die zugrunde liegende get_fork_point()Funktion aufgerufen wird .
Dies gilt nicht mehr, nachdem der Befehl in C neu geschrieben wurde, da sein interner Aufruf, der direkt an get_fork_point()gesendet wird, keine kurze Referenz enthält.
Verschieben Sie das Argument "dwim the refname" in die vollständige "refname" -Logik, die in "git merge-base" verwendet wird, in die zugrunde liegende get_fork_point()Funktion, sodass sich der andere Aufrufer der Funktion bei der Implementierung von "git rebase" auf die gleiche Weise verhält diese Regression.