Рабочий процесс с ветками функциональности
Изучите рабочий процесс с ветками функциональности: разрабатывайте изменения на отдельных ветках и вливайте их в main после проверки.
Обзор
Рабочий процесс с ветками функциональности — наиболее распространённый способ совместной работы команд с Git. Правило простое: вся разработка ведётся на отдельных ветках, никогда непосредственно в main. Каждая новая функциональность, исправление или эксперимент получают собственную ветку, а в ветку main попадает только завершённая и проверенная работа. Это гарантирует стабильность main и готовность к релизу в любой момент.
Основная идея
Поскольку работа изолирована на ветках, несколько разработчиков могут одновременно создавать разные функции, не мешая друг другу. Ветка main служит единственным источником истины для кода, готового к производству. Ветка — это сфокусированная единица работы с чётким началом (создана от main) и чётким концом (влита обратно в main).
Важно: ветка в Git дешёвая — это всего лишь перемещаемый указатель на коммит, а не копия файлов. Её создание мгновенно и почти не занимает дисковое пространство, именно поэтому создавать отдельную ветку для каждой задачи практично.
Именование веток
Единообразная схема именования делает ветки самодокументируемыми. Большинство команд используют префикс, обозначающий тип ветки, и ссылку на выполняемую задачу:
feature/login-form
feature/W3-142-checkout-page
fix/null-pointer-on-logout
chore/upgrade-eslintКосая черта — всего лишь соглашение: Git воспринимает feature/login-form как единое имя ветки, хотя инструменты используют его для группировки веток по префиксу. Избегайте пробелов и заглавных букв, чтобы имена было удобно вводить.
Пошаговый пример
Рабочий процесс — это короткий повторяющийся цикл: ответвиться от main, поработать, отправить, проверить, влить, убраться.
1. Создайте ветку от актуального main
Всегда начинайте с последнего main, чтобы ветка основывалась на текущем коде:
git switch main
git pull
git switch -c feature/login-formgit switch -c создаёт ветку и сразу переключается на неё (старый аналог — git checkout -b). Подробнее о команде — в разделе git switch.
2. Работайте, делая коммиты по ходу
Фиксируйте изменения небольшими логическими шагами, а не одним огромным коммитом в конце — маленькие коммиты проще проверять и отменять:
git add login.html login.js
git commit -m "Add login form markup and validation"Предпочитайте индексирование конкретных файлов вместо git add ., чтобы случайно не зафиксировать несвязанные изменения. Подробнее о том, как делать хорошие коммиты, — в разделе git commit.
3. Отправьте ветку
Отправьте ветку, чтобы коллеги могли видеть вашу работу и чтобы вы могли открыть pull request. Флаг -u связывает вашу локальную ветку с удалённой, после чего достаточно набрать git push:
git push -u origin feature/login-formО том, что делает -u (--set-upstream), подробно рассказано в разделе git push.
Проверка и слияние
На платформе хостинга, такой как GitHub или GitLab, вы открываете pull request (PR) — на GitLab он называется merge request. Здесь коллеги проверяют diff, оставляют комментарии и одобряют изменения. Обычно системы непрерывной интеграции (CI) автоматически запускают набор тестов для ветки. После того как PR одобрен и проверки пройдены, ветка вливается в main.
Платформы предлагают три распространённые стратегии слияния:
- Merge commit — сохраняет все коммиты ветки плюс коммит слияния. История полная, но может быть шумной.
- Squash and merge — объединяет все коммиты ветки в один аккуратный коммит в main. Популярный вариант: main остаётся чистым, каждая функция — единственная запись.
- Rebase and merge — воспроизводит коммиты ветки поверх main без коммита слияния, создавая линейную историю.
Уборка после слияния
После слияния ветки удалите её локально и удалённо, чтобы репозиторий не засорялся устаревшими ветками:
git switch main
git pull
git branch -d feature/login-form # delete the local branch
git push origin --delete feature/login-form # delete the remote branchgit branch -d не даст удалить ветку, которая не была влита, — это защищает от потери работы. (Используйте -D для принудительного удаления, если вы уверены в своём решении.)
Поддержание ветки в актуальном состоянии
Если main обновился, пока вы работали, перенесите эти изменения в свою ветку, чтобы итоговое слияние прошло гладко и конфликты обнаружились как можно раньше. Есть два варианта:
# Option A — merge main into your branch (keeps history as-is)
git switch feature/login-form
git merge main
# Option B — rebase your branch onto the latest main (linear history)
git switch feature/login-form
git rebase mainСлияние не деструктивно и безопасно для общих веток, но добавляет коммиты слияния. Перебазирование даёт более чистую, линейную историю, но перезаписывает коммиты ветки — поэтому избегайте перебазирования ветки, которую уже скачали другие. Эмпирическое правило: перебазируйте собственную приватную ветку, сливайте всё общее.
Разрешение конфликтов
Когда два изменения затрагивают одни и те же строки, слияние или перебазирование останавливается и просит разрешить конфликт. Git помечает конфликтующие фрагменты в затронутых файлах; вы редактируете их, затем индексируете и продолжаете. Полный процесс описан в разделе Разрешение конфликтов слияния.
Сохранение незавершённой работы
Если нужно переключить ветку, но вы ещё не готовы делать коммит, git stash откладывает незафиксированные изменения, чтобы вы могли свободно переключаться и вернуться к ним позже:
git stash # set current changes aside
git switch main # do something urgent
git switch feature/login-form
git stash pop # bring the changes backПреимущества и компромиссы
Рабочий процесс с ветками функциональности популярен, поскольку он прост в понимании, органично сочетается с pull request'ами и проверкой кода и поддерживает main в готовом к релизу состоянии.
Главный риск — долгоживущие ветки: чем дольше существует ветка, тем сильнее она расходится с main и тем сложнее итоговое слияние («ад слияния»). Чтобы этого избежать:
- Делайте ветки небольшими и краткосрочными — в идеале вливайте их в течение одного-двух дней.
- Регулярно вливайте main в свою ветку (или перебазируйтесь) — не только в конце работы.
- Разбивайте крупные функции на несколько меньших веток, каждая из которых вливается независимо.
- Никогда не коммитьте напрямую в main — это противоречит самой идее рабочего процесса.
Когда командам требуются ветки релизов, ветки hotfix и строгий процесс продвижения изменений, они нередко переходят к более полной модели — например, Git Flow или разработке на основе ствола (trunk-based development). Но ветка функциональности лежит в основе всех этих подходов.