Звичайний git rebase main переносить усі коміти поточної гілки, яких немає в main. Але інколи потрібно перенести лише частину комітів чи змінити основу на зовсім іншу гілку. Для цього є --onto:
git rebase --onto <нова-основа> <стара-основа> <гілка>
Git бере коміти з діапазону стара-основа..гілка і відтворює їх поверх нова-основа.
Сценарій 1 - гілку створено не від тієї гілки. Гілку feature почали від develop, а треба було від main:
main ── A
\
develop B ── C
\
feature D ── E
git rebase --onto main develop feature
main ── A ── D' ── E' (feature)
Коміти B і C з develop у feature не потрапили.
Сценарій 2 - залежні pull request. Гілка part-2 побудована поверх part-1. Після злиття part-1 через squash її коміти в main мають інші хеші, і звичайний git rebase main намагатиметься застосувати їх повторно з конфліктами:
git rebase --onto main part-1 part-2
Переноситься лише власна робота part-2.
Сценарій 3 - видалити коміти з середини гілки:
git rebase --onto HEAD~5 HEAD~3
Коміти HEAD~4 і HEAD~3 зникають, решта переноситься на HEAD~5.
Що пам'ятати:
- як і будь-який rebase,
--ontoстворює нові коміти з новими хешами - для вже опублікованої спільної гілки це переписування історії; - якщо заплуталися -
git rebase --abortпід час процесу чиgit reflogпісля нього; --update-refs(Git 2.38+) оновлює й проміжні гілки в ланцюжку - зручно для стопки залежних гілок.
Докладніше в документації: git rebase: перенесення гілки з --onto