Git Flow, GitHub Flow и trunk-based: какой Git workflow выбрать
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/* | develop | develop | Разработка новой функции |
| release/* | develop | main и develop | Стабилизация версии: багфиксы, номер версии, документация |
| hotfix/* | main | main и 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. Правила умещаются в несколько пунктов:
- main всегда в рабочем состоянии и готов к деплою.
- Любая работа — в ветке от main с говорящим именем.
- Ветку регулярно пушат и открывают pull request (merge request) для обсуждения.
- После ревью и зелёного CI ветку сливают в main.
- Слитое в 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 Flow | GitHub Flow | Trunk-based |
|---|---|---|---|
| Долгоживущие ветки | main и develop | main | main (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 с нуля до уверенного разработчика».
Перейти к курсу