Ответ
Команда git merge <branch-name> интегрирует изменения из указанной ветки в текущую (HEAD). Процесс зависит от истории коммитов и может проходить по трём основным сценариям.
1. Fast-Forward Merge (Быстрая перемотка)
Условие: Текущая ветка (main) является прямым предком целевой ветки (feature).
Что происходит: Указатель текущей ветки просто перемещается вперёд до конца целевой ветки. Новый коммит слияния не создаётся. История остаётся линейной.
git checkout main
git merge feature # HEAD (main) теперь указывает на последний коммит feature
2. Recursive Merge (3-way Merge или Создание коммита слияния)
Условие: Ветки разошлись (у каждой есть уникальные коммиты после общего предка). Что происходит: Git создаёт новый коммит слияния (merge commit), который имеет двух родителей. Изменения автоматически объединяются, если они не конфликтуют.
# История: main (A--B) и feature (A--C)
git checkout main
git merge feature
# Создаётся коммит M с родителями B и C
# История: A--B--M
# /
# C--
Алгоритм: Git находит общего предка (base), затем создаёт патч между base и каждой веткой и применяет оба патча к базе.
3. Merge с конфликтами
Условие: Git не может автоматически разрешить противоречивые изменения в одном и том же месте одного файла. Что происходит:
- Процесс слияния прерывается.
- Файлы с конфликтами помечаются в рабочей директории. В них добавляются специальные маркеры:
<<<<<<< HEAD (Current Change) код из текущей ветки ======= код из сливаемой ветки >>>>>>> feature (Incoming Change) - Статус
git statusпокажет "Unmerged paths". - Разработчик должен вручную отредактировать файлы, убрав маркеры и оставив нужный код, затем выполнить
git addдля разрешённых файлов. - Завершить слияние коммитом:
git commit.
Лучшие практики:
- Перед слиянием убедитесь, что рабочая директория чиста (
git status). - Используйте
git merge --no-ffдля запрета fast-forward, чтобы всегда создавался видимый коммит слияния. - Для сложных интеграций рассмотрите стратегию
git rebaseдля поддержания линейной истории.