Вы сделали git merge или git pull, и терминал выдал зловещее сообщение «CONFLICT (content): Merge conflict in…»? Не паникуйте. Конфликт слияния — это не ошибка и не поломка репозитория. Это штатная ситуация, когда Git не может автоматически объединить изменения из двух веток.
В этом руководстве мы разберём, как читать маркеры конфликтов,.resolve их вручную и через IDE, а также как предотвратить подобные ситуации в будущем.
Почему возникает merge conflict?
Конфликт происходит только в одном случае: две ветки изменили одну и ту же строку одного и того же файла. Git не знает, чью версию оставить, и передаёт решение вам.
- Вы и коллега отредактировали одну функцию параллельно
- Вы изменили строку, которая была удалена в другой ветке
- Два коммита модифицировали один и тот же блок кода по-разному
Важно: конфликт возникает только при слиянии (merge), ребейзе (rebase) или cherry-pick. Обычные коммиты никогда не вызывают конфликтов.
Шаг 1: Чтение маркеров конфликта
Когда Git обнаруживает конфликт, он помечает проблемные участки специальными маркерами прямо в файле:
<<<<<<< HEAD
ваш текущий код (ветка, в которую сливаете)
=======
входящий код (ветка, которую сливаете)
>>>>>>> feature-branchЧто означает каждый маркер:
<<<<<<< HEAD— начало вашего текущего кода (ветка, на которой вы находитесь)=======— разделитель между двумя версиями>>>>>>> feature-branch— конец входящего кода (ветка, которую вы сливаете)
Ваша задача — удалить все маркеры и оставить только правильный код. Иногда нужно сохранить обе версии, иногда — выбрать одну, иногда — написать новую.
Шаг 2: Разрешение конфликта вручную
Самый надёжный способ — открыть файл в любом текстовом редакторе и решить конфликт руками.
Пример разрешения:
Было (конфликт):
<<<<<<< HEAD
$timeout = 30;
=======
$timeout = 60;
>>>>>>> feature/update-timeoutСтало (после решения — выбираем большее значение):
$timeout = 60;После редактирования сохраните файл и выполните:
# Помечаем конфликт как решённый
git add <имя_файла>
# Завершаем слияние
git commit -m "Resolve merge conflict in config.php"Шаг 3: Разрешение через IDE (рекомендуемый способ)
Современные IDE показывают конфликты визуально и позволяют решать их кликами. Это быстрее и безопаснее ручного редактирования.
VS Code:
- Откройте файл с конфликтом
- Над каждым блоком появятся кнопки: Accept Current Change, Accept Incoming Change, Accept Both Changes, Compare Changes
- Выберите нужный вариант одним кликом
- Сохраните файл и сделайте коммит
PhpStorm / IntelliJ IDEA:
- При конфликте появится диалог Conflicts
- Нажмите Merge — откроется трёхпанельный инструмент
- Левая панель — ваша версия, правая — входящая, центральная — результат
- Переносите нужные блоки стрелками в центральную панель
- Нажмите Apply
Шаг 4: Что делать, если всё пошло не так
Если вы запутались в конфликтах и хотите начать заново, можно безопасно отменить слияние:
# Полная отмена merge — возвращает состояние ДО команды git merge
git merge --abort
# Для rebase:
git rebase --abortЭта команда работает только пока слияние не завершено (нет финального коммита). После коммита используйте git reset --hard HEAD~1, но будьте осторожны — это необратимо.
Лучшие практики предотвращения конфликтов
- Сливайте основную ветку в свою регулярно (минимум раз в день)
- Работайте над разными файлами, когда это возможно
- Разбивайте большие задачи на мелкие PR/MR
- Коммитьте часто — маленькие коммиты легче сливать
- Общайтесь с командой перед изменением общих файлов
- Используйте
git pull --rebaseвместо обычного pull для линейной истории
Что делать, если конфликты возникают постоянно?
Файл меняется слишком часто
Если один файл вызывает конфликты ежедневно — это архитектурный запах. Рассмотрите возможность разделения файла на модули, выделения конфигурации в отдельный файл или пересмотра ответственности компонентов.
Команда работает без координации
Частые конфликты — сигнал о проблемах в процессе. Внедрите code review, планирование спринтов и согласование зон ответственности. Технические средства не заменят коммуникацию.
Слишком длинные feature-ветки
Если ветка живёт недели без слияния с основной, конфликты неизбежны. Используйте trunk-based development или сокращайте цикл разработки до 1-3 дней.