Конфлікт злиття
Конфлікт злиття (англ. merge conflict) виникає, коли Git об'єднує зміни й не може безпечно вирішити, яка версія файла має перемогти.
Попри назву, конфлікти злиття можуть з'являтися під час кількох операцій Git, а не лише після запуску git merge. Вони можливі, коли ти:
- Зливаєш одну гілку в іншу через
git merge. - Переносиш коміти на вершину іншої гілки через
git rebase. - Забираєш віддалені зміни через
git pull, бо після отримання змін зазвичай виконується злиття або ребейз. - Застосовуєш окремий коміт в іншому місці через
git cherry-pick. - Скасовуєш правки коміту через
git revert, якщо зворотні зміни не застосовуються чисто. - Повертаєш сховані зміни через
git stash popабоgit stash apply.
Зазвичай конфлікти виникають, коли дві гілки змінили ті самі рядки у файлі або коли одна гілка змінила файл, який інша видалила чи перейменувала. Git зупиняє операцію, щоб фінальне рішення залишилося за тобою.
Схожі помилки на кшталт «your local changes would be overwritten» — не зовсім те саме. У такому разі Git зазвичай зупиняється ще до початку операції, щоб спершу можна було зберегти або скасувати локальні правки.
Коли в текстовому файлі конфліктує вміст, Git записує у файл маркери конфлікту:
<<<<<<< HEAD
версія з твоєї поточної гілки
=======
версія, яку Git намагається додати
>>>>>>> feature-branchЧастина над ======= показує один бік конфлікту, а частина під ним — інший. Відредагуй файл до фінальної версії, яка справді потрібна, а потім прибери всі маркери конфлікту.
Ours і theirs
Git і редактори коду іноді підписують два боки конфлікту як ours (наш) і theirs (їхній). Деякі інструменти використовують для тієї самої ідеї позначки current (поточний) та incoming (вхідний). З цими назвами варто бути обережніше: вони описують сторони поточної операції Git, а не обов'язково «мою роботу» і «чужу роботу».
Для звичайного злиття значення зазвичай інтуїтивне:
git switch maingit merge feature
- Ours — це
main: гілка, активна до початку злиття. - Theirs — це
feature: гілка, яка вливається.
Під час ребейзу позначки можуть здаватися переплутаними:
git switch featuregit rebase main
Git тимчасово переносить твою роботу на вершину main. Якщо конфлікт стається, поки Git відтворює коміт із feature:
- Ours — це бік
main, бо саме він є поточною розгорнутою базою під час ребейзу. - Theirs — це коміт із
feature, який відтворюється.
Це означає, що вибір ours під час ребейзу може викинути зміни з гілки, яку ти вважаєш «своєю». Команди на кшталт git restore --ours path/to/file і git restore --theirs path/to/file вибирають цілий бік конфліктного файла, тож використовуй їх, лише коли точно розумієш, який бік Git має на увазі в поточній операції.
Як розв'язати конфлікт
Звичайний порядок дій:
- Запусти
git status, щоб побачити, які файли конфліктують. - Відкрий кожен конфліктний файл і відредагуй його до правильної фінальної версії.
- Прибери рядки з маркерами
<<<<<<<,=======і>>>>>>>. - Додай розв'язані файли в область підготовки через
git add. - Продовж операцію: закоміть злиття, запусти
git merge --continueабоgit rebase --continue— залежно від того, що підказує Git.
Git не перевіряє, чи логічно правильне твоє розв'язання. Щойно файл додано в область підготовки, Git вважає його вміст відповіддю. Перечитай результат, перш ніж продовжувати.
Якщо конфлікт стався несподівано і розв'язувати його зараз не хочеться, часто можна повернутися до попереднього стану через git merge --abort або git rebase --abort.
.gitignoregit checkoutgit configgit taggit worktree