git-workflow
Git-гигиена и релизная дисциплина — Conventional Commits (таблица типов, BREAKING CHANGE), semver-правила бампа, поимённые коммиты и запрет `git add .`/`git add -A` при параллельных сессиях, ловушка s
Файлы1
Открыть в GitHubSKILL.mdskills/git-workflow/SKILL.md
GitHubНавык: Git-workflow и релизы
Ключевой принцип: история — публичный документ. Каждый коммит читают ревьюеры, git bisect и генератор changelog. Состояние репозитория проверяй сам (git status, git diff) — не верь отчётам «всё чисто» на слово.
1. Conventional Commits
Формат: тип(scope): суть в повелительном наклонении — до ~72 символов, без точки в конце.
| Тип | Когда | Semver |
|---|---|---|
feat |
Новая функциональность для пользователя | minor |
fix |
Исправление бага | patch |
docs |
Только документация | patch/— |
refactor |
Перестройка кода без изменения поведения | patch |
perf |
Ускорение без изменения поведения | patch |
test |
Добавление/правка тестов | — |
chore |
Обслуживание: зависимости, конфиги, скрипты | — |
ci / build |
Пайплайны / система сборки | — |
BREAKING CHANGE: несовместимое изменение → ! после типа (feat!:) и/или футер BREAKING CHANGE: описание миграции. Это единственное, что бампает major — независимо от типа.
2. Semver: что бампает версию
- major (X.0.0) — любой BREAKING CHANGE (API, схема, формат конфига).
- minor (x.Y.0) — хотя бы один
featбез breaking. - patch (x.y.Z) — только
fix/refactor/perf/docs. - Версия релиза = максимум по всем коммитам с прошлого тега. Тег
vX.Y.Zобязан совпадать с версиями в манифестах (package.json, plugin.json и т.п.) — иначе релиз невоспроизводим.
3. Поимённые коммиты — почему git add . опасен
Параллельные сессии (multi-clauding) слепы друг к другу: в одном рабочем каталоге может лежать чужой незакоммиченный WIP. git add . / git add -A захватит его в твой коммит — молча.
git status --porcelain # сам посмотри, что реально изменено
git diff -- src/api/users.ts # проверь содержимое перед add
git add src/api/users.ts src/api/users.test.ts # ТОЛЬКО по именам
git commit -m "fix(api): не терять 404 при пустом userId"
git status # после коммита: чужой WIP остался нетронут
Незнакомые/несвязанные изменения в git status — стоп и спроси владельца, не включай их.
4. Ловушка squash-merge долгоживущей ветки
После squash-PR в main base получает один squash-коммит, не связанный с историей ветки → следующий PR той же ветки даёт ложные конфликты («те же файлы расходятся»).
Диагностика ПЕРЕД пушем ветки, у которой уже был squash-PR:
git fetch
git merge-base --is-ancestor origin/main HEAD && echo ok || echo "base ушёл вперёд"
Если base ушёл вперёд — feat почти всегда надмножество. Подтверди: git diff origin/main <squash-точка> пуст → разрешай:
git merge -s ours origin/main # делает base предком, сохраняя дерево ветки без потерь
Анализируй заранее, не жди сообщения GitHub о конфликте.
5. Worktree для параллельной работы
Параллельная/фоновая задача в том же репо → отдельный каталог и ветка: git worktree add <os-worktree-root>/<repo>-<slug>-<stamp> -b feat/<slug> HEAD. Каждое окно получает свой каталог — коммиты не пересекаются. После вливания: git worktree remove --force … && git worktree prune. Канон — скилл worktree-workflow.
6. Changelog (Keep a Changelog)
CHANGELOG.md: секция [Unreleased] сверху, релизы ## [X.Y.Z] - YYYY-MM-DD; рубрики Added (feat) / Fixed (fix) / Changed (refactor, perf, поведенческие правки) / Breaking (или Changed с пометкой) / Deprecated / Removed / Security. Источник — git log <prev-tag>..HEAD, но пиши для человека: что изменилось для пользователя, а не пересказ коммитов.
7. Безопасность
- Force-push запрещён. Rebase опубликованных веток,
push --force, удаление чужих веток — только с явного подтверждения владельца (и предпочитай--force-with-lease). - push / publish / release — только с явного подтверждения. Локальные коммиты и теги готовь свободно; всё, что уходит наружу — стоп и спроси.
- Неоднозначное односложное «ок»/«go»/«давай» — не авторизация необратимого действия. Переспроси, назвав действие явно: «пушу тег v2.0.0 и публикую релиз — подтверди».