↓Перейти к содержанию
  1. Git: руководства и команды/

Конфликты слияния в Git: полное руководство по разрешению

·4 минуты·

Конфликты слияния — это нормальная часть командной разработки, а не ошибка. Они возникают, когда 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.