🧙 Садовник: уточнил шаги, добавил проверки и обоснования. Примите, если полезно.
#1Proposed changes · v2 → suggestion
+14−1031−¶ # Зачем промежуточная ветка
2−
3− В простой схеме фичи льются сразу в `main`. Пока разработчик один, это работает. Как только появляется необходимость **проверить несколько фич вместе** до выкатки, нужна промежуточная ветка.
4−
5− Здесь она называется `demo`. В других проектах встретишь `develop`, `development` или `staging` — суть одна.
6−
7− ```
8− feature/твоя-фича → demo → main
9− первый PR второй PR
10− (ревью) (релиз)
11− ```
12−
13− **Главное отличие от простой схемы:** два pull request вместо одного, и ветка ответвляется от `demo`, а не от `main`.
14−¶ ## Как оформлять коммиты
15−
16− Полная форма сообщения выглядит так:
17−
18− ```
19− тип(область): описание в повелительном наклонении
20− ```
21−
22− Пять правил:
23−
24− 1. **Тип** — `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`.
25− 2. **Повелительное наклонение** — «добавь», а не «добавил».
26− 3. **Описывай ЧТО сделано, а не КАК.**
27− 4. **Первая строка до 50 символов.**
28− 5. **Подробности** — после пустой строки.
29−
30− **Примеры по-русски:**
31− ```
32− feat: добавлен модуль авторизации
33− fix: исправлен баг с регистрацией пользователя
34− docs: обновлена документация API
35− refactor: переработка модуля платежей
36− test: добавлены тесты для API эндпоинтов
37− chore: обновлены зависимости проекта
38− ```
39−
40− **Примеры по-английски:**
41− ```
42− feat: add user authentication via JWT
43− fix: resolve database connection timeout
44− refactor: optimize course search algorithm
45− test: add integration tests for payment module
46− chore: upgrade FastAPI to v0.100.0
47− ```
48−
49− Язык выбирает команда — важно только, чтобы в одном проекте он был один.
50−¶ ## Что писать в скобочках
51−
52− Скобки после типа — это **область изменения** (scope). Одно слово: какой части проекта касается коммит.
53−
54− ```
55− fix(git): успешный push не становится ошибкой
56− chore(deps): закрыты уязвимости ip-address и fast-uri
57− fix(ui): длинные названия больше не распирают мобильную вёрстку
58− feat(mcp): точечная правка списка
59− fix(cache): закрытие списка отзывает его у общего кеша сразу
60− feat(safety): разрушительная команда не попадает в исполняемые
61− ```
62−
63− Прочитав такую строку, ты понимаешь **куда** смотреть, ещё не открыв диф. Без области — «fix: исправлен баг» — приходится лезть в коммит, чтобы понять, о чём он вообще.
64−
65− **Правила для области:**
66−
67− | Правило | Как | Как не надо |
68− |---|---|---|
69− | Одно слово, строчными | `fix(auth)` | `fix(Модуль Авторизации)` |
70− | Часть системы, а не файл | `fix(cache)` | `fix(redis_client.py)` |
71− | Из устоявшегося набора | `api`, `ui`, `db`, `auth`, `deps` | каждый раз новое слово |
72− | Не дублирует тип | `feat(cart)` | `feat(feature)` |
73−
74− Набор областей у проекта конечный: обычно 5–15 штук. Их стоит один раз выписать в `CONTRIBUTING.md` и дальше выбирать из списка, а не сочинять на ходу. Иначе через полгода в истории будет `auth`, `authorization`, `authz` и `users-auth` — и польза от области пропадёт.
75−
76− **Область необязательна.** Если изменение общее и не привязано к части системы — пиши без скобок: `chore: обновлены зависимости`. Пустые скобки `fix(): ...` — ошибка, так не пишут.
77−
78− **Ломающее изменение** помечается восклицательным знаком **после** скобок:
79−
80− ```
81− feat(api)!: убран устаревший эндпоинт /v1/users
82− ```
83−
84− Это сигнал: у того, кто пользуется твоим кодом, после обновления что-то сломается.
85−¶
861## Цикл
8721. Обновить demo и ответвиться от неё
883 ```bash
894 git switch demo
905 git pull origin demo
916 git switch -c feature/your-name-of-feature
927 ```
938
94− **Ключевое:** ветка создаётся от `demo`, а **не** от `main`. Ответвишься от `main` — получишь конфликты со всем, что уже влили в `demo` до тебя.
9+ **Ключевое:** ветка создаётся от `demo`, а **не** от `main`. Ответвишься от `main` — получишь конфликты со всем, что уже влили в `demo` до тебя. Перед созданием ветки проверь, что `demo` актуальна.
9510 $ git switch demo && git pull origin demo
9611 why: Ветка должна ответвляться оттуда, куда потом вольётся. Это главное правило любой схемы ветвления, и его чаще всего нарушают.
9712 - [ ] Ветка создана от demo, а не от main
9813 - [ ] Имя ветки с префиксом и описывает задачу
14+ - [ ] Demo обновлена до последней версии
99152. Закоммитить изменения
10016 ```bash
10117 git add .
10218 git commit -m "feat(cart): добавлено удаление товара из корзины"
10319 ```
10420
105− Перед `git add .` всегда смотри `git status` — точка забирает всё, включая то, что ты не собирался коммитить.
21+ Перед `git add .` всегда смотри `git status` — точка забирает всё, включая то, что ты не собирался коммитить. Проверь, что все изменения добавлены корректно.
10622 $ git status
10723 why: Формат коммитов нужен не ради красоты: по типам собирают список изменений к релизу автоматически, а по областям фильтруют историю — `git log --grep="(auth)"` покажет всё, что делали с авторизацией.
10824 - [ ] Сообщение начинается с типа
10925 - [ ] Область в скобках указана и взята из принятого набора
11026 - [ ] Первая строка короче 50 символов
27+ - [ ] Все нужные изменения добавлены в индекс
11128 → Conventional Commits по-русски — https://www.conventionalcommits.org/ru/v1.0.0/
112293. Перед push поднять ветку над demo через rebase
11330 ```bash
11431 git switch demo
11532 git pull origin demo
11633 git switch feature/your-name-of-feature
11734 git rebase demo
11835 ```
11936
12037 **Что делает rebase:** берёт твои коммиты и прикладывает их заново поверх свежего `demo` — как будто ты только что ответвился. История остаётся прямой, без лишнего коммита слияния.
12138
12239 **Правило безопасности:** rebase **переписывает историю**. Делай его только со своей веткой, которую никто больше не трогает. Никогда — с `demo` или `main`.
12340
124− Если что-то пошло не так: `git rebase --abort`.
41+ Если что-то пошло не так: `git rebase --abort`. Проверь, что после rebase все изменения на месте и нет конфликтов.
12542 $ git rebase demo
12643 why: Сравни с merge: он создаёт дополнительный коммит и ветвит историю. При десятке разработчиков история превращается в плетёнку, в которой невозможно найти, когда появилась ошибка. Rebase держит её линейной.
12744 - [ ] Ветка поднята над свежим demo
12845 - [ ] Ты понимаешь, почему rebase нельзя делать с общими ветками
46+ - [ ] Нет конфликтов после rebase
47+ - [ ] Все изменения сохранены
12948 → git rebase — документация — https://git-scm.com/docs/git-rebase
130494. Первый PR: ветка в demo
13150 ```bash
13251 git push origin feature/your-name-of-feature
13352 ```
13453
13554 Дальше на GitHub жмёшь **New Pull Request** и внимательно выбираешь направление:
13655
13756 - **base** — `demo` (КУДА льём)
13857 - **compare** — `feature/your-name-of-feature` (ОТКУДА льём)
13958
14059 Затем описание и ревьюеры.
14160
142− Если перепутать base и compare местами, PR предложит влить `demo` в твою ветку — то есть наоборот.
61+ Если перепутать base и compare местами, PR предложит влить `demo` в твою ветку — то есть наоборот. Убедись, что PR создан корректно и все участники ревью добавлены.
14362 $ git push origin feature/your-name-of-feature
14463 why: На этом этапе код смотрят люди. Именно здесь ловятся ошибки, которые тесты не видят: непонятные имена, скопированный код, решения, которые через месяц придётся переписывать.
14564 - [ ] base = demo, compare = твоя ветка
14665 - [ ] В описании понятно, что и зачем сделано
14766 - [ ] Добавлены ревьюеры
67+ - [ ] PR создан и виден в интерфейсе GitHub
148685. Протестировать на demo
149− После мержа фича живёт в `demo` рядом с чужими. Это тот самый момент, ради которого вся схема и затевалась.
69+ После мержа фича живёт в `demo` рядом с чужими. Это тот самый момент, ради которого вся схема и затевалась. Проведи полное тестирование фичи в контексте других изменений.
15070 why: Фича может работать идеально в одиночку и ломаться рядом с другой. Такие поломки не ловятся ни ревью, ни тестами отдельной ветки — только совместной проверкой.
15171 - [ ] Фича проверена на demo вместе с остальными
72+ - [ ] Нет конфликтов с другими изменениями
73+ - [ ] Все функциональные требования выполнены
152746. Второй PR: demo в main
15375 Когда на `demo` всё сошлось, создаётся второй pull request:
15476
15577 - **base** — `main`
15678 - **compare** — `demo`
15779
15880 В описании перечисляются **все** изменения, которые уйдут в прод. Дальше — подтверждение от тимлида.
15981
160− Этот PR делает не автор фичи, а тот, кто выпускает релиз.
82+ Этот PR делает не автор фичи, а тот, кто выпускает релиз. Убедись, что все изменения в `demo` готовы к продакшену.
16183 why: Второй PR — это граница между «работает у нас» и «работает у пользователей». Он даёт последнюю возможность остановиться и список того, что именно выкатывается.
16284 - [ ] base = main, compare = demo
16385 - [ ] В описании перечислены все изменения релиза
16486 - [ ] Есть подтверждение ответственного
165−¶
166−¶
167−¶
168−¶ ## Когда эта схема нужна, а когда нет
169−
170− | Ситуация | Схема |
171− |---|---|
172− | Один разработчик, выкатываешь когда готово | `feature/` → `main`, один PR |
173− | Несколько разработчиков, нужно проверять фичи вместе | `feature/` → `demo` → `main` |
174− | Есть отдельный стенд для тестирования | точно с `demo` |
175−
176− Не бери сложную схему на вырост. Два PR на каждую правку в одиночном проекте — это ритуал, а не польза. Перейти от простой схемы к этой легко, обратно — тоже.
87+ - [ ] Все изменения в demo проверены и готовы к прод
Review