Pomińmy --ontona chwilę. upstreami branchsą dość proste, a właściwie trochę naśladują checkouti branch- drugi argument jest opcjonalny:
git branch <newbranch>
git branch <newbranch> <base>
git checkout -b <newbranch>
git checkout -b <newbranch> <base>
git rebase <upstream>
git rebase <upstream> <branch>
(Bok, nazwy tych argumentów rebase„upstream” i „branży” nie są bardzo opisywać zawartość IMO ja zwykle myśleć o nich jak peachoftree,. <start>I <end>, co jest, jak będę je za pomocą: git rebase <start> <end>)
Po pominięciu drugiej gałęzi wynik jest prawie taki sam, jak najpierw sprawdzenie tej gałęzi, a następnie wykonanie jej tak, jakby nie określono tej gałęzi. Wyjątkiem jest to, branchże nie zmienia twojej aktualnej gałęzi:
git checkout <base> && git branch <newbranch> && git checkout <previous_branch>
git checkout <base> && git checkout -b <newbranch>
git checkout <end> && git rebase <start>
Jeśli chodzi o zrozumienie, co rebaserobi po wywołaniu, zacząłem od myślenia o tym jako o specjalnym typie scalania. To nie jest tak naprawdę, ale pomogło, gdy po raz pierwszy zaczął rozumieć bazę. Aby pożyczyć przykład peachoftree:
A--B--F--G master
\
C--D--E feature
A git merge masterwyniki w tym:
A--B--F-----G master
\ \
C--D--E--H feature
Podczas gdy git rebase master(podczas gdy na gałęzi feature!) Powoduje to:
A--B--F--G master
\
C'--D'--E' feature
W obu przypadkach featurezawiera teraz kod z obu masteri feature. Jeśli nie jesteś włączony feature, możesz użyć drugiego argumentu, aby przejść do niego jako skrótu: git rebase master featurezrobi to samo, co powyżej.
Teraz na specjalne --onto. Ważną częścią, o której należy pamiętać, jest domyślna wartość, <start>jeśli nie jest określona. Tak więc powyżej, gdybym --ontokonkretnie określił , spowoduje to to samo:
git rebase --onto master master
git rebase --onto master master feature
(Nie używam --ontobez sprecyzowania, <end>ponieważ łatwiej jest przeanalizować mentalnie, nawet jeśli te dwie są takie same, jeśli już są włączone feature).
Aby zobaczyć, dlaczego --ontojest przydatny, oto inny przykład. Powiedzmy, że byłem włączony featurei zauważyłem błąd, który zacząłem naprawiać - ale featurezamiast tego masterprzez pomyłkę:
A--B--F--G master
\
C--D--E feature
\
H--I bugfix
Chcę przesunąć te zatwierdzenia bugfix, aby nie były już od nich zależne feature. W tej chwili jakikolwiek rodzaj scalenia lub zmiany bazy pokazany powyżej w tej odpowiedzi zajmie trzy featurezatwierdzenia wraz z dwoma bugfixzatwierdzeniami.
Na przykład git rebase master bugfixjest zły. Zasięg <start>do <end>dzieje się zawierać wszystkie rewizje u feature, które są odtwarzanych na górze master:
A--B--F--G master
\ \
\ C'--D'--E'--H'--I' bugfix
\
C--D--E feature
To, czego tak naprawdę chcemy, to zakres zatwierdzeń od featuredo bugfixodtworzenia na górze master. Po to --ontojest - określenie innego celu „powtórki” niż gałąź „start”:
git rebase --onto master feature bugfix
A--B--F--G master
\ \
\ H'--I' bugfix
\
C--D--E feature