↓Перейти к содержанию
  1. Git: руководства и команды/

Conventional Commits: стандарт написания сообщений коммитов

··6 минут·

Conventional Commits — это спецификация для написания структурированных сообщений коммитов. Стандарт позволяет автоматически генерировать changelog, определять тип версионирования (semver) и делать историю проекта читаемой для инструментов и людей.

Базовая структура #

<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

Примеры:

feat: add user authentication
fix: resolve null pointer in login form
docs: update API endpoint documentation

Типы коммитов #

feat — новая функциональность:

feat: add dark mode toggle
feat(auth): implement OAuth2 login
feat!: redesign user dashboard (breaking change)

fix — исправление ошибки:

fix: prevent XSS in comment input
fix(api): handle empty response from server
fix: correct typo in error message

docs — изменения в документации:

docs: add getting started guide
docs(api): document authentication endpoints
docs: fix broken links in README

style — форматирование, отступы, отсутствующие точки с запятой (не меняет логику):

style: fix indentation in auth module
style: add missing semicolons
style: format according to prettier config

refactor — рефакторинг без добавления функций и без исправления ошибок:

refactor: extract user validation to separate service
refactor(auth): simplify token refresh logic
refactor: rename variables for clarity

perf — изменения для улучшения производительности:

perf: optimize database queries
perf(images): add lazy loading for thumbnails

test — добавление или исправление тестов:

test: add unit tests for auth service
test(api): add integration tests for user endpoints
test: fix flaky timeout test

chore — вспомогательные задачи, не влияющие на код продукта:

chore означает «рутинная задача» — обновление зависимостей, конфигурации инструментов, генерация файлов. Изменения типа chore не попадают в changelog и не влияют на версию продукта. Это главное отличие от fix и feat.

Что относится к chore:

  • обновление npm/pip/go зависимостей
  • изменение конфигурации линтера, prettier, eslint
  • добавление/изменение .editorconfig, .gitignore
  • настройка инструментов разработки (не CI/CD — для этого есть ci)
  • автоматически сгенерированные файлы
chore: update npm dependencies to latest
chore(deps): bump lodash from 4.17.20 to 4.17.21
chore: add .editorconfig for consistent formatting
chore: update .gitignore to exclude build artifacts
chore(lint): configure eslint for TypeScript

ci — изменения в CI/CD конфигурации:

ci: add GitHub Actions workflow
ci: fix deployment pipeline
ci(docker): optimize build cache

revert — откат предыдущего коммита:

revert: revert "feat: add dark mode toggle"
This reverts commit a1b2c3d4.

Scope (область изменений) #

Scope — опциональное уточнение компонента в скобках:

feat(auth): add two-factor authentication
fix(api): handle 404 responses correctly
docs(readme): update installation instructions
test(utils): add tests for date formatter
perf(database): add index to users table

Scope помогает быстро понять, какой модуль затронут изменением.

Breaking Changes #

Breaking change — изменение, ломающее обратную совместимость. Обозначается двумя способами:

# Способ 1: восклицательный знак после типа
feat!: redesign authentication API
fix!: change default port from 8080 to 3000

# Способ 2: BREAKING CHANGE в footer
feat(api): change response format

BREAKING CHANGE: API now returns JSON instead of XML.
Clients must update their parsers.

# Оба способа одновременно (наиболее явно)
feat(auth)!: rename login endpoint

BREAKING CHANGE: /api/login renamed to /api/auth/login

Breaking change вызывает мажорное увеличение версии в semver (1.x.x → 2.0.0).

Тело коммита (Body) #

Тело коммита объясняет, ЧТО и ПОЧЕМУ (не как):

fix: prevent race condition in session handling

Previously, concurrent requests could create duplicate sessions
when users logged in simultaneously. This was causing data
inconsistency in the user table.

The fix adds a database-level unique constraint and
handles the race condition with a retry mechanism.

Отделяется от заголовка пустой строкой. Каждая строка — не длиннее 72 символов.

Footer содержит дополнительные метаданные:

feat: add user profile page

Implement profile editing and avatar upload.

