Ветвление
1Что такое ветки и зачем они нужны2Слияние веток и конфликты← вы здесь3Конфликты слияния
Урок 2~12 минут

Слияние веток и конфликты

Ветки созданы, работа сделана. Теперь нужно объединить результаты. Для этого в 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 говорит: «Оба изменили это место. Реши сам, что оставить».

Как разрешить конфликт

  1. Открываешь файл с конфликтом
  2. Видишь маркеры <<<<<<<, =======, >>>>>>>
  3. Оставляешь нужный вариант (или объединяешь оба), убираешь маркеры
  4. git add имя-файла
  5. git commit
bash
# Слияние с конфликтом:
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

bash
git merge feature           # слить ветку feature в текущую
git merge --no-ff feature   # принудительно создать merge-commit (даже при fast-forward)
git merge --abort           # отменить merge, вернуться к исходному состоянию
git status                  # показывает файлы с конфликтами
git diff                    # показывает что именно конфликтует

Когда использовать --no-ff

bash
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.

Конфликт — это не ошибка, это Git говорит: 'Оба изменили одно место, реши сам'. Это нормально.
🌿
Визуализация ветокшаг 0 / 6
a1b2c3Initial commitd4e5f6Add README7g8h9iAdd login feat…mainHEAD
🎯
Миссия 1 из 4
Как слить ветку feature в текущую ветку?