Урок 04

Merge и разрешение конфликтов

Что такое merge

Merge — слияние одной ветки в другую. Изменения из feature попадают в main.

Простой merge

git switch main
git merge feature-login

Если в main не было изменений — получится fast-forward: main просто перескочит на последний коммит feature.

Три вида merge

Fast-forward

main:    A---B
feature:       C---D
                ↓
main:    A---B---C---D

Ничего не сливается, просто указатель двигается вперёд.

Recursive merge (3-way)

main:    A---B---E
feature:       C---D
                ↓
main:    A---B---E---M
              \     /
               C---D

Создаётся merge-коммит M, объединяющий две линии.

Squash merge

Все коммиты из feature сжимаются в один и попадают в main:

main:    A---B---E---S
                    ↑
           (C+D сжаты в один S)

Плюс: чистая история в main. Минус: теряются отдельные коммиты.

Способы:

git merge --squash feature-login
git commit -m "feat: добавить авторизацию"

Отмена merge

git merge --abort            # если merge в процессе
git revert -m 1 <merge-sha>  # если merge уже сделан

Конфликты

Конфликт возникает, когда в двух ветках изменены одни и те же строки.

Пример:

git switch main
git merge feature-login
# CONFLICT (content): Merge conflict in app/User.php
# Automatic merge failed; fix conflicts and then commit the result.

Как выглядит конфликт

Открой файл — увидишь:

public function getName()
{
<<<<<<< HEAD
    return $this->first_name;
=======
    return $this->first_name . ' ' . $this->last_name;
>>>>>>> feature-login
}

Разбор:

  • Между <<<<<<< HEAD и ======= — твоя версия
  • Между ======= и >>>>>>> feature-login — версия из feature

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

1. Открой файл.

2. Оставь нужную версию. Обычно комбинируешь обе:

public function getName()
{
    return $this->first_name . ' ' . $this->last_name;
}

3. Удали маркеры <<<<<<<, =======, >>>>>>>.

4. Добавь в staging:

git add app/User.php

5. Заверши merge:

git commit

Git автоматически подставит сообщение.

Просмотр конфликтов

git status                   # покажет файлы с конфликтами
git diff                     # покажет что конфликтует

Инструменты

VS Code подсвечивает конфликты и даёт кнопки:

  • Accept Current — оставить твою версию
  • Accept Incoming — оставить входящую
  • Accept Both — объединить

PHPStorm — то же самое, плюс толковый 3-way merge tool.

Стратегия: не накапливать конфликты

Правила:

  1. Часто мержи main в свою ветку:
git switch main
git pull
git switch feature/user-profile
git merge main

Маленькие конфликты решаются за минуту. Большие — за час.

  1. Не работай долго в одной ветке. Идеально — 1-3 дня.

  2. Не рефактори чужие файлы без согласования. Иначе конфликты со всеми.

  3. Один PR = одна задача. Не смешивай «добавил фичу + починил 5 багов + переформатировал код».

Итог

Merge — базовая операция. Конфликты — норма. Решай их сразу, не откладывай.

Дальше — rebase vs merge.