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/lessons/git-lab-11-1-branching-strategies

lesson ── git-labs ── ~22 мин ── 7 шагов

Trunk-based: фичи под флагами в main

Цель - руками собрать trunk-based workflow и увидеть, почему он выглядит «плоско» по сравнению с GitHub Flow. Каждая фича уезжает в main маленьким коммитом за флагом, потом флаг включается, потом удаляется. Никаких долгоживущих feature-веток.

▶ интерактивный sandbox

Поднимется контейнер gitlab/git-base с git, bash, pre-commit. В браузере откроется терминал, можно сразу git init. Каждый шаг проверяется автоматически. Сеть air-gapped, github.com недоступен.

запустить sandbox →

stack ── git · bash · 256 MB RAM · air-gapped · самоуничтожается через 30 мин простоя

Шаги

  1. 01

    Создай репо с базовой структурой

    bash
    cd /home/student/work
    mkdir -p trunk-lab && cd trunk-lab
    git init -b main
    cat > app.py <<'EOF'
    FLAGS = {}
    def greet(name):
        return f"Hello, {name}"
    print(greet("world"))
    EOF
    git add . && git commit -m "init: greet"

    FLAGS = {} - заглушка для флагов, которые будут добавляться по ходу. Это типичный паттерн.

    ✓ База готова. FLAGS пустой.

  2. 02

    Добавь первую фичу под флагом - один маленький коммит

    Фича - заглавные буквы в приветствии. Сначала добавь её под выключенным флагом - изменения попадают в main, но поведение не меняется.

    bash
    cd /home/student/work/trunk-lab
    git switch -c feat/uppercase
    cat > app.py <<'EOF'
    FLAGS = {"uppercase": False}
    def greet(name):
        out = f"Hello, {name}"
        if FLAGS.get("uppercase"):
            out = out.upper()
        return out
    print(greet("world"))
    EOF
    git add . && git commit -m "feat(uppercase): scaffold behind flag, default off"
    git switch main
    # --no-ff = всегда создать merge-коммит, даже если возможен fast-forward
    git merge --no-ff feat/uppercase -m "merge feat/uppercase"
    git branch -d feat/uppercase  # сразу удаляем - ветка слита, не нужна
    python3 app.py                # вывод "Hello, world" - флаг off

    Главное: вывод Hello, world - тот же. Фича в main, но выключена. Ветка прожила ~30 секунд.

    ✓ Фича в main, поведение не изменилось.

  3. 03

    Включи флаг отдельным коммитом

    bash
    cd /home/student/work/trunk-lab
    sed -i 's/"uppercase": False/"uppercase": True/' app.py   # включаем флаг in-place
    git commit -am "enable(uppercase): turn on for everyone"
    python3 app.py                # теперь "HELLO, WORLD"

    Вывод теперь HELLO, WORLD. Это отдельный коммит - можно откатить только включение, не трогая сам код фичи.

    ✓ Флаг включён, поведение изменилось.

  4. 04

    Добавь вторую фичу - параллельно, тоже маленьким коммитом

    Имитируем работу двух разработчиков параллельно. Вторая фича - кастомное приветствие.

    bash
    cd /home/student/work/trunk-lab
    git switch -c feat/greeting
    # добавляем ключ "greeting": False в словарь FLAGS
    sed -i 's/FLAGS = {"uppercase": True}/FLAGS = {"uppercase": True, "greeting": False}/' app.py
    # заменяем литеральное "Hello" на условный выбор в зависимости от флага
    sed -i 's/out = f"Hello, {name}"/g = "Hi" if FLAGS.get("greeting") else "Hello"\n    out = f"{g}, {name}"/' app.py
    git commit -am "feat(greeting): customizable, behind flag"
    git switch main
    git merge --no-ff feat/greeting -m "merge feat/greeting"
    git branch -d feat/greeting
    python3 app.py                # снова "HELLO, WORLD" - greeting off

    Вывод снова HELLO, WORLD - greeting выключен. Но фича уже в main.

    ✓ Вторая фича смержена, поведение не изменилось.

  5. 05

    Посмотри граф - всё ещё почти линейный

    bash
    cd /home/student/work/trunk-lab
    git log --oneline --graph --all

    Видишь 4 коммита, два merge-коммита от --no-ff (это pre-конвенция, чтобы фичи были маркируемы). Но логически - всё идёт по main. Никаких параллельных долгоживущих веток.

    ✓ Четыре коммита, плоская структура.

  6. 06

    Включи второй флаг

    bash
    cd /home/student/work/trunk-lab
    sed -i 's/"greeting": False/"greeting": True/' app.py
    git commit -am "enable(greeting): GA"
    python3 app.py                # "HI, WORLD" - обе фичи активны

    Вывод HI, WORLD. Обе фичи активны.

    ✓ Обе фичи работают.

  7. 07

    Удали флаги - финальный шаг жизненного цикла

    Когда фичи стабильны и больше нет смысла их отключать - удали флаги, чтобы код не накапливал dead code.

    bash
    cd /home/student/work/trunk-lab
    cat > app.py <<'EOF'
    def greet(name):
        return f"Hi, {name}".upper()
    print(greet("world"))
    EOF
    git commit -am "cleanup: remove uppercase + greeting flags (both GA)"
    python3 app.py
    git log --oneline --graph

    Вывод тот же - HI, WORLD. Но код чистый: ни FLAGS, ни if. Граф - линейная история фич. Это и есть trunk-based в финале.

    ✓ Флаги удалены, код чистый. История - линейная.

Что ты узнал

Trunk-based - одна вечная ветка (main) и короткоживущие feature-ветки на часы-день. Фичи мерджатся под флагами, включаются отдельно, флаги удаляются после стабильной работы.

команды

  • git switch -c feat/x && ... && git switch main && git merge feat/xкороткая ветка, час-день жизни
  • grep -r FLAGS .найти все feature flags, чтобы вычистить

концепции

  • · main всегда зелёный - тесты проходят на каждом коммите
  • · флаг - не настоящая ветка, а условие в коде
  • · флаг живёт ровно до GA фичи, потом удаляется

← предыдущая

git bisect: найти баг бинарным поиском

следующая →

Fork-flow с двумя remote

Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки