open atlas
↑ К треку
Git: от нуля до сеньора GIT · 06 · 04

Trunk-based development

Trunk-based development: все часто интегрируют в один trunk (main) через очень короткоживущие ветки, а незавершённые фичи спрятаны за feature-флагами, не на длинных ветках. Нужны мощный CI и флаги; релизные ветки нарезаются из trunk. Так крупные организации избегают ада слияний.

GIT Middle ◷ 17 min
Уровень
ОсновыJuniorMiddleSenior

На масштабе Google — тысячи инженеров в одном репозитории — долгоживущие ветки не просто неудобны, они катастрофичны: ветка, открытая две недели против кодовой базы, которую меняют тысячи людей, превращается в неслияемое месиво. Workflow, который это решает, — trunk-based development (TBD), и его правило звучит почти безрассудно: все коммитят в одну ветку, всё время, и никто не держит ветку открытой долго. Это то, что реально применяет большинство организаций масштаба FAANG, и это логический конец принципа «держи ветки короткими».

К концу этого урока ты сможешь объяснить, как TBD интегрирует работу непрерывно без ада слияний, почему feature-флаги не опциональны, а несущие, и как версионные релизы всё равно происходят из единственного trunk.

Цель

После этого урока ты сможешь описать однотранковую модель trunk-based development, объяснить, почему она опирается на feature-флаги и сильный CI, и показать, как релизные ветки, нарезанные из trunk, дают версионирование без повторного ввода долгоживущих веток разработки.

1

Все интегрируют в один trunk — main — непрерывно, много раз в день. Непрерывная интеграция в исходном, буквальном смысле означает именно это: каждый разработчик сливает свою работу в общий trunk минимум раз в день, часто несколько раз. Trunk — единственный источник истины, а разрыв между «код написан» и «код на trunk» измеряется часами. Причина математическая: расхождение между веткой и trunk растёт со временем, поэтому, если каждое изменение интегрируется за часы, расхождение — а значит, и конфликты слияния — остаётся крошечным. TBD бьёт по аду слияний в корне, вообще не давая двум линиям работы разойтись.

2

Работа происходит в очень короткоживущих ветках или небольших прямых коммитах. Ветки в TBD живут часы, редко больше дня. Многие команды используют ветку ровно столько, чтобы прогнать CI и получить быстрое ревью PR:

git checkout main
git pull
git checkout -b fix-rate-limit-header
# одно небольшое, сфокусированное изменение ...
git push -u origin fix-rate-limit-header
# быстрое ревью + зелёный CI, слияние в тот же день, удаление ветки

Меньшие организации, практикующие TBD, иногда коммитят прямо в trunk для тривиальных изменений (с CI, гейтящим пуш). Так или иначе, единица работы — маленькая: изменение, которое можно закончить, отревьюить и интегрировать в тот же день. Большие фичи делают не на больших ветках — их разбивают на маленькие инкременты, каждый из которых приземляется на trunk.

3

Незавершённые фичи слиты, но спрятаны за feature-флагами. Это несущая идея. Если фича занимает три недели, ты не держишь трёхнедельную ветку — ты сливаешь её наполовину готовый код в trunk непрерывно, завернув в feature-флаг, выключенный в продакшене:

if (flags.enabled("new-checkout")) {
  return renderNewCheckout();
}
return renderLegacyCheckout();

Незавершённый код на trunk (интегрирован, скомпилирован, протестирован против чужих изменений), но невидим пользователям, пока флаг не включат — что может быть постепенной выкаткой на 1%, потом 10%, потом всех. Флаги — это то, что делает «сливай постоянно, даже незавершённую работу» безопасным. Без них TBD невозможен; с ними длина ветки падает почти до нуля, а незавершённость живёт в конфигурации, а не в топологии git.

4

Версионные релизы рождаются из релизных веток, нарезанных от trunk — и только от trunk. TBD не запрещает версионирование; он запрещает долгоживущие ветки разработки. Когда нужно отгрузить версионный релиз, ты нарезаешь короткую релизную ветку из trunk на выбранном коммите, стабилизируешь, тегируешь и отгружаешь — но разработка никогда не переезжает на эту ветку:

