Урок 6 из 8 · 20 мин · обновлено

Конфликты слияния: почему случаются и как их решать

Откуда берутся конфликты при слиянии веток, как выглядят маркеры конфликта в файле, как его разрешить и как реже попадать в такие ситуации.

Откуда берутся конфликты

В прошлом уроке слияние прошло гладко: Git сам объединил изменения. Так бывает почти всегда — если правки в разных файлах или в разных частях одного файла.

Но представьте: в ветке main заголовок поменяли на «Пиццерия у дома», а в ветке new-header — на «Тесто: пицца за 10 минут». Какой оставить? Git не знает, что правильно, и просит решить человека. Это и есть конфликт слияния.

Конфликт — не ошибка и не поломка. Это обычная рабочая ситуация, особенно в команде.

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

Терминал
git merge new-header
Результат
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.

Git сообщает, в каком файле проблема. Откроем его — спорное место помечено маркерами:

HTML
<header>
<<<<<<< HEAD
  <h1>Пиццерия у дома</h1>
=======
  <h1>Тесто: пицца за 10 минут</h1>
>>>>>>> new-header
</header>
  • от <<<<<<< HEAD до ======= — вариант из текущей ветки, в которую вливаете (здесь main);
  • от ======= до >>>>>>> new-header — вариант из вливаемой ветки.

Остальная часть файла, где споров нет, уже объединена.

Решаем конфликт

  1. Выберите итоговый вариант. Можно оставить один из двух или собрать третий из обоих.
  2. Удалите маркеры <<<<<<<, ======= и >>>>>>>.
  3. Сохраните файл, добавьте его в индекс и завершите слияние:
HTML
<header>
  <h1>Тесто: пицца у дома за 10 минут</h1>
</header>
Терминал
git add index.html
git commit -m "Объединил варианты заголовка"

git status в любой момент подскажет, в каких файлах конфликты ещё не решены.

Если файлов с конфликтами несколько, повторите это для каждого, а коммит сделайте один в конце.

Если запутались

Начатое слияние можно отменить целиком:

Терминал
git merge --abort

Проект вернётся в состояние до git merge — можно спокойно разобраться и попробовать снова.

Конфликты в редакторе

VS Code подсвечивает конфликты и показывает над ними кнопки: «Принять текущее», «Принять входящее», «Принять оба». Удобно, но понимать маркеры всё равно нужно: иногда правильный ответ — собрать вариант вручную.

Как реже попадать в конфликты

  • Короткие ветки. Чем быстрее задача вливается в main, тем меньше успевают разойтись версии.
  • Небольшие коммиты. Их проще сравнивать и объединять.
  • Регулярно подтягивайте main в свою ветку: git merge main, пока работаете над задачей.
  • Договаривайтесь в команде, кто какую часть кода меняет.

Попробуйте сами. Устройте конфликт специально. Создайте ветку text, поменяйте в ней первый абзац index.html и сделайте коммит. Вернитесь в main, поменяйте тот же абзац по-другому, закоммитьте и влейте text. Решите конфликт.

Решение
Терминал
git switch -c text
# поменяли первый абзац в index.html
git commit -am "Новый текст абзаца в ветке text"

git switch main
# поменяли тот же абзац по-другому
git commit -am "Новый текст абзаца в main"

git merge text           # CONFLICT в index.html
# открыли файл, выбрали вариант, удалили маркеры
git add index.html
git commit -m "Решил конфликт в первом абзаце"

Флаг -a в git commit -am сразу добавляет в коммит все изменённые файлы, которые Git уже отслеживает, — без отдельного git add.

Мини-тест: проверьте себя

Закрепите урок: несколько вопросов, разбор ответов — в конце.

  1. Когда возникает конфликт слияния?

  2. Что находится между маркерами <<<<<<< HEAD и =======?

  3. Что сделать после того, как вы поправили файл с конфликтом?

  4. Как отменить начатое слияние, если запутались?