Conventional Commits - спецификация формата commit-сообщений (conventionalcommits.org, выросла из Angular commit convention, публичный 1.0.0 в 2018). Не путать со стилем «50/72 + повелительное наклонение» Tim Pope - это про структуру строки, а не про длину и тон. Префикс заголовка по типу изменения делает историю машино-читаемой: changelog и semver-bump можно сгенерировать автоматически.
Формат
<type>(<scope>): <subject>
[optional body]
[optional footer]
- type - обязательный. Категория изменения.
- scope - опциональный. Модуль или подсистема.
- subject - короткое описание, повелительное наклонение, ≤ 50 символов с учётом префикса.
- body - детали, на 72 колонки.
- footer - ссылки на тикеты,
BREAKING CHANGE:,Co-authored-by:.
Типы
feat- новая фича для пользователяfix- баг-фиксdocs- только документацияstyle- форматирование, whitespacerefactor- изменение кода без новой фичи и без фикса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: для
подробного объяснения миграции.
Зачем
Главные две причины:
- Автоматический changelog. Инструменты вроде
standard-version,release-please,semantic-releaseпарсят историю, группируют по типам, генерируют CHANGELOG.md. - Автоматический semver.
fix:→ patch,feat:→ minor,BREAKING CHANGE:→ major. Связь с semver.
Без процесса автоматического релиза формат добавляет только обсуждение в команде. Если CHANGELOG ведёшь руками - можно жить без префиксов, ничего не пострадает.
Подводные камни
- Не путать
styleиfeat.style: reformat code- это только whitespace/индентация.feat: change button colors- это видимое пользователю изменение, даже если технически только CSS.scopeне обязателен. Если проект маленький - можно без него. Если большой - обязателен, иначе истории нечитаемые.
- Tools (pre-commit hook
commitlint) проверяют формат и блокируют коммит с нарушением. Полезно как страховка.