Сравнение

Git Flow, GitHub Flow и trunk-based: какой Git workflow выбрать

Обновлено: · Skillaria.Top

Git Flow — модель ветвления с долгоживущими ветками main и develop и вспомогательными feature, release и hotfix; она подходит для продуктов с плановыми версиями. Для веб-сервисов с частыми деплоями обычно проще GitHub Flow (короткие ветки от main и pull request) или trunk-based development с feature flags.

Что такое Git workflow и почему его выбор важен

Git workflow — договорённость команды о том, какие ветки существуют, откуда они создаются, куда сливаются и что считается готовым к релизу. Сам Git ничего из этого не навязывает, поэтому без договорённости каждый работает по-своему, и через месяц в репозитории десятки веток, непонятно, что задеплоено, а слияния превращаются в многочасовые конфликты.

Самые известные модели — Git Flow, GitHub Flow (вариант Feature Branch Workflow) и trunk-based development. Это не «старое и новое», а инструменты под разные условия: как часто вы выпускаете релизы, сколько версий продукта поддерживаете одновременно и насколько развиты автотесты.

Git Flow: модель с ветками develop и release

Git Flow описал Винсент Дриссен в 2010 году. Модель строится на двух долгоживущих ветках:

  • main (в старых проектах — master) — только выпущенный код, каждый коммит здесь соответствует релизу и помечается тегом;
  • develop — интеграционная ветка, куда сливаются готовые фичи для следующего релиза.

И трёх типах временных веток:

