Перейти к содержимому
EVI Solutions

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

Средне 15 мин Обновлено:

Краткий ответ

Конфликт слияния Git возникает, когда две ветки изменяют одну и ту же часть файла. Решается так: откройте файлы с маркерами конфликта, вручную выберите или объедините изменения, сохраните, выполните `git add` и завершите с помощью `git commit` или `git merge --continue`. Если запутались, `git merge --abort` вернёт всё в состояние до слияния.

Как проявляется проблема

  • Сообщение `CONFLICT (content): Merge conflict in ...` в терминале
  • Файлы содержат маркеры `<<<<<<<`, `=======`, `>>>>>>>`
  • `git status` показывает файлы в разделе "Unmerged paths"
  • Слияние начато, но не завершено, `git log` не показывает новый коммит
  • Редактор или IDE показывает красные маркеры на строках с конфликтом

Частые причины

Изменения одной и той же части файла в двух ветках

Две ветки изменяли одни и те же строки кода или один и тот же блок текста, поэтому Git не может автоматически решить, какая версия правильная.

Удаление или перемещение файла в одной ветке

Если файл удалён в одной ветке, а изменён в другой, Git сообщает о конфликте modify/delete.

Одновременная работа над одной веткой

Два разработчика изменяли один и тот же файл без получения последних изменений, поэтому слияние позже обнаруживает пересечение.

Настраиваемые параметры слияния

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

Пошаговое решение

  1. 1

    Проверьте состояние репозитория

    Выполните git status. Файлы с конфликтом будут перечислены в разделе "Unmerged paths". Запишите их или откройте терминал в корне проекта. Не прерывайте слияние, пока не решите, что хотите сделать.

  2. 2

    Откройте файл с конфликтом

    Откройте каждый файл из списка в редакторе. Найдите маркеры <<<<<<< HEAD, ======= и >>>>>>> имя-ветки. При стиле по умолчанию часть между <<<<<<< и ======= это ваша текущая ветка, а часть между ======= и >>>>>>> приходит из сливаемой ветки. Если вы используете стиль diff3, есть также часть с общим предком между ||||||| и =======.

  3. 3

    Вручную объедините изменения

    Удалите все маркеры конфликта и оставьте только нужный код. Можно сохранить одну сторону, другую или объединить обе. Обратите внимание на скобки, запятые и отступы. Если не уверены, откройте историю файла (git log -- файл), чтобы увидеть, кто что менял.

  4. 4

    Используйте редактор или IDE для просмотра

    VS Code предлагает опции "Accept Current Change", "Accept Incoming Change" и "Accept Both Changes"; аналогичные опции есть и в других редакторах. Это быстрее, но всегда проверяйте результат. Не принимайте слепо обе стороны, если логика кода пересекается.

  5. 5

    Сохраните и отметьте как решённое

    Когда закончите с файлом, сохраните его и выполните git add имя-файла. Повторите для всех файлов из списка. git status теперь должен показать "All conflicts fixed but you are still merging".

  6. 6

    Завершите слияние

    Выполните git commit (без -m, если хотите отредактировать сообщение) или git merge --continue. Этим создаётся коммит слияния. Проверьте git log --oneline -3, чтобы увидеть, что слияние зафиксировано.

  7. 7

    Протестируйте перед push

    Запустите сборку и тесты (npm test, mvn test или что использует проект). Конфликт может скрыть ошибку, которая проявится только при выполнении. Только когда тесты пройдут, выполните git push.

  8. 8

    Если хотите отменить

    Команда git merge --abort возвращает рабочий каталог в состояние до начала слияния. Используйте её, если решите, что лучше сначала получить изменения или посоветоваться с коллегой. Не используйте git reset --hard, если у вас есть несохранённые изменения.

Когда конфликт становится слишком большим

Если в файле десятки конфликтных блоков или вы не понимаете код, не выбирайте стороны наугад. Если хотите сохранить состояние перед слиянием, создайте резервную ветку до начала слияния (git branch моя-резервная); она не сохраняет несохранённые изменения в рабочем каталоге. Если начинаете слияние заново, на целевой ветке можно использовать git merge --no-commit, чтобы просмотреть изменения перед коммитом. Для больших конфликтов полезно включить git config merge.conflictstyle diff3, который показывает и общего предка, что облегчает понимание. Если конфликт включает бинарные файлы, Git не может их объединить; тогда нужно вручную выбрать одну версию (git checkout --ours файл или --theirs), затем выполнить git add файл.

Как избежать повторения

  • Часто получайте изменения из главной ветки (`git pull --rebase`) перед началом крупной работы.
  • Держите изменения небольшими и сфокусированными на одной задаче; коммитьте чаще.
  • Договоритесь в команде, кто меняет какие файлы и части кода.
  • Включите `git config merge.conflictstyle diff3`, чтобы легче понимать конфликты.

Когда лучше обратиться к специалисту

Если конфликт включает десятки файлов, бинарные файлы или вы не понимаете код достаточно, чтобы безопасно объединить изменения, обратитесь в IT поддержку или к более опытному коллеге, чтобы вместе разрешить конфликт и сохранить историю.

Разработка ПО и продуктов · Приложения на заказ, SaaS и MVP за 4-8 недель

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

Что означают маркеры `<<<<<<<`, `=======` и `>>>>>>>`?

`<<<<<<< HEAD` обозначает начало вашей текущей ветки, `=======` разделяет две версии, а `>>>>>>> имя-ветки` обозначает конец части из сливаемой ветки. Все маркеры конфликта должны быть удалены, прежде чем вы отметите файл как решённый.

Могу ли я отменить слияние, если уже выполнил `git add`?

Да, `git merge --abort` работает, пока вы не завершили коммит слияния. Если вы уже создали коммит слияния и не отправили его в удалённый репозиторий, можете отменить его с помощью `git reset --hard HEAD~1`, но сначала создайте резервную ветку или копию репозитория. Если коммит уже отправлен, используйте `git revert -m 1 <hash>`.

Как разрешить конфликт в бинарном файле?

Git не может автоматически объединить бинарные файлы. Решите, какая версия правильная, и выполните `git checkout --ours файл` (ваша ветка) или `git checkout --theirs файл` (другая ветка), затем `git add файл`.

Поделиться
Не нашли решение?ИИ-помощник работает 24/7. Опишите проблему или отправьте скриншот ошибки и получите инструкцию для вашего случая.Спросить ИИ-помощника