Git: как разрешить конфликт слияния (merge conflict)

Категория: Git · Язык: Bash · Обновлено:

Конфликт слияния возникает, когда две ветки изменили одни и те же строки. Чтобы разрешить его, откройте помеченные файлы, оставьте нужный вариант, выполните git add для файла и завершите слияние командой git commit. Отменить слияние можно командой git merge --abort.

Как выглядит конфликт

После git merge feature/phone-login git сообщает о конфликте, а в файле появляются маркеры:

Текст
<<<<<<< HEAD
Заголовок: вход через почту
=======
Заголовок: вход по номеру телефона
>>>>>>> feature/phone-login

Между <<<<<<< и ======= находится ваша версия (текущая ветка), между ======= и >>>>>>> версия из вливаемой ветки.

Шаги разрешения

Bash
git status                             # раздел «Unmerged paths» перечисляет конфликтные файлы
# откройте файл, оставьте нужный вариант и удалите три строки с маркерами
git add login.txt                      # сообщить git, что конфликт в файле решён
git commit                             # завершить слияние (сообщение подставится само)

Перед коммитом убедитесь, что маркеров не осталось: grep -rn '<<<<<<<\|>>>>>>>' . ничего не должен находить.

Взять версию целиком

Bash
git checkout --ours login.txt          # версия из текущей ветки
git checkout --theirs login.txt        # версия из вливаемой ветки
git add login.txt

Для всего слияния сразу действует стратегия: git merge -X ours feature и git merge -X theirs feature разрешают спорные строки в пользу одной из сторон, неспорные изменения сохраняются.

Полезные команды

Bash
git diff --name-only --diff-filter=U   # список файлов с неразрешёнными конфликтами
git diff                               # показать конфликт в сводном виде
git checkout --merge login.txt         # вернуть маркеры конфликта, если решение ошибочно
git mergetool                          # открыть настроенный графический инструмент

Отменить слияние

Bash
git merge --abort                      # вернуть всё к состоянию до git merge

Если слияние уже завершено коммитом, отмените его так же, как обычный коммит: git reset --hard HEAD~1, пока изменения не отправлены на сервер.

Как реже получать конфликты

  • Чаще забирайте изменения из основной ветки: git pull --rebase или git merge main в рабочую ветку.

  • Не смешивайте в одном коммите форматирование и правки логики.

  • Делите большие файлы и договаривайтесь о зонах ответственности в команде.

Частые вопросы

Что значит HEAD в маркерах конфликта?

Это текущий коммит, то есть последний коммит ветки, в которую вы вливаете изменения.

Как понять, что конфликт разрешён правильно?

Соберите проект и запустите тесты до коммита. Git проверяет только отсутствие маркеров в проиндексированных файлах, но не смысл кода.