ВеткаСоздаётся отСливается вЗачем
feature/*developdevelopРазработка новой функции
release/*developmain и developСтабилизация версии: багфиксы, номер версии, документация
hotfix/*mainmain и developСрочное исправление в выпущенной версии

Git Flow на чистом Git

Цикл одной фичи и релиза выглядит так:

# фича
git switch develop
git switch -c feature/cart-discounts
# ... коммиты ...
git switch develop
git merge --no-ff feature/cart-discounts
git branch -d feature/cart-discounts

# релиз
git switch -c release/1.4.0 develop
# ... правки версии и багфиксы ...
git switch main
git merge --no-ff release/1.4.0
git tag -a v1.4.0 -m "Release 1.4.0"
git switch develop
git merge --no-ff release/1.4.0
git branch -d release/1.4.0

Флаг --no-ff принципиален для этой модели: он создаёт merge-коммит даже там, где возможна перемотка, и в истории остаётся видно, какие коммиты относились к одной фиче или релизу.

Расширение git-flow

Чтобы не набирать эти последовательности руками, есть утилита git-flow (сейчас обычно ставят поддерживаемый форк, в пакетных менеджерах он часто называется git-flow-avh). Она добавляет подкоманды:

git flow init -d
git flow feature start cart-discounts
git flow feature finish cart-discounts
git flow release start 1.4.0
git flow release finish 1.4.0
git flow hotfix start 1.4.1
git flow hotfix finish 1.4.1

git flow init спрашивает имена веток и префиксов (с -d принимает значения по умолчанию), а команды finish выполняют все нужные слияния, ставят тег и удаляют временную ветку. Многие GUI-клиенты Git тоже умеют работать по Git Flow через кнопки.

Плюсы и минусы Git Flow

Плюсы: чёткая структура, понятный статус кода (main — то, что у клиентов; develop — следующая версия), отдельная фаза стабилизации релиза, удобная поддержка хотфиксов. Это хорошо ложится на мобильные приложения, коробочный софт, библиотеки и прошивки — там, где релиз проходит ревью магазина приложений или устанавливается у клиента.

Минусы: много веток и слияний, долгоживущие feature-ветки накапливают расхождения с develop, а двойные слияния release и hotfix легко забыть. Для веб-сервиса, который деплоится несколько раз в день, release-ветки становятся бюрократией. Сам автор модели в 2020 году добавил к своей статье примечание: для непрерывно поставляемого ПО стоит смотреть на более простые подходы вроде GitHub Flow.

GitHub Flow: короткие ветки и pull request

GitHub Flow — облегчённая версия Feature Branch Workflow. Правила умещаются в несколько пунктов:

  1. main всегда в рабочем состоянии и готов к деплою.
  2. Любая работа — в ветке от main с говорящим именем.
  3. Ветку регулярно пушат и открывают pull request (merge request) для обсуждения.
  4. После ревью и зелёного CI ветку сливают в main.
  5. Слитое в main деплоится сразу.
git switch main
git pull
git switch -c feature/new-payment
# ... коммиты с понятными сообщениями ...
git push -u origin feature/new-payment
# открываем pull request, проходим ревью и CI, сливаем в main

Плюсы: одна долгоживущая ветка, минимум правил, быстрый путь от идеи до продакшена, естественное код-ревью. Минусы: нет встроенного места для поддержки нескольких версий и для стабилизации перед релизом, а без хороших автотестов «main всегда готов» остаётся лишь пожеланием.

Похожий подход с дополнительными ветками окружений (например, staging и production) иногда называют GitLab Flow. Он полезен, когда деплой в продакшен происходит не мгновенно, а по расписанию или после ручной проверки.

Trunk-based development

В trunk-based development все разработчики интегрируют изменения в одну ветку (trunk, то есть main) часто — минимум раз в день. Ветки если и есть, то живут часы, а не недели. Незаконченная функциональность попадает в main, но скрыта за feature flag:

if (featureFlags.isEnabled("new-checkout", user)) {
    renderNewCheckout();
} else {
    renderOldCheckout();
}

Главное преимущество — почти полное отсутствие тяжёлых конфликтов: изменения маленькие и сливаются, пока все помнят контекст. Модель поддерживает непрерывную интеграцию в буквальном смысле и хорошо подходит зрелым командам с быстрым CI и высоким покрытием тестами. Релизные ветки допускаются, но их создают от trunk непосредственно перед выпуском, и исправления вносят сначала в trunk, а потом переносят через cherry-pick.

Минусы: требуется дисциплина и инфраструктура — быстрые тесты, флаги, мониторинг. Новичку страшно коммитить в main каждый день, а слабый CI превращает trunk в постоянно сломанную ветку. Флаги тоже нужно вовремя удалять, иначе код обрастает мёртвыми ветвлениями.

Сравнение Git Flow, GitHub Flow и trunk-based

КритерийGit FlowGitHub FlowTrunk-based
Долгоживущие веткиmain и developmainmain (trunk)
Жизнь feature-веткиДни и неделиДниЧасы или без веток
Частота релизовПлановые версииПо мере слиянияНепрерывно
Поддержка нескольких версийДа, через теги и hotfixНеудобноЧерез release-ветки
Требования к CI и тестамСредниеВысокиеОчень высокие
Риск больших конфликтовВысокийСреднийНизкий
Порог входаНужно выучить правилаМинимальныйНужна культура и feature flags
Типичный проектМобильное приложение, библиотека, коробкаВеб-сервис, open source, стартапКрупный продукт с частыми деплоями

Как выбрать git workflow для команды

Ответьте на несколько вопросов:

  • Нужно ли поддерживать несколько выпущенных версий? Если клиенты сидят на 2.x и 3.x и обеим нужны исправления — Git Flow или trunk-based с release-ветками.
  • Как часто вы деплоите? Раз в квартал — Git Flow не будет мешать. Каждый день — выбирайте GitHub Flow или trunk-based.
  • Насколько вы доверяете тестам? Если CI медленный и покрытие слабое, начинайте с GitHub Flow с обязательным ревью и постепенно укорачивайте ветки.
  • Какой размер и опыт команды? Небольшой команде и новичкам проще всего GitHub Flow: одно правило «main всегда рабочий» и pull request на всё.

Практический совет: не берите Git Flow «потому что так принято». Начните с самого простого процесса, который решает ваши задачи, и усложняйте его, только когда появится конкретная боль — например, понадобится фаза стабилизации или поддержка старых версий.

Правила, которые работают в любом workflow

  • Защитите main на сервере: запрет прямого push, обязательные ревью и зелёный CI перед слиянием.
  • Договоритесь об именах веток: feature/, fix/, hotfix/ плюс номер задачи.
  • Держите ветки короткими: чем дольше живёт ветка, тем больнее её сливать. Регулярно подтягивайте main в свою ветку через merge или rebase.
  • Выберите стратегию слияния pull request (merge commit, squash или rebase) и используйте её единообразно.
  • Помечайте релизы аннотированными тегами по семантическому версионированию.

Хотфикс в каждой модели: один баг, три процесса

Разница между подходами лучше всего видна на срочном исправлении в продакшене.

В Git Flow создаётся hotfix/1.4.1 от main, после исправления ветка сливается в main с тегом v1.4.1 и обязательно в develop (или в текущую release-ветку, если она есть). Забытое второе слияние — классическая ошибка: в следующем релизе баг «возвращается».

git switch -c hotfix/1.4.1 main
git commit -am "Исправить расчёт скидки"
git switch main && git merge --no-ff hotfix/1.4.1
git tag -a v1.4.1 -m "Hotfix 1.4.1"
git switch develop && git merge --no-ff hotfix/1.4.1

В GitHub Flow хотфикс — обычная короткая ветка от main с pull request, которому дают приоритет в ревью. После слияния он уходит в продакшен тем же автоматическим деплоем, отдельного процесса нет.

В trunk-based исправление сначала коммитится в trunk, а если в продакшене работает release-ветка, коммит переносится в неё через git cherry-pick -x <хеш>. Флаг -x добавляет в сообщение ссылку на исходный коммит, чтобы связь была видна в истории. Если же проблема в новой функции, часто достаточно выключить её feature flag, не трогая код вовсе.

Как ответить на собеседовании «какой Git workflow вы использовали»

Интервьюер проверяет не знание названий, а понимание компромиссов. Хороший ответ: назвать модель, описать, как в ней устроены ветки и ревью, и объяснить, почему она подходила проекту. Например: «Мы использовали GitHub Flow: ветки от main, pull request с обязательным ревью и CI, после слияния автоматический деплой. Git Flow не брали, потому что релизились по несколько раз в неделю и release-ветки только тормозили бы». Бонус — рассказать, что бы вы поменяли, если бы процесс рос.

Итог

Git Flow — строгая модель с ветками develop, release и hotfix, хорошая для продуктов с плановыми версиями и поддержкой нескольких релизов. GitHub Flow проще и подходит большинству веб-проектов, а trunk-based development даёт максимальную скорость, но требует зрелого CI и feature flags. Выбирайте git workflow по частоте релизов и качеству тестов, а не по моде. Все три подхода с их командами и типичными ошибками мы разбираем на практике в курсе по Git.

Частые вопросы

Git Flow устарел?

Нет, но его область применения сузилась. Для веб-сервисов с непрерывным деплоем он избыточен, а для мобильных приложений, библиотек и коробочного ПО по-прежнему удобен.

Нужна ли ветка develop, если релизы частые?

Обычно нет: develop дублирует main и добавляет лишнее слияние. При частых релизах достаточно main и коротких feature-веток.

Можно ли использовать rebase в Git Flow?

Можно подтягивать develop в свою незапушенную или личную feature-ветку через rebase, но финальные слияния в develop и main в классической модели делают через merge --no-ff, чтобы сохранить структуру истории.

Чем feature flag лучше долгой feature-ветки?

Код интегрируется в main сразу и не расходится с остальной кодовой базой, а включение функции становится отдельным решением, которое можно откатить без отката кода.

Как перейти с Git Flow на GitHub Flow?

Завершите текущие релизы, слейте develop в main, перенастройте CI на деплой из main и удалите develop. Новые ветки создавайте только от main.

Разберите тему на видео

Эта тема подробно разобрана с практикой в курсе «Git с нуля до уверенного разработчика».

Перейти к курсу