git checkout main
git checkout -b release/2.4
git tag -a v2.4.0 -m "Release 2.4.0"
# критические правки cherry-pick'ятся ИЗ trunk В релизную ветку

Ключевая дисциплина: правки делаются сначала на trunk, затем cherry-pick’ятся в релизную ветку, никогда наоборот. Релизная ветка — это в основном read-only снимок для отгрузки и патчинга конкретной версии; вся настоящая работа остаётся на одном trunk. Так TBD поддерживает версионные продукты без расхождения, которое потопило develop git-flow.

Почему это работает

Почему крупные организации выбирают эту требовательную модель вместо дружелюбного GitHub flow? Масштаб. При тысячах инженеров цена конфликтов слияния растёт сверхлинейно с временем жизни ветки и числом параллельных веток. Ветки GitHub flow «на день-два» нормальны при десяти инженерах и губительны при десяти тысячах. TBD толкает время жизни ветки к нулю, чтобы цена интеграции оставалась плоской, сколько бы людей ни коммитили. Цена крута — нужны отличный CI, реальная система feature-флагов и дисциплина разбивать каждую фичу на безопасные для trunk инкременты — именно поэтому TBD ассоциируется со зрелыми, высокоскоростными инженерными организациями, а не с маленькими командами.

Разбор примера

Сборка трёхнедельной переделки checkout без трёхнедельной ветки.

Ты переписываешь checkout, работа на 15 дней, в команде на TBD. Вместо ветки feature/new-checkout, открытой 15 дней, ты в первый же день заворачиваешь новый поток в feature-флаг new-checkout (выключен в проде). Затем каждый день ты приземляешь маленькие PR на trunk: новую модель корзины в понедельник, новый шаг оплаты во вторник, новую страницу подтверждения в среду — каждый слит за часы, каждый за флагом, каждый протестирован против остального кода по мере его эволюции. К 15-му дню весь новый поток на trunk, полностью интегрирован, ни разу не вызвав крупного слияния. Ты включаешь флаг для 1% пользователей, смотришь метрики, разгоняешь до 100%, затем удаляешь флаг и старый код.

Сравни с версией на git-flow или наивном GitHub flow: 15-дневная ветка, которая расходится с чужими 15 днями работы и детонирует конфликтами в момент слияния. TBD вообще не дал этой ветке существовать — та же фича отгружена как пятнадцать безопасных ежедневных интеграций.

Частая ошибка

Соблазнительная ошибка — перенять браночное правило TBD («коммить в trunk постоянно»), пропустив его включатели (мощный CI, feature-флаги, маленькие инкременты). Закоммить незавершённый, нефлагированный код прямо в trunk без сильного гейта тестов — и ты получишь не скорость уровня Google, а вечно сломанный trunk, блокирующий всех. TBD — это не «меньше процесса», а другой процесс: дисциплина перемещается из управления ветками в строгость CI и гигиену флагов. Команде без этой инфраструктуры обычно лучше подходит GitHub flow, пока системы CI и флагов не станут реальными.

Проверь себя
Викторина

В trunk-based development как интегрируют большую, многонедельную фичу, не держа долгоживущую ветку?

Итог

Trunk-based development заставляет всех интегрировать в один trunk непрерывно — много раз в день — через очень короткоживущие ветки или небольшие прямые коммиты, держа расхождение, а значит и конфликты слияния, крошечными. Незавершённые фичи слиты, но спрятаны за feature-флагами, так что длина ветки падает к нулю, а незавершённость живёт в конфигурации, а не в топологии git. Он требует мощной непрерывной интеграции и реальной инфраструктуры флагов, поэтому его применяют высокоскоростные, крупномасштабные организации. Версионные релизы всё равно происходят — через короткие релизные ветки, нарезанные от trunk, с правками, сделанными на trunk и cherry-pick’нутыми внутрь. Дальше ты соберёшь все три workflow в руководство по выбору правильного.

Практика

Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.

вспомнитьприменитьуглубить0 из 4 завершено

Что-то непонятно?

Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.

хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.