Злиття (Merge) — це операція злиття гілок у Git, яка об'єднує зміни з двох різних ліній розробки в одну цільову гілку. На відміну від rebase, merge зберігає повну історію розгалуження, створюючи спеціальний merge-коміт із двома батьками. За даними офіційної документації Git (2026), merge є найбезпечнішим способом об'єднання гілок, оскільки не перезаписує історію та дозволяє відстежити, коли й які гілки зливалися. Це стандартний вибір для злиття в публічних гілках, таких як main, develop та release.
Головне
Merge — це команда git merge, яка об'єднує зміни із зазначеної гілки в поточну. Git знаходить спільного предка (базовий коміт), обчислює diff кожної гілки відносно предка та створює merge-коміт, що містить об'єднаний набір змін. Результат — цільова гілка отримує всі зміни з гілки, що зливається.
Синтаксис: перебуваючи в цільовій гілці (наприклад, main), виконайте git merge feature. Git автоматично створює merge-коміт, якщо немає конфліктів. У повідомленні merge-коміта за замовчуванням вказується: «Merge branch 'feature' into main». Повідомлення можна змінити за допомогою прапорця -m або відредагувати у відкритому редакторі.
Merge — це неруйнівна операція. На відміну від rebase, merge не чіпає існуючі коміти: вони залишаються з тими ж хешами, авторами та датами. Це робить merge єдиним безпечним способом злиття для гілок, з якими одночасно працюють кілька розробників. Якщо щось пішло не так, merge можна скасувати командою git merge --abort.
# Перейти на цільову гілку
git checkout main
# Злити гілку функції
git merge feature
# Результат — merge-коміт із двома батьками
git log --oneline --graph
# Злиття з користувацьким повідомленням
git merge feature -m "feat: integrate authentication module"
Git підтримує три режими злиття, які вибираються залежно від бажаного результату. Звичайний merge (за замовчуванням) створює merge-коміт. Squash merge об'єднує всі коміти гілки функції в один. Fast-forward переміщує покажчик гілки без створення коміта, якщо це можливо. Вибір режиму залежить від робочого процесу команди та правил історії.
Звичайний merge (--no-ff) — створює merge-коміт, навіть якщо merge можна виконати fast-forward. Рекомендується для main-гілки: merge-коміт явно маркує момент інтеграції функції та дозволяє легко відкотити всі зміни гілки функції одним revert merge-коміта. GitHub використовує цей режим за замовчуванням при злитті PR через кнопку Merge.
Squash merge (--squash) — збирає всі коміти гілки функції в один коміт у цільовій гілці. Корисний, коли чернова історія гілки функції не повинна потрапляти в main. Недолік: втрачається зв'язок з оригінальними комітами — не можна побачити, як функція розроблялася покроково. GitHub використовує цей режим при виборі «Squash and merge» у PR.
Fast-forward (--ff) — якщо цільова гілка не має нових комітів після відгалуження гілки функції, Git просто переміщує покажчик уперед, без створення merge-коміта. Історія залишається лінійною. Прапорець --no-ff примусово створює merge-коміт, --ff-only завершиться помилкою, якщо fast-forward неможливий.
# Примусовий merge-коміт (рекомендується для main)
git merge --no-ff feature
# Squash merge — всі коміти в один
git merge --squash feature
git commit -m "feat: add authentication"
# Fast-forward тільки якщо можливо
git merge --ff-only feature
# Скасувати конфліктне злиття
git merge --abort
Стратегії злиття визначають алгоритм, який Git використовує для об'єднання змін. Кожна стратегія підходить для різних сценаріїв. Git автоматично вибирає відповідну стратегію, але розробник може вказати її явно через прапорець --strategy. Розуміння стратегій допомагає передбачити поведінку Git при складних злиттях.
Recursive — стратегія за замовчуванням для злиття двох гілок. Git знаходить спільного предка, обчислює зміни в кожній гілці та об'єднує їх. Якщо знайдено спільного предка, recursive коректно обробляє перейменування файлів та додавання нових. При конфліктах recursive може використовувати додаткові опції: ours (автоматично вибирати нашу версію) та theirs (вибирати їхню).
Octopus — для одночасного злиття більше двох гілок: git merge feature1 feature2 feature3. Octopus не підтримує вирішення конфліктів — всі конфлікти повинні бути вирішені до виклику команди. Використовується рідко, в основному для об'єднання кількох незалежних гілок, які гарантовано не конфліктують (наприклад, різні модулі).
| Стратегія | Кількість гілок | Вирішення конфліктів |
|---|---|---|
| Recursive | 2 | Автоматичне + опції ours/theirs |
| Octopus | 3+ | Ні — всі конфлікти повинні бути вирішені заздалегідь |
| Ours | Будь-яка | Завжди вибирає нашу версію, ігнорує чужі зміни |
| Subtree | 2 | Для злиття піддерев (subtree merge) |
Ours — особлива стратегія, яка повністю ігнорує зміни з гілки, що зливається, і зберігає поточний вміст цільової гілки. Merge-коміт створюється, але вміст залишається без змін. Корисна, коли потрібно зафіксувати в історії факт злиття, але фактично відхилити всі зміни з іншої гілки.
Merge-конфлікт виникає, коли одні й ті ж рядки файлу були змінені в обох гілках по-різному. Git не може автоматично визначити, яка версія правильна, і призупиняє merge. Конфлікт може також виникнути при перейменуванні файлу в одній гілці та його зміні в іншій, або при одночасному видаленні та модифікації одного файлу.
Процес вирішення: Git позначає конфліктуючі файли маркерами. У файлі з'являються ділянки з <<<<<<< HEAD (наша версія), ======= (розділювач) та >>>>>>> feature (їхня версія). Розробник вручну редагує конфліктну ділянку, вибираючи потрібні рядки з обох версій, прибирає маркери, зберігає файл і додає його в індекс через git add.
Для візуального вирішення конфліктів Git підтримує mergetool — зовнішній інструмент порівняння. Популярні mergetool: Meld, KDiff3, Beyond Compare, VS Code (вбудований редактор конфліктів). Mergetool відображає три панелі: наша версія, їхня версія та результат. Розробник візуально вибирає блоки коду для включення в підсумковий файл.
# Почати злиття та виявити конфлікт
git merge feature
# КОНФЛІКТ (вміст): Конфлікт злиття в src/main.swift
# Перевірити конфліктуючі файли
git status
# Відкрити візуальний mergetool
git mergetool
# Після вирішення — add та commit
git add src/main.swift
git commit
# Скасувати злиття
git merge --abort
Merge кращий за rebase у кількох ключових ситуаціях. Перша: при роботі з публічними гілками, доступними іншим розробникам. Merge не перезаписує історію, і колеги можуть безпечно синхронізуватися. Rebase у публічній гілці створить розбіжну історію та конфлікти у всіх, хто вже отримав старі коміти.
Друга ситуація: при завершенні гілки функції. Більшість команд віддає перевагу merge (з прапорцем --no-ff) у main, щоб зафіксувати момент інтеграції функції. Це спрощує навігацію по історії та дозволяє легко відкотити цілу функцію одним git revert merge-коміта. GitHub Flow за замовчуванням пропонує три опції merge: простий merge, squash merge та rebase merge.
Третя ситуація: при роботі з pull request, який пройшов рев'ю. GitHub та GitLab пропонують кнопку merge з різними опціями. Merge (Create a merge commit) — повна історія з merge-комітом. Squash and merge — чиста історія без деталей розробки. Rebase and merge — лінійна історія без merge-коміта, але з перезаписом комітів. Вибір залежить від правил команди.
Перше правило: завжди бути на актуальній версії цільової гілки перед merge. Виконайте git checkout main && git pull перед тим, як зливати гілку функції. Це мінімізує конфлікти та гарантує, що merge-коміт міститиме всі актуальні зміни. Якщо цільова гілка сильно пішла вперед, спочатку виконайте git merge main всередині гілки функції для вирішення конфліктів у її контексті.
Друге правило: тестувати код після merge. Merge може змінити поведінку, навіть якщо не було конфліктів. CI/CD пайплайн повинен прогнати тести на merge-коміті перед відправкою в продакшн. Деякі команди використовують merge gates — обов'язкові перевірки, які блокують merge до їх проходження.
Третє правило: документувати merge-коміти. Стандартне повідомлення «Merge branch 'feature' into main» малокорисне. Рекомендується додавати опис того, що було злито: «Merge authentication module: login, registration, password recovery». Це спрощує аналіз історії та пошук регресій. У великих проектах merge-коміти автоматично генеруються з назви PR.
Часті запитання
Зливати — виконати git merge для об'єднання змін з однієї гілки в іншу. Результатом є merge-коміт, який фіксує факт злиття та містить зміни з обох гілок. Це основний спосіб інтеграції гілок функцій у main, develop або release у Git Flow.
Squash merge об'єднує всі коміти гілки функції в один коміт у цільовій гілці, втрачаючи проміжну історію розробки. Звичайний merge створює merge-коміт, зберігаючи всі коміти гілки функції. Squash merge дає чисту історію, але не дозволяє відстежити покрокову розробку функції.
Відкрийте конфліктуючий файл, знайдіть ділянки з маркерами <<<<<<< HEAD та >>>>>>>. Відредагуйте вміст, залишивши потрібні рядки з обох версій, видаліть маркери. Збережіть файл, виконайте git add та git commit. Можна використовувати git mergetool для візуального вирішення.
Merge завжди використовується для публічних гілок (main, develop, release), оскільки не перезаписує історію. Rebase застосовується в особистих гілках функцій до їх публікації. Після того як гілка стала частиною спільного репозиторію та до неї звернулися колеги, дозволений тільки merge.
До завершення merge (під час конфлікту) — git merge --abort скасовує злиття повністю. Після завершення — git revert <merge-commit-hash> -m 1 створює скасовуючий коміт. Прапорець -m 1 вказує, яку батьківську гілку зберегти (цільову). Git revert безпечніший за git reset для опублікованих гілок.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також