Ветвление в Git
| Что такое ветка | подвижный указатель на коммит |
|---|---|
| Основные команды | git branch, git switch, git merge, git rebase |
| git switch | с Git 2.23 (2019) |
| Ветка по умолчанию | настраивается через init.defaultBranch (с Git 2.28, 2020) |
| Модели ветвления | GitHub Flow, Git Flow, trunk-based development |
Ветвление в Git — возможность вести несколько независимых линий разработки в одном репозитории: делать новую функцию, исправлять ошибку и экспериментировать, не мешая друг другу и основной версии кода. Ветка в Git — всего лишь лёгкий подвижный указатель на коммит, поэтому её создание и переключение происходят мгновенно, а ветки создают десятками. Именно дешёвое ветвление отличало Git от более старых систем, где ветка означала копирование всего проекта.[1]
Как устроены ветки
История Git — граф коммитов, каждый из которых ссылается на родителя. Ветка — это файл, в котором записан хеш одного коммита. Когда вы делаете новый коммит, указатель текущей ветки сдвигается на него. Особый указатель HEAD показывает, какая ветка сейчас активна.
C---D feature ← HEAD
/
A---B---E main
Здесь ветка feature ответвилась от коммита B и получила два коммита, а в main тем временем появился коммит E.
git branch # список локальных веток
git switch -c feature/login # создать ветку и перейти на неё
git switch main # вернуться на main
git branch -d feature/login # удалить слитую ветку
git branch -vv # ветки и их связь с удалёнными
Команда git switch появилась в Git 2.23 (2019) как более понятная замена перегруженной git checkout, которая и переключает ветки, и восстанавливает файлы.[2]
Слияние веток
Готовую работу возвращают в основную ветку двумя способами (подробно — в статье Merge и rebase):
- Перемотка (fast-forward): если в
mainне было новых коммитов, указатель просто сдвигается вперёд, история остаётся линейной. - Коммит слияния (merge commit): если ветки разошлись, Git создаёт коммит с двумя родителями, объединяющий изменения.[6]
Если обе ветки изменили одни и те же строки, возникает конфликт: Git помечает спорные места маркерами <<<<<<<, =======, >>>>>>>, и человек решает, какой вариант оставить, после чего фиксирует результат.
Альтернатива слиянию — rebase: коммиты ветки переносятся поверх свежей main, история становится линейной, но хеши коммитов меняются. Поэтому перебазировать можно только свою, ещё никем не используемую ветку.
Удалённые ветки
Ветки на сервере видны локально как origin/main, origin/feature/login — это снимки состояния на момент последнего git fetch. Локальная ветка может отслеживать удалённую, тогда git pull и git push работают без аргументов:
git push -u origin feature/login # опубликовать ветку и связать её с удалённой
git fetch --prune # обновить сведения и удалить исчезнувшие ветки
На платформах вроде GitHub и GitLab слияние обычно происходит не локально, а через pull request, где изменения проверяют коллеги и автоматические тесты CI/CD.
Ветка по умолчанию
Основная ветка исторически называлась master. В 2020 году GitHub, GitLab и другие платформы перешли на main для новых репозиториев, а в Git 2.28 появилась настройка init.defaultBranch. Ничего особенного в имени нет: основная ветка — та, которую команда договорилась считать главной.
Модели ветвления
| Модель | Суть | Подходит для |
|---|---|---|
| GitHub Flow | main всегда готова к выкладке; каждая задача — короткая ветка, слияние через pull request, затем развёртывание[4] |
веб-сервисы с непрерывной поставкой |
| Git Flow | долгоживущие main и develop, ветки feature/*, release/*, hotfix/*[3] |
продукты с версионными релизами и поддержкой старых версий |
| Trunk-based development | все интегрируют изменения в общий ствол (trunk) минимум раз в день; ветки живут часы, незавершённое прячется за флагами функций[5] | зрелые команды с сильной автоматизацией тестов |
Модель Git Flow описал Винсент Дриссен в 2010 году; позже сам автор отметил, что для веб-приложений с непрерывной поставкой лучше подходят более простые схемы. Общая тенденция — короче ветки и чаще интеграция: чем дольше живёт ветка, тем больнее её сливать.
Практические советы
- Называйте ветки по смыслу и с префиксом:
feature/,fix/,chore/, иногда с номером задачи. - Регулярно подтягивайте изменения основной ветки в свою, чтобы конфликты были маленькими.
- Защищайте
mainна сервере: запрет прямых push, обязательные проверки и ревью. - Удаляйте слитые ветки — платформы умеют делать это автоматически.
- Для работы над двумя ветками одновременно без переключения используйте
git worktree— отдельные рабочие каталоги для разных веток одного репозитория.