Короткий ответ
Trunk-based development держит одну основную ветку, в которую короткоживущие фиче-ветки мержатся по многу раз в день за фиче-флагами, а Git Flow вводит отдельные долгоживущие ветки develop, release/*, hotfix/* вокруг main с более формальным процессом релизов; выбор зависит от частоты релизов, зрелости CI/CD и необходимости поддерживать несколько версий продукта одновременно.
Как это работает подробнее
в trunk-based модели интеграция происходит постоянно и мелкими порциями, что требует надёжного CI, feature flags для скрытия незавершённой функциональности и автоматических тестов перед мерджем. Git Flow с явными release-ветками удобен, когда релизы случаются редко, требуют отдельного этапа стабилизации и нужно одновременно поддерживать несколько выпущенных версий (например, библиотека с LTS-ветками).
Пример кода
git switch main
git pull --ff-only
git switch -c feature/short-lived
git add .
git commit -m "feat: add guarded change"
git rebase main
git switch main
git merge --ff-only feature/short-lived
git switch develop
git switch -c release/2.4.0
git commit --allow-empty -m "chore: prepare 2.4.0"
git switch main
git merge --no-ff release/2.4.0Что использовать на практике
- Рекомендация. команды с непрерывной доставкой (деплой по многу раз в день) почти всегда выигрывают от trunk-based подхода — он снижает объём "merge hell" и конфликтов за счёт мелких изменений. Команды, выпускающие редкие релизы с обязательным QA-этапом, или поддерживающие несколько параллельных версий продукта, чаще используют вариации Git Flow или release-веток.
Подводные камни
- Ошибка. внедрять Git Flow "по умолчанию" без необходимости поддерживать несколько версий, получая на ровном месте долгоживущие ветки с болезненными мерджами; пытаться перейти на trunk-based без базовой автоматизации тестов и feature flags, из-за чего в main начинают попадать незавершённые и ломающие изменения.