


Конфликт слияния в Git означает, что автоматическое объединение остановилось и требуется ваше решение. Нужно выбрать итоговое содержимое, проверить его, отметить файл как разрешённый и завершить merge. Простое удаление маркеров конфликта ещё не доказывает, что программа работает правильно.
Ниже воспроизведём конфликт в отдельном учебном репозитории. Пример не меняет существующий проект и не требует удалённого сервера. На Mentoring.digital можно выбрать наставника для разбора собственной истории веток, когда учебный случай уже понятен.
Запустите git status. Он показывает текущую ветку, конфликтующие файлы и подсказку о незавершённой операции. В этой статье рассматривается именно git merge. Для rebase и cherry-pick команды продолжения и отмены другие; не подставляйте команды из инструкции механически.
Перед началом merge полезно иметь чистую рабочую копию и сохранённую понятную точку возврата. Если конфликт случился в рабочем проекте с несохранёнными изменениями, сначала разберитесь с их состоянием. Git предупреждает, что merge --abort не всегда может восстановить всё, если незакоммиченные изменения существовали до слияния.
Создайте новую пустую папку merge-lab, откройте в ней терминал и выполните команды. Если папка уже содержит проект, выберите другое имя. Настройки имени и почты ниже применяются только к этому учебному репозиторию.
git init -b main
git config user.name "Merge Lab"
git config user.email "merge-lab@example.invalid"
Создайте файл message.txt с единственной строкой Hello. Затем сохраните исходную версию:
git add message.txt
git commit -m "Add initial greeting"
git switch -c feature
В ветке feature замените строку на Hello, team, сохраните файл и сделайте коммит:
git add message.txt
git commit -m "Address the team"
git switch main
В main в файле снова будет исходное Hello. Теперь замените его на Hello, students и выполните:
git add message.txt
git commit -m "Address the students"
git merge feature
git status
Обе ветки изменили одну исходную строку по-разному. Слияние должно остановиться на конфликте message.txt. Это ожидаемый результат упражнения.
При обычном стиле отображения конфликта файл будет содержать две версии:
<<<<<<< HEAD
Hello, students
=======
Hello, team
>>>>>>> feature
В данном merge HEAD обозначает текущую ветку main, а нижняя часть пришла из feature. При стиле diff3 или zdiff3 дополнительно может показываться общий предок. Не считайте количество разделителей фиксированным для всех настроек.
Посмотреть исходные версии конфликтующего файла отдельно можно так:
git show :1:message.txt
git show :2:message.txt
git show :3:message.txt
Для этого обычного конфликта первая команда показывает общего предка, вторая нашу сторону, третья присоединяемую. На конфликтах добавления или удаления некоторые стадии могут отсутствовать. При rebase смысл сторон отличается, поэтому сначала определяют выполняемую операцию.
Для упражнения договоримся, что итоговое приветствие должно обращаться к обеим группам: Hello, team and students. Замените всё конфликтное содержимое этой строкой. В настоящем проекте решение может требовать объединить две реализации или согласовать одну с автором изменения.
Команды принятия только ours или theirs подходят не всегда: можно незаметно выбросить полезные изменения другой ветки. Особенно внимательно проверяйте конфигурацию, миграции, зависимости и тестовые ожидания.
git diff --check
git diff
git add message.txt
git diff --cached
git status
git commit -m "Merge feature and combine greeting"
git add сообщает Git, что вы разрешили конфликт в файле. Он не проверяет смысл решения. До коммита просмотрите подготовленный diff и выполните проверки проекта. Для нашего текста проверка проста: одна строка, обе группы упомянуты, маркеров нет.
После коммита git status должен показывать чистую рабочую копию. Команда ниже помогает увидеть результат слияния и его родителей:
git log --oneline --graph --all -6
git show --no-patch --format="%h %p %s" HEAD
У merge-коммита этого упражнения будут два родителя. В приложении дополнительно запускают тесты затронутого поведения: сборка без ошибок не гарантирует сохранения бизнес-логики. Например, при объединении проверок доступа нужно проверить и разрешённый, и запрещённый запрос.
Если вы ещё на стадии конфликта и решили отказаться от операции, используйте:
git merge --abort
Затем снова выполните git status и проверьте файлы. Эта команда предназначена для незавершённого merge. После создания merge-коммита история уже другая: не применяйте к ней инструкции по отмене конфликта и не делайте принудительный push без понимания последствий для команды.
Чтобы отдельно потренировать отмену, повторите упражнение в ещё одной новой папке и вызовите merge --abort сразу после появления конфликта. Так оба сценария останутся понятными и независимыми.
Небольшие изменения с одной задачей легче объединять и проверять. Согласовывайте массовое форматирование отдельно от изменения поведения. Перед слиянием читайте историю затронутых строк, а после него проверяйте общий результат, а не только каждый конфликтный фрагмент по отдельности.
На курсе Git с наставником можно последовательно разобрать ветки, merge и состояние рабочей копии. Если конфликт уже возник в вашем проекте, ментор по Git поможет прочитать историю и выбрать способ разрешения с учётом командного процесса.