Ветвление
1Что такое ветки и зачем они нужны2Слияние веток и конфликты3Конфликты слияния4Стратегии слияния: fast-forward, no-ff, squash← вы здесь5Detached HEAD: что это и как исправить
📖 Полная статья по теме →
Урок 4~12 минут

Стратегии слияния: fast-forward, no-ff, squash

Три способа сделать git merge — и у каждого разная история коммитов в результате.

Fast-forward merge

Когда у main нет новых коммитов после того как ответвилась feature, Git просто перемещает указатель:

До:
main:    A─B
              \
feature:       C─D─E

После fast-forward:
main:    A─B─C─D─E
                   ↑ просто переместили указатель
bash
git switch main
git merge feature        # fast-forward по умолчанию

История выглядит линейной — как будто feature и не было. Хорошо для небольших правок.

No-fast-forward (--no-ff)

Всегда создаёт merge-коммит, даже если возможен fast-forward:

После --no-ff:
main:    A─B──────────M
              \       ↑ merge-коммит
feature:       C─D─E─╯
bash
git merge feature --no-ff

В истории видно что была отдельная ветка. Удобно для аудита — сразу ясно что это была одна фича.

Squash merge

Сжимает все коммиты ветки в один:

После squash:
main:    A─B─S
              ↑ один коммит со всеми изменениями feature

feature: A─B─C─D─E (остаётся без изменений)
bash
git merge feature --squash
git commit -m "feat: полное описание фичи"

Squash не создаёт merge-коммит автоматически — нужен явный git commit. Ветка feature при этом не удаляется и не сливается технически.

Попробуй в симуляции

Выбери стратегию и посмотри как изменится граф истории.

Сравнение

Fast-forwardNo-ffSquash
Merge-коммит
История веткиНе виднаВиднаНе видна
Количество коммитовВсеВсе + mergeОдин
ЧитаемостьЛинейнаяСтруктурнаяЧистая

Когда что использовать

Fast-forward — мелкие правки, hotfix, один человек
No-ff — когда важно сохранить факт наличия ветки (feature ветки в GitFlow)
Squash — большие фичи с черновыми коммитами ("fix fix fix"), pull requests

Настройка по умолчанию

bash
# Всегда no-ff для конкретного репозитория
git config merge.ff false
 
# Глобально
git config --global merge.ff false
squash merge — лучший выбор для фич-веток: вся работа становится одним чистым коммитом в main, история остаётся читаемой.
git merge feature
Указатель main просто перемещается вперёд. Никаких лишних коммитов.
main
A
B
C
D
E
feature
A
B
C
D
E
Merge-коммит
Fast-forward
No
Squash
История ветки
Fast-forward
No
Squash
Чистая история
Fast-forward~
No
Squash
УГЛУБЛЁННОЕ ЧТЕНИЕ
Полная статья: Ветвление
Теория, примеры и разбор темы в одном месте