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 topic
Zweig git checkout -b topic origin/master
wurde der Verlauf des Fernverfolgungszweigs origin/master
mö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/master
früher auf Commits gezeigt B3
wurde B2
, B1
und jetzt zeigt es auf B
, und Ihr topic
Zweig wurde darüber gestartet, als es noch origin/master
war B3
.
In diesem Modus wird das Reflog von origin/master
to B3
als 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-base
Befehl 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 --rebase
Befehl " " berechnet den Gabelpunkt des Zweigs, der neu basiert, unter Verwendung der Reflog-Einträge des base
Zweigs "(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 B3
und dann B2
und 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 , B3
indem 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 Derived
und 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 C
und D
jeweils und Konflikt textuell , wenn in der falschen Reihenfolge angewandt wird ;
E
hängt textlich ab von D
.
Das korrekte Ergebnis git rebase master dev
ist , dass B
wie die gabelPunkt identifiziert wird dev
und master
, so dass C
, D
, E
sind die Festschreibungen , dass Bedarf an wiedergegeben werden master
; aber C
und D
sind 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 B
eines Zweigs, der enthält, B'
zu einem Konflikt. Wenn die patchidentischen Commits nicht korrekt identifiziert werden, führt die Auswahl C
eines 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-point
Regressionsfix
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.