git merge
Слияние истории коммитов одной ветки в другую
Описание
git merge объединяет изменения из одной ветки в другую. Команда берёт независимые линии разработки, созданные командой git branch, и интегрирует их в единую ветку. Перед слиянием нужно переключиться на ветку-получатель (обычно main или develop), затем выполнить git merge <имя-ветки>.
Git поддерживает несколько стратегий слияния. Fast-forward применяется, когда ветка-получатель не имеет собственных коммитов после точки ветвления — Git просто перемещает указатель вперёд. Recursive (3-way merge) используется, когда обе ветки разошлись — Git создаёт новый merge-коммит с двумя родителями. Squash сжимает все коммиты ветки в один перед слиянием.
При конфликтах слияния Git помечает проблемные участки маркерами <<<<<<<, =======, >>>>>>>. После разрешения конфликтов нужно проиндексировать файлы (git add) и завершить слияние (git merge --continue или git commit).
Синтаксис
Флаги и опции
| Флаг | Описание |
|---|---|
--no-ff |
Всегда создавать merge-коммит, даже если возможен fast-forward. Сохраняет историю ветки. |
--ff |
Разрешить fast-forward если возможно (поведение по умолчанию) |
--ff-only |
Выполнить слияние только если возможен fast-forward; отказать при необходимости merge-коммита |
--squash |
Сжать все коммиты ветки в один рабочий коммит (без создания merge-коммита) |
-m <сообщение> |
Задать сообщение для создаваемого merge-коммита |
--abort |
Прервать процесс слияния и вернуть состояние до git merge |
--continue |
Продолжить слияние после разрешения конфликтов |
--quit |
Забыть о текущем слиянии, не трогая рабочий каталог |
-s <стратегия> |
Выбрать стратегию слияния: ort, recursive, octopus, ours, subtree |
-X <опция> |
Дополнительные опции стратегии: ours, theirs, ignore-space-change |
--no-commit |
Выполнить слияние, но не создавать коммит — позволяет просмотреть результат |
--edit |
Открыть редактор для сообщения merge-коммита (включено по умолчанию) |
--no-edit |
Принять автоматически сгенерированное сообщение merge-коммита без открытия редактора |
--stat |
Показать диффстат после успешного слияния |
Паттерны использования
Стандартное слияние feature-ветки
# Переключиться на main git switch main # Получить последние изменения git pull origin main # Слить feature-ветку с сохранением истории git merge --no-ff feature/user-auth # Отправить на remote git push origin main
Squash merge (чистая история)
# Все коммиты ветки → один коммит git switch main git merge --squash feature/refactor # Создать итоговый коммит вручную git commit -m "feat: refactor authentication module" # Ветку теперь можно удалить git branch -D feature/refactor
Разрешение конфликтов
# При конфликте Git остановится git merge feature/api # Посмотреть конфликтующие файлы git status # Открыть и исправить конфликты в редакторе # Затем проиндексировать git add src/api/handler.py # Завершить слияние git merge --continue
Слияние с выбором стороны при конфликте
# Принять все конфликты "нашей" стороны git merge -X ours feature/branch # Принять все конфликты "их" стороны git merge -X theirs hotfix/urgent # Игнорировать изменения пробелов git merge -X ignore-space-change feature/format
Слияние с просмотром перед коммитом
# Слить, но не коммитить git merge --no-commit --no-ff feature/x # Проверить результат git diff --cached # Если всё ок — зафиксировать git commit # Если не нравится — отменить git merge --abort
Прерывание при конфликте
# Начали слияние, возник конфликт git merge feature/complex # Решили разобраться позже git merge --abort # Репозиторий вернулся в состояние до merge git status # чисто
Советы и подводные камни
--no-ff при слиянии feature-веток в основную. Это сохраняет явную «пузырьковую» историю и позволяет чётко видеть, когда и какая фича была добавлена. Без этого флага при fast-forward история становится линейной и непонятной.
git mergetool для запуска визуального инструмента (vimdiff, meld, VS Code). Настройте через git config --global merge.tool vscode. В VS Code маркеры конфликтов подсвечиваются и есть кнопки «Accept Current/Incoming/Both».
git merge --squash Git не знает, что ветка слита. git branch --merged не покажет её как слитую, а повторный squash-merge попытается добавить те же изменения снова. После squash-merge всегда удаляйте исходную ветку принудительно через git branch -D.