Урок 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 сообщает, в каком файле проблема. Откроем его — спорное место помечено маркерами:
<header>
<<<<<<< HEAD
<h1>Пиццерия у дома</h1>
=======
<h1>Тесто: пицца за 10 минут</h1>
>>>>>>> new-header
</header>
- от
<<<<<<< HEADдо=======— вариант из текущей ветки, в которую вливаете (здесьmain); - от
=======до>>>>>>> new-header— вариант из вливаемой ветки.
Остальная часть файла, где споров нет, уже объединена.
Решаем конфликт
- Выберите итоговый вариант. Можно оставить один из двух или собрать третий из обоих.
- Удалите маркеры
<<<<<<<,=======и>>>>>>>. - Сохраните файл, добавьте его в индекс и завершите слияние:
<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.
Мини-тест: проверьте себя
Закрепите урок: несколько вопросов, разбор ответов — в конце.
-
Когда возникает конфликт слияния?
Если изменения в разных местах, Git объединит их сам. Конфликт — когда он не может решить, какой вариант одной и той же строки оставить.
-
Что находится между маркерами <<<<<<< HEAD и =======?
HEAD — текущая ветка, в которую вы вливаете. Между ======= и >>>>>>> — вариант из вливаемой ветки.
-
Что сделать после того, как вы поправили файл с конфликтом?
git add сообщает Git, что конфликт в файле решён, а git commit завершает слияние.
-
Как отменить начатое слияние, если запутались?
merge --abort возвращает проект в состояние до начала слияния. Можно спокойно разобраться и попробовать снова.