Слияние веток: merge, fast-forward и merge-коммит
Соединяем работу из разных веток воедино и разбираемся в двух видах слияния.
Слияние (merge) — объединение изменений из одной ветки в другую.
Как выполнить merge
Главное правило: вы переключаетесь на ветку, в которую хотите влить изменения, и затем сливаете в неё другую ветку. Чтобы влить feature в main:
git switch main
git merge featureЗвучит контринтуитивно, но запомните: «куда вливаем — там и стоим».
Fast-forward: просто двигаем указатель
Если в main не было новых коммитов с момента создания feature, git делает fast-forward: ему достаточно сдвинуть указатель main вперёд на последний коммит feature. Новый коммит не создаётся, история остаётся линейной.
Вывод:
Updating 9f8e7d6..a1b2c3d Fast-forward login.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
Merge-коммит: когда история разошлась
Если за время работы над feature в main тоже появились коммиты, истории разошлись. Простым сдвигом указателя не обойтись — git создаёт особый merge-коммит с двумя родителями, который объединяет обе линии истории.
Вывод:
Merge made by the 'ort' strategy. search.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
| Тип | Когда | Результат |
| Fast-forward | в целевой ветке не было новых коммитов | указатель просто сдвигается, новый коммит не создаётся |
| Merge-коммит | истории разошлись | создаётся коммит с двумя родителями |
Управляем поведением
Иногда merge-коммит хотят создать всегда — чтобы в истории было явно видно факт слияния ветки:
git merge --no-ff featureА флаг --ff-only, наоборот, разрешает слияние только если оно возможно fast-forward, иначе откажет. Это удобно, чтобы держать историю линейной.
После слияния
Влитую ветку обычно удаляют, чтобы не захламлять список:
git branch -d featureОткуда у merge-коммита два родителя
Обычный коммит ссылается на один предыдущий — своего родителя. Merge-коммит особенный: у него два родителя — последний коммит каждой из сливаемых веток. Именно так git «сшивает» две разошедшиеся линии истории в одну. Если позже посмотреть историю с графом (git log --graph), вы увидите, как две ветки расходятся, а потом снова сходятся в merge-коммите.
Линейная история или явные слияния
У команд разный вкус к виду истории. Одни любят, когда каждое слияние ветки видно явным merge-коммитом — так нагляднее, какая фича когда влилась; для этого используют --no-ff. Другие предпочитают плоскую линейную историю без «развилок» — её добиваются через rebase (последний раздел курса). Оба подхода рабочие; главное — договориться внутри команды и придерживаться одного.
Итог
- Стойте на ветке-получателе, затем
git merge <ветка-источник>. - Fast-forward просто двигает указатель, если история не расходилась.
- Merge-коммит с двумя родителями создаётся, когда истории разошлись.