linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Главы
  • How it works
  • Уроки
  • База знаний
  • Собеседование
home/git/kb/Совместная работа/merge-strategies

kb/collab ── Совместная работа ── intermediate

Стратегии merge PR (GitHub)

В GitHub три кнопки для merge PR: Create a merge commit (--no-ff, с merge-коммитом), Squash and merge (один сжатый коммит без родителя из ветки), Rebase and merge (rebase + fast-forward без merge-коммита). Команды выбирают одну для всего проекта.

view as markdownaka: merge-strategy, github-merge-buttons

Когда PR готов к merge, GitHub предлагает три стратегии - это не разные команды Git, а три способа влить ветку. На GitLab/Bitbucket варианты те же, только названия чуть отличаются.

Create a merge commit

Эквивалент git merge --no-ff feature. Создаётся merge-коммит с двумя родителями, даже если fast-forward возможен.

main:  ... → A → B → M ← merge-коммит
                  \ /
              feat: C → D

Преимущества:

  • История сохраняет факт ветвления - видно, где была feature.
  • PR откатывается одной командой: git revert -m 1 <merge-sha>.
  • Все коммиты PR попадают в main как есть.

Недостатки:

  • История захламляется merge-коммитами, особенно на активном проекте.
  • Линейная навигация по истории сложнее (git log --first-parent помогает).

Когда выбирать: большим командам с упором на аудит и откат целых PR; командам, ценящим прозрачность «откуда что».

Squash and merge

GitHub берёт все коммиты PR, сжимает в один новый коммит, добавляет в main без merge-коммита.

main:  ... → A → B → S    ← S содержит все правки из feat

Старые коммиты ветки в main не попадают (остаются в самой ветке до её удаления, потом доступны через reflog некоторое время).

Преимущества:

  • История main всегда линейная и чистая.
  • Один PR - один коммит, гранулярность совпадает с тикетами.
  • Внутренний шум PR (WIP, fix typo, address comments) не попадает в main.
  • Откат PR - обычный git revert <commit-sha>.

Недостатки:

  • Атомарные коммиты внутри PR (если автор их вычистил) теряются.
  • Для bisect внутри фичи приходится ходить в саму ветку, в main - только один коммит.
    • Связь между коммитом в main и веткой PR - только через сообщение коммита (если автоматически добавлено (#123)).

Когда выбирать: небольшим командам, которым важна чистая линейная история и где авторы PR'ов не дисциплинированы в коммитах. По опыту многих коммерческих проектов это наиболее частый дефолт - но в больших организациях со строгим аудитом нередко предпочитают merge-commit (см. ниже).

Rebase and merge

Все коммиты PR перебазируются поверх main (новые SHA), потом fast-forward в main. Никакого merge-коммита.

main:  ... → A → B → C' → D'    ← C' и D' - переписанные коммиты feat

Преимущества:

  • История линейная - как у squash.
  • Сохраняет атомарные коммиты внутри PR - как у merge commit.
  • Bisect работает на всю историю включая внутренности PR'а.

Недостатки:

  • SHA коммитов отличаются от тех, что были в ветке (после rebase). Если ссылались на SHA из feature до merge - ссылки сломаются.
    • Требует от автора PR чистых коммитов. Если коммиты - «WIP», «fix»
    • они так и попадут в main по одному, что хуже, чем squash.
  • Связь «коммит → PR» теряется, нужно искать по сообщению.

Когда выбирать: командам, которые готовы вкладываться в чистоту коммитов через interactive rebase, и где важна одновременно линейная история и сохранение атомарных коммитов. (Заметь: ядро Linux формально не использует GitHub-кнопку «Rebase and merge» - у них своя email/maintainer-tree модель. Принцип «линейная история + атомарные коммиты» там тот же, способ интеграции другой.)

Сравнение

СтратегияMerge-коммитСохраняет коммиты PRИстория
Merge commitдадаразвилки
Squash and mergeнетнет (один новый)линейная
Rebase and mergeнетда (новые SHA)линейная

Какая стратегия для какой команды

Прагматичные правила:

  • Стартап / маленькая команда / нет дисциплины коммитов → Squash and merge. Покрывает большинство сценариев, никого не учит rebase'у, история всегда чистая.
  • Большая компания / много команд / важен аудит → Merge commit. Возможность откатить весь PR одним revert ценнее, чем линейная история.
    • Open source / профессионалы / атомарные коммиты - норма → Rebase and merge. Сохраняет качественную внутреннюю историю PR.

Главное - выбрать одну для проекта. Смесь стилей в одной истории читается плохо: то развилки, то линейность, то один коммит на PR, то десять.

Настройка в GitHub

Settings → General → Pull Requests → Merge button. Можно разрешить одну, две или все три кнопки. Лучше оставить только выбранную стратегию - меньше путаницы, меньше «сегодня я squash, завтра rebase».

Дополнительные настройки:

  • Always suggest updating pull request branches - при доступном update предлагать кнопку обновить ветку на свежий main.
    • Allow auto-merge - PR смержится автоматически, как только подойдут условия (approve + CI).
    • Automatically delete head branches - удалять ветку после merge. Включить.

Подводные камни

  • Squash + branch protection «require linear history» не конфликтуют. Squash даёт линейную историю по определению.
  • Squash и сохранение метаданных. GitHub автоматически добавляет в сообщение (#123) со ссылкой на PR. Полезно для навигации; проверь, что включено в настройках.
  • Rebase и большие PR. На PR с 30 коммитами rebase может спровоцировать серию конфликтов (по разу за коммит). Если main активный - лучше squash, чтобы конфликт разрешать раз.

§ см. также

  • mergegit mergeСливает другую ветку в текущую. Делает либо fast-forward (двигает указатель), либо создаёт merge-коммит с двумя родителями. При пересекающихся изменениях возможны конфликты.
  • rebasegit rebaseПереписывает коммиты ветки, делая их потомками другого коммита. Создаёт новые SHA, история становится линейной. Безопасен только для веток, которые ещё никто, кроме автора, не видел.
  • pull-requestPull Request (PR)Запрос на влитие ветки в основную с прохождением ревью и CI. На GitHub/GitLab/Bitbucket - стандартный механизм совместной работы. Технически это не команда Git, а функция хостинга, надстроенная над веткой и серией коммитов.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки