Конфликты слияния¶
Конфликт возникает, когда Git не может автоматически объединить изменения из двух веток. Обычно это происходит, если одна и та же строка кода была изменена по-разному в разных ветках.
Как выглядит конфликт¶
При попытке слияния Git остановится и сообщит о конфликте:
Auto-merging file.txt
CONFLICT (content): Merge conflict in file.txt
Automatic merge failed; fix conflicts and then commit the result.
В файле появятся маркеры конфликта:
<<<<<<< HEAD
Изменения из текущей ветки (куда сливаем)
=======
Изменения из сливаемой ветки
>>>>>>> feature-branch
Пошаговое разрешение конфликта¶
Шаг 1: Найти файлы с конфликтами¶
git status
Git покажет список файлов в состоянии "both modified".
Шаг 2: Открыть файлы и выбрать правильную версию¶
Откройте каждый файл с конфликтом в редакторе. Вы увидите маркеры <<<<<<<, ======= и >>>>>>>.
Варианты действий:
- Оставить изменения из текущей ветки (между <<<<<<< HEAD и =======).
- Оставить изменения из другой ветки (между ======= и >>>>>>>).
- Объединить оба варианта вручную.
- Написать совершенно новый код.
Удалите все маркеры конфликта после выбора решения.
Шаг 3: Добавить разрешенные файлы в индекс¶
После того как вы исправили все конфликты в файле:
git add <имя_файла>
Шаг 4: Завершить слияние¶
Когда все конфликтующие файлы добавлены:
git commit
Git предложит стандартное сообщение коммита слияния. Можно оставить его или изменить.
Примечание: В современных версиях Git при использовании
git mergeкоммит может создаться автоматически послеgit add.
Отмена слияния при конфликте¶
Если вы поняли, что зашли в тупик, или хотите начать разрешение конфликтов заново:
git merge --abort
Эта команда вернет репозиторий в состояние до начала слияния.
Инструменты для разрешения конфликтов¶
Текстовые редакторы¶
VS Code, IntelliJ IDEA, WebStorm и другие современные редакторы имеют встроенные инструменты для визуального разрешения конфликтов (кнопки "Accept Current", "Accept Incoming", "Compare").
Специализированные утилиты¶
Можно настроить внешний инструмент для слияния:
# Использовать meld (Linux)
git config --global merge.tool meld
git mergetool
# Использовать kdiff3
git config --global merge.tool kdiff3
Разрешение в пользу одной из сторон¶
Иногда нужно просто взять всю версию файла из одной ветки:
# Взять версию из текущей ветки (нашей)
git checkout --ours <файл>
git add <файл>
# Взять версию из сливаемой ветки (их)
git checkout --theirs <файл>
git add <файл>
Профилактика конфликтов¶
- Часто делайте pull из основной ветки в свою фич-ветку:
bash git pull origin main - Делайте мелкие коммиты — их легче сливать.
- Коммуницируйте с командой — договаривайтесь, кто какие файлы правит.
- Используйте модульную архитектуру, чтобы разные разработчики работали с разными файлами.