У кожній команді рано чи пізно звучить питання: «робимо rebase чи merge?». Відповідь: і те, і те, просто в різних місцях. Обидві команди об’єднують зміни з двох гілок, але залишають по собі різну історію.
Merge: історія такою, якою вона була
git merge створює новий коміт із двома батьками. Нічого не переписується, тож це безпечно навіть на гілках, якими користуються інші. Ціна — розгалужена історія, яка на жвавому репозиторії схожа на схему метро.
git switch main
git merge feature/login
Rebase: історія такою, якою ви хочете її показати
git rebase бере ваші коміти й відтворює їх на новій базі. Історія лінійна й читається як оповідь. Але коміти отримують нові хеші — це нові об’єкти, навіть якщо зміни ті самі.
git switch feature/login
git rebase main
# після розв’язання конфлікту:
git add . && git rebase --continue
Золоте правило: не робіть rebase гілки, на якій працює хтось, крім вас.
Як поєднати на практиці
| Ситуація | Вибір |
|---|---|
| Оновити свою гілку змінами з main | rebase |
| Прибирання перед pull request | rebase -i |
| Злиття готової функції в main | merge (або squash) |
| Гілка, спільна для кількох людей | merge |
Два рядки конфігурації, які раджу всім: git pull робитиме rebase замість зайвих merge-комітів, а незбережені локальні зміни автоматично відкладатимуться.
git config --global pull.rebase true
git config --global rebase.autoStash true
Push після rebase
Після rebase звичайний git push буде відхилено, бо історії відрізняються. Замість --force використовуйте --force-with-lease: він перезапише гілку, лише якщо ніхто тим часом нічого до неї не додав.
Щось пішло не так? Reflog
Git майже нічого не губить. git reflog показує, де був HEAD перед кожною операцією, тож невдалий rebase скасовується однією командою.
git reflog
# a1b2c3d HEAD@{4}: rebase (start): checkout main
git reset --hard HEAD@{5}
Наостанок Суперечка «rebase чи merge» — це зазвичай суперечка про те, хто читає історію. Домовтеся в команді один раз, запишіть у CONTRIBUTING.md і повертайтеся до роботи.
