Merge и rebase
↑ 6.1 Git · ← Предыдущая · → Следующая
Зачем это на собесе
Классика: в чём разница, когда что использовать и почему «золотое правило rebase».
Объяснение
Оба способа объединяют изменения веток, но по-разному строят историю.
merge | rebase | |
|---|---|---|
| Результат | merge-коммит с двумя родителями (или fast-forward) | линейная история: коммиты ветки переигрываются поверх целевой |
| История | сохраняет реальную хронологию, «ромбы» | чистая, линейная |
| Хэши коммитов | не меняются | меняются (новые коммиты) |
| Конфликты | разрешаются один раз | могут возникать на каждом переигрываемом коммите |
| Безопасность | безопасно для общих веток | переписывает историю: нельзя на опубликованных общих ветках |
| Отмена | git revert -m 1 <merge> | сложнее, reflog |
# merge: влить feature в main
git switch main && git merge --no-ff feature/x # всегда создавать merge-коммит
git merge --ff-only feature/x # только если возможна перемотка
# rebase: обновить feature поверх main
git switch feature/x && git fetch && git rebase origin/main
git rebase --continue / --abort / --skip
# интерактивный rebase: причесать историю перед PR
git rebase -i HEAD~5 # pick, reword, squash, fixup, drop, edit, reorder
git commit --fixup <hash> && git rebase -i --autosquash origin/mainSquash merge (в PR): все коммиты ветки схлопываются в один — чистая история main, но теряется детализация.
Золотое правило rebase: не переписывайте историю, которую уже получили другие (main, общие ветки). Свою feature-ветку перед PR — можно и нужно.
Типичный процесс: работа в feature-ветке → git pull --rebase/rebase origin/main для актуальности → rebase -i для чистки → PR → merge/squash в main.
Нюансы и подводные камни
- После
rebaseветку нужно отправлятьpush --force-with-lease. - Rebase ветки, от которой ответвились другие, ломает их основания.
- Слишком долгоживущие ветки приводят к болезненным конфликтам — вливайте
mainчаще. git pullпо умолчанию делает merge: настройтеpull.rebase=trueосознанно.- В PR-платформах squash скрывает авторство отдельных коммитов.
Практика
- Сравните граф после
merge --no-ffиrebaseна тестовом репозитории. - Соберите 5 коммитов в 2 через
rebase -i(squash,fixup,reword). - Настройте
git config pull.rebase true,rebase.autoStash.
Вопросы с ответами
Чем rebase отличается от merge?
Merge объединяет ветки merge-коммитом, сохраняя историю; rebase переигрывает коммиты поверх другой ветки, создавая линейную историю с новыми хэшами.
Почему нельзя делать rebase общих веток?
Он меняет хэши коммитов, и у коллег история расходится с вашей.