Слияние веток и конфликты
Ветки созданы, работа сделана. Теперь нужно объединить результаты. Для этого в Git есть git merge.
Два вида слияния
Fast-forward (без merge-коммита)
Если ветка feature просто ушла вперёд от main, а сам main не двигался — Git делает fast-forward: просто переставляет указатель main на HEAD feature.
До:
main → C1 → C2 → C3
↑
feature → C4 → C5
После git merge feature:
main → C1 → C2 → C3 → C4 → C5
↑
feature
Никакого лишнего коммита. История линейная.
Merge commit (три-точечный merge)
Если main тоже двигался пока ты работал в feature — ветки разошлись. Тогда Git создаёт merge-коммит с двумя родителями.
main: C1 → C2 → C3 → C5 → C6 (merge)
↓ ↑
feature: C3 → C4 ——┘
Посмотри на симуляцию — именно этот сценарий там показан.
Конфликты
Git не умеет телепатировать. Если две ветки изменили одни и те же строки одного файла — возникает конфликт.
<<<<<<< HEAD
Привет, мир!
=======
Hello, world!
>>>>>>> feature
Это не ошибка — это Git говорит: «Оба изменили это место. Реши сам, что оставить».
Как разрешить конфликт
- Открываешь файл с конфликтом
- Видишь маркеры
<<<<<<<,=======,>>>>>>> - Оставляешь нужный вариант (или объединяешь оба), убираешь маркеры
git add имя-файлаgit commit
# Слияние с конфликтом:
git switch main
git merge feature
# Auto-merging index.html
# CONFLICT (content): Merge conflict in index.html
# Открываешь файл, правишь, сохраняешь
git add index.html
git commit -m "merge: feature into main"Полезные команды при merge
git merge feature # слить ветку feature в текущую
git merge --no-ff feature # принудительно создать merge-commit (даже при fast-forward)
git merge --abort # отменить merge, вернуться к исходному состоянию
git status # показывает файлы с конфликтами
git diff # показывает что именно конфликтуетКогда использовать --no-ff
git merge --no-ff feature -m "feat: добавил профиль пользователя"Флаг --no-ff создаёт merge-коммит даже при fast-forward. Зачем?
Чтобы в истории было видно, что это была отдельная задача. Без флага история выглядит линейной — и непонятно, где заканчивается одна фича и начинается другая. С --no-ff — в истории явно видны «пакеты» изменений.
В командных проектах обычно используют --no-ff или squash-merge через Pull Request.
Советы
- Мержь часто, мержь рано. Чем дольше ветка живёт отдельно — тем больше конфликтов накапливается.
- Перед merge обнови main.
git pull origin main— потом merge. Так конфликты ты решаешь локально, а не на сервере. - Конфликты — это нормально. Даже senior разработчики регулярно их встречают. Страшно только первые пару раз.
В следующем модуле — удалённые репозитории: push, pull, fetch и работа с GitHub.