- Андрей Куманяев/
- Git: руководства и команды/
- Конфликты слияния в Git: полное руководство по разрешению/
Конфликты слияния в Git: полное руководство по разрешению
Конфликты слияния — это нормальная часть командной разработки, а не ошибка. Они возникают, когда Git не может автоматически объединить изменения из двух веток, потому что обе ветки изменили одну и ту же строку кода. Это руководство покажет, как их читать, понимать и разрешать.
Почему возникают конфликты #
Конфликт возникает когда два разработчика изменили одну строку в одном файле, или когда один удалил файл, а другой его изменил. Git не знает «чья версия правильнее» и просит разработчика принять решение.
# Обычная ситуация:
# Разработчик 1 изменил строку в main
# Разработчик 2 изменил ту же строку в feature
git merge feature
# CONFLICT (content): Merge conflict in src/auth.js
# Automatic merge failed; fix conflicts and then commit the result.
Как Git обозначает конфликты #
Git вставляет специальные маркеры прямо в файл:
<<<<<<< HEAD
return authenticate(user.password);
=======
const hash = hashPassword(user.password);
return authenticate(hash);
>>>>>>> feature/auth
Расшифровка: <<<<<<< HEAD — начало вашей версии (текущая ветка). ======= — разделитель. >>>>>>> feature/auth — конец версии из сливаемой ветки.
Поиск конфликтных файлов #
# Показывает все конфликтные файлы
git status
# Вывод при конфликте:
# both modified: src/auth.js
# both modified: src/utils.js
# Только конфликтные файлы
git diff --name-only --diff-filter=U
Процесс разрешения конфликтов #
Шаг 1: Найти конфликтные файлы
git status
Шаг 2: Открыть каждый файл и решить конфликт
Для каждого конфликтного блока нужно выбрать одну из опций: оставить только вашу версию, оставить только их версию, написать новый код, совмещающий оба изменения.
Затем удалить все маркеры конфликта (<<<<<<<, =======, >>>>>>>).
Шаг 3: Добавить разрешённые файлы
git add src/auth.js
git add src/utils.js
Шаг 4: Завершить слияние
git commit
# Git автоматически подготовит сообщение о слиянии
Использование полной версии одной стороны #
Если хотите принять все изменения из одной стороны:
# Принять нашу версию полностью
git checkout --ours path/to/file
# или
git restore --ours path/to/file
# Принять их версию полностью
git checkout --theirs path/to/file
# или
git restore --theirs path/to/file
# Добавить в индекс
git add path/to/file
Просмотр трёх версий файла #
Git хранит три версии конфликтного файла в индексе:
git show :1:file.js # Общий предок (базовая версия)
git show :2:file.js # Наша версия (HEAD)
git show :3:file.js # Их версия (merging)
Это помогает понять, что изменил каждый разработчик относительно исходной версии.
Использование mergetool #
Визуальные инструменты упрощают разрешение конфликтов:
# Открыть настроенный mergetool
git mergetool
# Популярные инструменты:
git config --global merge.tool vimdiff
git config --global merge.tool meld
git config --global merge.tool vscode
VS Code как mergetool:
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait $MERGED'
Отмена слияния #
Если конфликты слишком сложные — можно отменить слияние:
git merge --abort
Это вернёт репозиторий в состояние до git merge.
Типичные конфликты и их решения #
Конфликт при удалении файла:
CONFLICT (modify/delete): src/old-module.js deleted in feature/cleanup and modified in HEAD.
Решение: решите, нужен ли файл. git rm src/old-module.js (удалить) или git add src/old-module.js (сохранить).
Конфликт переименования:
CONFLICT (rename/rename): src/auth.js renamed to src/authentication.js in HEAD and to src/login.js in feature
Решение: выберите одно имя или создайте новое.
Практические примеры #
# Просмотр статуса при конфликте
git status
# Просмотр только конфликтных файлов
git diff --name-only --diff-filter=U
# Просмотр содержимого конфликтного файла
cat path/to/conflicted-file
# Три версии файла
git show :1:file.js # Предок
git show :2:file.js # Наша версия
git show :3:file.js # Их версия
# Использование mergetool
git mergetool
# Принять нашу версию файла
git checkout --ours path/to/file
git add path/to/file
# Принять их версию файла
git checkout --theirs path/to/file
git add path/to/file
# После разрешения всех конфликтов
git add .
git commit
# Отмена при сложных конфликтах
git merge --abort
Предотвращение конфликтов #
Конфликты неизбежны, но их можно минимизировать: делайте git pull перед началом работы; делайте маленькие коммиты и часто пушьте; общайтесь с коллегами о том, кто что редактирует; избегайте больших изменений в одном файле несколькими разработчиками.
Часто задаваемые вопросы #
Что означают символы <<<<<<<, =======, >>>>>>>? <<<<<<< — начало вашей версии кода. ======= — граница между двумя версиями. >>>>>>> — конец версии из сливаемой ветки.
Как я узнаю, какая версия кода правильная? Git не знает — это решает разработчик. Посмотрите на контекст изменений, обсудите с коллегой. Часто правильное решение — совместить оба изменения.
Как разрешить конфликт через git mergetool? git mergetool откроет настроенный инструмент (VS Code, vimdiff, meld). Он показывает три панели: ваша версия, их версия, результат. Редактируйте результат и сохраните.
Можно ли автоматически разрешить все конфликты? Частично. git merge -X ours возьмёт вашу версию при всех конфликтах. git merge -X theirs — их версию. Но это опасно: можно потерять важные изменения.
Что делать, если я случайно выбрал неправильное разрешение? Если не сделали коммит — git merge --abort. Если уже закоммитили — git revert HEAD для отмены коммита слияния.
Заключение #
Конфликты слияния — это не проблема, это рабочий процесс. Алгоритм: git status → найти конфликты → открыть файлы → решить конфликты → удалить маркеры → git add → git commit. При сложных конфликтах используйте git mergetool или git merge --abort.
Подробнее о слиянии веток — полное руководство по git merge. О работе с ветками — ветки в Git.