# Conventional Commits _Ежедневная работа · GitLab Knowledge Base_ **TL;DR:** Формат сообщения коммита `(): `. Позволяет автоматически собирать changelog и выбирать semver-уровень при релизе. Стандарт от 2018, поддерживается большинством release-инструментов. Conventional Commits - спецификация формата commit-сообщений (conventionalcommits.org, выросла из Angular commit convention, публичный 1.0.0 в 2018). Не путать со стилем «50/72 + повелительное наклонение» Tim Pope - это про *структуру строки*, а не про длину и тон. Префикс заголовка по типу изменения делает историю машино-читаемой: changelog и semver-bump можно сгенерировать автоматически. ## Формат ``` (): [optional body] [optional footer] ``` - **type** - обязательный. Категория изменения. - **scope** - опциональный. Модуль или подсистема. - **subject** - короткое описание, повелительное наклонение, ≤ 50 символов с учётом префикса. - **body** - детали, на 72 колонки. - **footer** - ссылки на тикеты, `BREAKING CHANGE:`, `Co-authored-by:`. ## Типы - `feat` - новая фича для пользователя - `fix` - баг-фикс - `docs` - только документация - `style` - форматирование, whitespace - `refactor` - изменение кода без новой фичи и без фикса - `perf` - улучшение производительности - `test` - добавление/исправление тестов - `chore` - обслуживание (deps, конфиги) - `build`, `ci` - инфраструктура сборки - `revert` - отмена другого коммита Список не закрытый - команды добавляют свои (`security`, `i18n`), главное - фиксировать в документации проекта. ## Примеры ``` feat(auth): add password reset flow fix(api): handle null in user.profile docs(readme): document SSL setup chore(deps): bump react to 18.3.1 refactor!: drop support for Node 16 ``` ## Ломающие изменения Два варианта пометки: **1. `!` после типа:** ``` refactor(api)!: rename POST /user to POST /users ``` **2. `BREAKING CHANGE:` в футере:** ``` feat(api): rename POST /user to POST /users BREAKING CHANGE: endpoint /user no longer exists, use plural /users. ``` Можно совмещать - `!` для краткости, `BREAKING CHANGE:` для подробного объяснения миграции. ## Зачем Главные две причины: 1. **Автоматический changelog.** Инструменты вроде `standard-version`, `release-please`, `semantic-release` парсят историю, группируют по типам, генерируют CHANGELOG.md. 2. **Автоматический semver.** `fix:` → patch, `feat:` → minor, `BREAKING CHANGE:` → major. Связь с [semver](/courses/git/kb/semver.md). Без процесса автоматического релиза формат добавляет только обсуждение в команде. Если CHANGELOG ведёшь руками - можно жить без префиксов, ничего не пострадает. ## Подводные камни - **Не путать `style` и `feat`.** `style: reformat code` - это только whitespace/индентация. `feat: change button colors` - это видимое пользователю изменение, даже если технически только CSS. - **`scope` не обязателен.** Если проект маленький - можно без него. Если большой - обязателен, иначе истории нечитаемые. - **Tools (pre-commit hook `commitlint`)** проверяют формат и блокируют коммит с нарушением. Полезно как страховка. ## Команды ```bash git commit -m "feat(auth): add password reset" ``` Простой Conventional Commit ```bash git commit -m "fix: handle null" -m "" -m "BREAKING CHANGE: removed deprecated API" ``` Несколько -m создают тело с разделением пустыми строками ```bash npx commitlint --from HEAD~5 ``` Проверить последние 5 коммитов на соответствие Conventional Commits ## См. также - [git commit](/courses/git/kb/commit-cmd.md) - [Семантическое версионирование (SemVer)](/courses/git/kb/semver.md) - [Атомарный коммит](/courses/git/kb/atomic-commit.md)