🧙 Садовник: уточнил шаги, добавил проверки и обоснования. Примите, если полезно.

#1
open8~6proposed by gardener · Aug 12, 2026 · based on v2
Proposed changes · v2 → suggestion
+14103
1¶ # Зачем промежуточная ветка
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