Closes #123
Fixes #456
Reviewed-by: Alice <[email protected]>
Co-authored-by: Bob <[email protected]>

Распространённые footer-токены: Closes, Fixes, Refs, BREAKING CHANGE, Co-authored-by.

Примеры реальных коммитов #

feat(auth): add JWT token refresh

Implement automatic token refresh when token expires.
Refresh happens silently without user logout.

Closes #87

---

fix(validation): validate email format on registration

Previously empty email was accepted during signup.
Added RFC 5322 compliant email validation.

Fixes #234

---

feat(api)!: change pagination format

BREAKING CHANGE: pagination now uses cursor-based
instead of offset-based approach.
Update all API clients to use `cursor` parameter
instead of `page` and `offset`.

---

chore(deps): update dependencies

- lodash: 4.17.20 → 4.17.21 (security fix)
- axios: 0.24.0 → 0.27.2
- typescript: 4.5.4 → 4.7.4

Автоматизация на основе Conventional Commits #

Semantic Release — автоматический релиз и changelog:

# Установить
npm install -D semantic-release

# Определяет версию по типам коммитов:
# feat:         1.0.0 → 1.1.0 (minor)
# fix:          1.0.0 → 1.0.1 (patch)
# BREAKING:     1.0.0 → 2.0.0 (major)

Commitlint — валидация сообщений коммитов:

# Установить
npm install -D @commitlint/cli @commitlint/config-conventional

# commitlint.config.js
module.exports = {
  extends: ['@commitlint/config-conventional']
}

# Проверить последний коммит
npx commitlint --from HEAD~1 --to HEAD --verbose

Conventional Changelog — генерация CHANGELOG.md:

# Установить
npm install -D conventional-changelog-cli

# Сгенерировать changelog
npx conventional-changelog -p conventional -i CHANGELOG.md -s

Настройка git-cz (commitizen) #

Интерактивный помощник для написания Conventional Commits:

# Установить
npm install -g commitizen cz-conventional-changelog

# Настроить
echo '{ "path": "cz-conventional-changelog" }' > ~/.czrc

# Использование — вместо git commit:
git cz
# Запустит интерактивный мастер:
# ? Select the type of change: (feat/fix/docs/...)
# ? What is the scope? (optional)
# ? Write a short description:
# ...

Практические рекомендации #

✓ Используйте повелительное наклонение: "add" не "added"
✓ Первая буква строчная в description
✓ Нет точки в конце description
✓ Заголовок до 72 символов
✓ Отделяйте тело от заголовка пустой строкой
✓ Будьте конкретны: "fix null pointer in login" не "fix bug"
✓ Один коммит — одно изменение
✗ Не используйте: "wip", "update", "changes", "misc"

Часто задаваемые вопросы #

Обязательно ли следовать Conventional Commits? Нет, но это стандарт де-факто в open source. Помогает автоматизировать changelog и версионирование, делает историю более читаемой.

Как выбрать между fix и refactor? fix — исправление ошибочного поведения. refactor — изменение кода без изменения поведения (оптимизация, упрощение). Если баг был исправлен попутно — это fix.

Что делать если коммит затрагивает несколько типов? Разбейте на несколько коммитов. Если невозможно — используйте наиболее значимый тип (feat > fix > refactor > chore).

Нужен ли scope? Необязательно. Полезен в больших проектах с несколькими модулями. В маленьких — излишен.

Как Semantic Release определяет версию? feat → minor bump (1.0.0 → 1.1.0), fix/perf → patch bump (1.0.0 → 1.0.1), BREAKING CHANGE → major bump (1.0.0 → 2.0.0). docs/chore/style/test — не влияют на версию.

Заключение #

Conventional Commits — это соглашение, которое превращает сообщения коммитов в структурированные данные. Основа: type(scope): description. Типы: feat, fix, docs, style, refactor, perf, test, chore, ci. Breaking changes обозначаются ! или BREAKING CHANGE в footer. Позволяет автоматизировать changelog через Semantic Release. Подробнее о лучших практиках написания коммитов — лучшие практики коммитов.

По теме #