Ветки: feature-ветка без страха
Ветки: feature-ветка без страха
Ветки - главная суперспособность Git. Они позволяют работать над задачей изолированно: ты не ломаешь main, коллеги не ломают твой код, а когда всё готово - изменения сливаются через merge request. В Git создание ветки - мгновенная операция (это просто файл с SHA-1 хешем коммита), поэтому веток может быть сколько угодно.
Понимание веток и стратегий ветвления - обязательный навык для работы в команде. Без него невозможно участвовать в code review, CI/CD пайплайнах и релизном процессе.
Создание и переключение веток
# Создать ветку и переключиться на неё (старый синтаксис)
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-ветке:
Просмотр и управление ветками
# Список локальных веток (* = текущая)
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.
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
Стратегии ветвления
Слияние ветки обратно в основную делается через merge или rebase - чем они отличаются и что выбирать, разбираем в следующем уроке.
В командной работе нужны чёткие правила: как именовать ветки, куда сливать, когда релизить. Существует несколько популярных стратегий.
Git Flow
Классическая модель с несколькими долгоживущими ветками:
Плюсы: чёткое разделение, подходит для запланированных релизов. Минусы: сложно, много веток, долгоживущие ветки расходятся.
GitHub Flow
Упрощённая модель: одна ветка main + feature-ветки:
Плюсы: простота, continuous deployment. Минусы: main должен быть всегда стабилен, нужны хорошие тесты и CI.
Trunk-Based Development
Разработчики коммитят прямо в main (trunk) или используют очень короткоживущие ветки (1-2 дня):
Плюсы: минимальные конфликты, быстрая интеграция, continuous delivery. Минусы: требует feature flags, хорошего CI, дисциплины.
Именование веток в команде
Хорошее имя ветки сразу говорит, что в ней происходит:
# Формат: <тип>/<задача>-<описание>
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