Пропустимо --ontoна мить. upstreamі branchє досить базовими, насправді начебто мімічними checkoutі branch- другий аргумент необов’язковий:
git branch <newbranch>
git branch <newbranch> <base>
git checkout -b <newbranch>
git checkout -b <newbranch> <base>
git rebase <upstream>
git rebase <upstream> <branch>
( За винятком, імена цих аргументів в rebase«вгору» і «гілки» не надто описовий IMO я зазвичай думаю про них , як peachoftree ,. <start>І <end>, що , як я буду використовувати їх: git rebase <start> <end>)
Коли другу гілку опущено, результат майже такий же, як спочатку перевірити цю гілку, а потім зробити це так, як ніби ви її не вказали. Виняток - це те, branchщо не змінює поточну галузь:
git checkout <base> && git branch <newbranch> && git checkout <previous_branch>
git checkout <base> && git checkout -b <newbranch>
git checkout <end> && git rebase <start>
Що стосується розуміння того, що rebaseробить, коли викликається, я спершу почав думати про це як про особливий тип злиття. Це насправді не так, але це допомогло, коли вперше почали розуміти базу даних. Позичити приклад гороху:
A--B--F--G master
\
C--D--E feature
А git merge masterрезультати в цьому:
A--B--F-----G master
\ \
C--D--E--H feature
Хоча git rebase master(поки на гілці feature!) Це призводить до цього:
A--B--F--G master
\
C'--D'--E' feature
В обох випадках featureтепер міститься код і з masterі feature. Якщо ви не ввімкнено feature, другий аргумент можна використовувати для переключення на нього як ярлик: git rebase master featureзробить те саме, що і вище.
Тепер для спец --onto. Важлива частина, яку слід пам’ятати при цьому, - це те, що він за замовчуванням, <start>якщо не вказано. Отже вище, якби я --ontoконкретно вказав , це призведе до того ж:
git rebase --onto master master
git rebase --onto master master feature
(Я не використовую --ontoбез вказівки <end>просто тому, що простіше розумово розібратися, навіть подумав, що ці двоє однакові, якщо вже ввімкнено feature.)
Щоб зрозуміти, чому --ontoкорисно, ось інший приклад. Скажімо, я ввімкнув featureі помітив помилку, яку я потім почав виправляти - але відключився featureзамість masterпомилки:
A--B--F--G master
\
C--D--E feature
\
H--I bugfix
Мені хочеться "перемістити" ці зобов'язання, bugfixщоб вони більше не залежали feature. Як це є, будь-який тип злиття або відновлення, показаний вище у цій відповіді, буде приймати три featureкоміти разом з двома bugfixкомітами.
Наприклад, git rebase master bugfixнеправильно. Діапазон, <start>який <end>трапляється, включає всі featureкомісії з , які відтворюються поверх master:
A--B--F--G master
\ \
\ C'--D'--E'--H'--I' bugfix
\
C--D--E feature
Те , що ми на самому ділі хочемо діапазон коммітов від featureдо bugfixпереграється на вершині master. Саме для цього --ontoпотрібно вказати іншу ціль "повтор", ніж гілка "пуск":
git rebase --onto master feature bugfix
A--B--F--G master
\ \
\ H'--I' bugfix
\
C--D--E feature