how/история
«Слил ветку» - но как? Без merge-коммита или с ним? Что значит «branches diverged» и зачем существует --no-ff. На графе коммитов всё видно за секунду.
git merge feat может закончиться двумя совершенно
разными способами, и от того, какой случится, зависит, как потом
выглядит история.
Жми ▶ - посмотрим на пять сценариев. Тот же git merge feat ведёт
себя по-разному в зависимости от того, что было на main.
Начальное состояние:
main: A
↘
feat: A → B → C
На main только коммит A. На feat - A → B → C. Главное: на main
после ветвления нет новых коммитов. Это значит, что верхушка main
(A) - предок верхушки feat (C).
В Git'е это и есть условие для fast-forward: целевая ветка отстаёт по прямой линии от исходной.
итого
Что важно запомнить:
refs/heads/main на SHA верхушки feat.
Новых коммитов не появляется, история остаётся линейной, факт
ветвления пропадает.git merge --no-ff feat принуждает создать merge-коммит, даже
когда FF возможен. Полезно, если важно видеть в логе «здесь была
ветка feat». На GitHub-flow PR'ы мерджатся именно так.git merge --ff-only feat - наоборот: «если FF не получается, не
делай ничего». Защита от случайных merge-коммитов в git pull-ах
(см. pull.ff = only).git rebase feat onto main - третий путь: перенести коммиты feat
поверх main так, чтобы FF снова стал возможен. История остаётся
линейной, но SHA коммитов меняются (тот же diff, новый родитель =
новый хеш). Поэтому ребейзить можно только то, что ещё никто не
утянул.Что выбирать на практике:
--no-ff (стандарт PR-форджей).rebase (либо
git pull --rebase).ff вполне ок, история чище.