Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Чим відрізняються fast-forward, злиття з --no-ff і squash-злиття?

Злити гілку feature у main можна трьома способами, і від вибору залежить вигляд історії.

Fast-forward - можливий, коли main не просунувся після створення feature. Git просто пересуває вказівник main на останній коміт feature, нового коміту не створюється:

до:     main ── A                після:  A ── B ── C   (main, feature)
                 \
                  B ── C (feature)

Історія лінійна, але факт існування гілки зникає: не видно, які коміти були однією задачею.

--no-ff - завжди створює коміт злиття, навіть коли fast-forward можливий:

git merge --no-ff feature
A ────────── M   (main)
 \          /
  B ── C ──      (feature)

Видно межі задачі; відкотити всю функціональність можна одним git revert -m 1 M. Ціна - більше комітів злиття в історії.

Squash - усі зміни гілки стають одним новим комітом в main:

git merge --squash feature
git commit -m "Add invoice export"

Історія main чиста: одна задача - один коміт. Але:

  • проміжні коміти гілки в main не потрапляють - деталізація для git bisect і blame втрачається;
  • Git не вважає feature злитою (git branch --merged її не покаже), а git branch -d feature відмовиться її видаляти;
  • якщо продовжити роботу в тій самій гілці, наступний squash може дати конфлікти з уже злитими змінами.

Порівняння:

Fast-forward --no-ff Squash
коміт злиття ні так ні
проміжні коміти в main так так ні
межі задачі видно ні так так (один коміт)

Налаштування: git config merge.ff only дозволяє лише fast-forward (злиття впаде, якщо воно неможливе), pull.ff only - те саме для git pull. На GitHub і GitLab спосіб злиття pull request обирається в налаштуваннях репозиторію.

Докладніше в документації: git merge: fast-forward

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання