Ветки: feature-ветка без страха

Ветки: feature-ветка без страха

Ветки - главная суперспособность Git. Они позволяют работать над задачей изолированно: ты не ломаешь main, коллеги не ломают твой код, а когда всё готово - изменения сливаются через merge request. В Git создание ветки - мгновенная операция (это просто файл с SHA-1 хешем коммита), поэтому веток может быть сколько угодно.

Понимание веток и стратегий ветвления - обязательный навык для работы в команде. Без него невозможно участвовать в code review, CI/CD пайплайнах и релизном процессе.

Feature ветка расходится с main на коммите C1 и сливается обратно через merge commit

Создание и переключение веток

# Создать ветку и переключиться на неё (старый синтаксис)
git checkout -b feature/auth

# Создать ветку и переключиться (современный синтаксис, Git 2.23+)
git switch -c feature/auth

# Создать ветку без переключения
git branch feature/auth

# Переключиться на существующую ветку
git switch main
git checkout main    # старый синтаксис, работает тоже

Когда ты создаёшь ветку, Git просто создаёт новый указатель на текущий коммит. Файлы не копируются, ничего не дублируется. Именно поэтому ветки в Git такие дешёвые.

Создание ветки feature/auth: указатели main, HEAD и feature/auth ссылаются на один и тот же коммит C

После нескольких коммитов в feature-ветке:

Расхождение веток: после двух коммитов в feature/auth указатель ветки и HEAD ушли вперёд на коммит E, а main остался на C

Просмотр и управление ветками

# Список локальных веток (* = текущая)
git branch
# * feature/auth
#   main

# Список всех веток (локальные + remote)
git branch -a
#   feature/auth
# * main
#   remotes/origin/main
#   remotes/origin/feature/login

# Подробный список с последним коммитом и tracking info
git branch -vv
# * feature/auth  a1b2c3d [origin/feature/auth] feat: add JWT middleware
#   main          e4f5g6h [origin/main] chore: update dependencies

# Ветки, уже слитые в текущую ветку (можно удалять)
git branch --merged

# Ветки, НЕ слитые в текущую ветку
git branch --no-merged

Удаление веток

# Безопасное удаление (только если ветка слита)
git branch -d feature/auth

# Принудительное удаление (даже если не слита)
git branch -D feature/auth

# Удаление remote-ветки
git push origin --delete feature/auth

# Очистка устаревших remote-tracking веток
# (ветки удалены на remote, но локальные ссылки остались)
git fetch --prune

Про сам fetch и его отличие от pull - в уроке про базовый цикл add → commit → push.

`git branch -d` откажется удалять ветку, если она не слита в текущую ветку - это защита от потери работы. `-D` удаляет принудительно. Используй `-D` только когда уверен, что ветка больше не нужна.

Push ветки на remote

# Первый push (устанавливает upstream tracking)
git push -u origin feature/auth

# Дальнейшие push-и (upstream уже установлен)
git push

# Push с другим именем на remote
git push origin feature/auth:feature/FL-123-auth

Detached HEAD

Detached HEAD - состояние, когда HEAD указывает не на ветку, а напрямую на коммит. Это случается при git checkout <hash>:

git checkout a1b2c3d
# You are in 'detached HEAD' state...

# HEAD указывает на коммит, а не на ветку
git log --oneline -1
# a1b2c3d feat: add auth handler

В detached HEAD можно смотреть код, запускать тесты, даже делать коммиты. Но эти коммиты не принадлежат ни одной ветке, и Git может их удалить при garbage collection. Если всё же потерял такой коммит - его обычно можно вытащить через reflog.

# Если хочешь сохранить работу из detached HEAD - создай ветку
git switch -c feature/experiment

# Вернуться на обычную ветку
git switch main
Detached HEAD удобен для быстрой проверки: «как работал код три дня назад?». Переключился на старый коммит, проверил, вернулся обратно - никаких побочных эффектов.

Стратегии ветвления

Слияние ветки обратно в основную делается через merge или rebase - чем они отличаются и что выбирать, разбираем в следующем уроке.

В командной работе нужны чёткие правила: как именовать ветки, куда сливать, когда релизить. Существует несколько популярных стратегий.

Git Flow

Классическая модель с несколькими долгоживущими ветками:

Git Flow: пять долгоживущих ветвей main, hotfix, develop, feature, release с диагональными переходами и тегами релизов на main

Плюсы: чёткое разделение, подходит для запланированных релизов. Минусы: сложно, много веток, долгоживущие ветки расходятся.

GitHub Flow

Упрощённая модель: одна ветка main + feature-ветки:

GitHub Flow: единственная ветка main и три короткоживущие ветки feature/auth, fix/login, chore/deps - каждая через PR в main

Плюсы: простота, continuous deployment. Минусы: main должен быть всегда стабилен, нужны хорошие тесты и CI.

Trunk-Based Development

Разработчики коммитят прямо в main (trunk) или используют очень короткоживущие ветки (1-2 дня):

Trunk-Based Development: частые мелкие коммиты прямо в main и единственная feature-ветка X, живущая меньше двух дней

Плюсы: минимальные конфликты, быстрая интеграция, continuous delivery. Минусы: требует feature flags, хорошего CI, дисциплины.

Для небольших команд (2-5 человек) GitHub Flow - оптимальный баланс простоты и контроля. Git Flow оправдан при нескольких параллельных версиях. Trunk-Based Development подходит зрелым командам с CI/CD.

Именование веток в команде

Хорошее имя ветки сразу говорит, что в ней происходит:

# Формат: <тип>/<задача>-<описание>
feature/FL-123-add-jwt-auth
fix/FL-456-null-pointer-in-handler
chore/FL-789-update-go-version
refactor/FL-101-extract-validation

# Типы:
# feature - новая функциональность
# fix - исправление бага
# chore - инфраструктура, зависимости
# refactor - рефакторинг
# docs - документация
# test - тесты

Привязка к номеру задачи (FL-123) позволяет GitLab/Jira автоматически связывать ветку с задачей, а CI может проверять, что номер задачи присутствует в имени ветки. Как всё это выглядит в собранном командном процессе - в мини-проекте про workflow на GitLab.

Мини-задание

  • Создай три ветки: feature/auth, feature/ui, fix/typo от main
  • Сделай по одному коммиту в каждой ветке
  • Посмотри все ветки через git branch -vv и git log --oneline --graph --all
  • Удали одну из веток с помощью git branch -d - убедись, что Git требует слияния
  • Переключись на конкретный коммит (detached HEAD), осмотрись, и вернись обратно на main

Зарегистрируйтесь бесплатно, чтобы пройти квиз, решить задание с автопроверкой и вести прогресс.