Когда git merge feat выполняется на ветке main, Git сначала
проверяет: можно ли просто «перемотать» main на верхушку feat?
Когда возможен
Когда main с момента ветвления не получала новых коммитов:
до merge:
main: A → B
\
feat: C → D
git switch main && git merge feat:
после:
main: A → B → C → D ← main "догнал" feat
feat: A → B → C → D
Никакого merge-коммита. Просто файл .git/refs/heads/main
переписывается со старого SHA на SHA коммита D.
Когда невозможен
Когда на main был хотя бы один коммит после ветвления:
main: A → B → E
\
feat: C → D
Здесь fast-forward невозможен, нужен three-way merge с merge-коммитом (см. merge).
Контроль поведения
bash
git merge feat # ff если возможен, иначе three-way
git merge --no-ff feat # всегда создаёт merge-коммит,
# даже когда ff возможен
git merge --ff-only feat # только ff; если невозможен - отказ
--no-ff- стратегия команд, которые хотят сохранять топологию: «здесь была feature-ветка». Полезно для GitFlow.--ff-only- страховка от случайных merge-коммитов. Удобно как дефолт дляpull:git config --global pull.ff only.
Подводные камни
- Fast-forward не создаёт коммит, поэтому в
git log --oneline --graphне видно, что была ветка. Если факт ветвления важен для аудита ---no-ff.- При
--ff-onlyи расхождении веток Git откажется работать - нужно явно merge или rebase, не «как-нибудь автоматически».
- При
- У
pullдефолт исторически другой; чтобы не получать случайные merge-коммиты -pull.ff = onlyилиpull.rebase = true.