Merge — це операція в Git, яка об'єднує зміни з однієї гілки в іншу, створюючи коміт злиття (merge commit). Git підтримує кілька стратегій: fast-forward (лінійна історія), three-way merge (зі створенням merge commit) і squash merge (стиснення всіх комітів в один). За даними git-scm.com, 2025, merge залишається найбільш використовуваним механізмом інтеграції коду в командній Git-розробці.
Головне
Merge (злиття) — це фундаментальна операція в Git, яка об'єднує зміни з однієї гілки (source) в іншу (target). У результаті злиття цільова гілка отримує всі коміти з вихідної гілки, яких у ній ще не було. Залежно від ситуації, Git може виконати merge трьома різними способами.
Основна цінність merge — збереження історії: merge commit фіксує факт об'єднання гілок, зберігає інформацію про те, коли і які гілки зливались. Це полегшує аудит змін, пошук регресій та розуміння хронології розробки. У великих проектах merge commit є стандартним способом інтеграції коду.
За даними GitLab Flow, merge commits використовуються в 73% команд, які працюють з Git. Альтернативні підходи (rebase, squash) надають перевагу команди, орієнтовані на лінійну історію. Вибір стратегії залежить від розміру команди, частоти релізів та прийнятих у проекті угод.
Merge потрібен, коли розробник завершив роботу над фічею і хоче інтегрувати її в develop або main. Типовий сценарій: розробник створив feature-гілку від develop, попрацював у ній кілька днів, а за цей час у develop з'явилися нові коміти від інших учасників. Перед злиттям потрібно об'єднати зміни — і для цього використовується merge.
Без merge неможливо спільно працювати над одним кодом у Git. Кожного разу, коли два розробники одночасно вносять зміни в одну кодову базу, їхні гілки розходяться. Merge — єдиний спосіб звести ці зміни назад без втрати даних.
Git підтримує три типи merge, кожен з яких призначений для свого сценарію. Вибір типу злиття впливає на історію комітів, зручність відкату та читабельність лога.
Fast-forward виникає, коли цільова гілка не мала нових комітів з моменту створення вихідної. У цьому випадку Git просто переміщує покажчик цільової гілки вперед, на останній коміт вихідної. Історія залишається лінійною, без merge commit.
# Fast-forward merge: develop не змінювався з моменту створення feature
git checkout develop
git merge feature/new-login
# Результат: покажчик develop перемістився на кінець feature
# Жодного merge commit не створено
Fast-forward зручний для короткочасних гілок, де розробник працював наодинці. Але в цього підходу є недолік: втрачається інформація про те, що гілка існувала — всі коміти виглядають як зроблені безпосередньо в develop.
Three-way merge виконується, коли обидві гілки мають нові коміти після точки розходження. Git створює окремий merge commit з двома батьками, який фіксує факт об'єднання гілок. Цей підхід рекомендується для feature-гілок у командній розробці.
# Примусовий three-way merge з прапорцем --no-ff
git checkout develop
git merge --no-ff feature/new-login
# Створено merge commit з повідомленням за замовчуванням
# Можна задати своє повідомлення через -m
git merge --no-ff feature/new-login -m "Merge feature/new-login into develop"
Прапорець --no-ff гарантує створення merge commit, навіть якщо fast-forward можливий. Це найкраща практика для збереження інформації про розгалуження в проекті.
Squash merge стискає всі коміти вихідної гілки в один і застосовує його до цільової. Історія фічі втрачається — в гілку потрапляє один коміт з усіма змінами. Це зручно, коли детальні коміти у feature-гілці не несуть цінності для загальної історії.
# Squash merge: всі коміти feature стиснуті в один
git checkout develop
git merge --squash feature/experimental
git commit -m "feat: experimental login flow (squashed)"
Squash підходить для чернеток, експериментальних гілок і ситуацій, коли важливо зберегти чистоту історії. Мінус — втрачається зв'язок з вихідними комітами, що ускладнює відкат окремих змін.
Ours і Theirs — дві спеціальні стратегії merge у Git. Ours повністю ігнорує зміни з вихідної гілки, залишаючи тільки те, що є в цільовій. Theirs, навпаки, приймає версію вихідної гілки при будь-якому конфлікті. Ці стратегії корисні при злитті великих обсягів коду, коли заздалегідь відомо, яка версія має перемогти.
Механізм merge у Git заснований на порівнянні трьох точок: спільного предка (merge base), стану вихідної гілки та стану цільової гілки. Git знаходить merge base — останній коміт, спільний для обох гілок — і обчислює, які зміни відбулися в кожній гілці після розходження.
Git використовує тристоронній алгоритм злиття, який враховує не тільки дві порівнювані версії файлу, але й їхнього спільного предка. Завдяки цьому Git може автоматично вирішити ситуації, коли зміни в одній гілці не зачіпають змінені ділянки іншої — навіть якщо обидва файли були модифіковані.
Розглянемо сценарій: два розробники працюють над різними файлами в одній feature-гілці. Перший змінив LoginActivity.kt, другий — ProfileFragment.kt. Коли вони зливають свої зміни, Git бачить, що зміни торкнулися різних файлів, і виконує merge автоматично, без втручання людини.
Якщо ж обидва розробники змінили LoginActivity.kt, але в різних методах — Git також впорається автоматично, об'єднавши зміни рядково. Конфлікт виникає тільки якщо обидва змінили одні й ті самі рядки або якщо один видалив код, який інший змінив.
Конфлікт merge виникає, коли Git не може автоматично об'єднати зміни, тому що обидві гілки модифікували одні й ті самі рядки по-різному. У цьому випадку Git позначає конфліктні ділянки у файлах і чекає ручного вирішення від розробника.
Конфліктні ділянки розмічаються спеціальними маркерами: <<<<<<< HEAD показує код із цільової гілки, ======= — роздільник, >>>>>>> source-branch — код із вихідної гілки. Розробник повинен вручну вибрати, який варіант залишити, або об'єднати їх.
# 1. Запустити merge і побачити конфлікт
git merge feature/new-login
# Вивід: CONFLICT (content): Merge conflict in LoginActivity.kt
# 2. Подивитися список файлів з конфліктами
git status
# both modified: src/ui/login/LoginActivity.kt
# 3. Вирішити конфлікт: відредагувати файл, прибрати маркери
# 4. Додати вирішений файл і завершити merge
git add src/ui/login/LoginActivity.kt
git merge --continue
# або: git commit (без --continue)
Для вирішення конфліктів існують інструменти: git mergetool відкриває візуальний мерджер (Meld, Beyond Compare, VS Code). Багато розробників вважають за краще вирішувати конфлікти в IDE — IntelliJ IDEA і Android Studio надають вбудований інструмент із трипанельним порівнянням, який значно спрощує цей процес.
Поради щодо вирішення конфліктів: завжди розумійте, що робить кожна сторона конфлікту, не видаляйте чужий код без розуміння його логіки, і якщо конфлікт занадто складний — залучіть авторів обох гілок до спільного вирішення.
Вибір між Merge і Rebase — одне з найчастіших архітектурних рішень у Git. Обидва підходи об'єднують зміни, але роблять це по-різному: merge зберігає історію розгалуження, rebase переписує історію, роблячи її лінійною.
Багато команд використовують гібридний підхід: rebase для приведення feature-гілки до актуального стану develop (git rebase develop), а потім merge з прапорцем --no-ff для фіксації злиття. Це дає чисту історію всередині фічі та інформативні точки злиття на рівні develop.
Часті запитання
Без --no-ff Git виконує fast-forward merge, якщо можливо — просто переміщує покажчик гілки. З --no-ff Git завжди створює merge commit, зберігаючи інформацію про розгалуження. Рекомендується для feature-гілок у командній розробці.
Використовуйте git mergetool або вбудований інструмент IDE. Якщо конфлікт зачіпає десятки файлів — можливо, гілки занадто сильно розійшлися. У такому випадку варто обговорити з командою план злиття, можливо — розбити його на кілька етапів.
Так: git merge --abort скасовує merge, якщо він ще не завершений (конфлікт). Якщо merge вже завершений — використовуйте git reset --hard HEAD~1 або git revert -m 1 <merge-commit> для безпечного відкату.
Рекомендується для командної роботи. Merge commit фіксує факт злиття, містить посилання на обидві гілки та спрощує розуміння історії. Для особистих або експериментальних гілок допустимий squash merge або fast-forward.
Git не може автоматично зливати бінарні файли — він вибирає одну з версій цілком. Для бінарних файлів (зображення, .aab, .apk) рекомендується мінімізувати паралельні зміни та використовувати Git LFS для великих файлів.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також