Перейти к содержанию
Innovialabs

Как писать хорошие сообщения коммитов: Conventional Commits

Практика3 мин

Коротко

Хороший коммит объясняет, что и зачем изменилось, одной короткой строкой; Conventional Commits добавляет к ней тип вроде feat или fix, и по этим типам инструменты сами считают версию и пишут changelog.

Короткий ответ

Хорошее сообщение коммита — это короткая строка в повелительном наклонении, по которой через полгода понятно, что изменилось, плюс тело с объяснением «зачем», если это не очевидно. Conventional Commits — договоренность о формате этой строки:

<тип>(<область>): <описание>

<тело — необязательно>

<футер — необязательно>

Например: fix(cart): не сбрасывать корзину после обновления страницы.

Базовые правила любого коммита

  • Один коммит — одно логическое изменение. Не смешивайте фикс бага, переименование и обновление зависимостей.
  • Заголовок короткий, примерно до 50–72 символов, чтобы не обрезался в git log --oneline и интерфейсах.
  • Повелительное наклонение: «add», «fix», «remove» — как будто вы даете команду кодовой базе. В русскоязычных командах часто пишут «добавить», «исправить».
  • Без точки в конце заголовка.
  • Пустая строка между заголовком и телом.
  • Тело отвечает на «зачем», а не пересказывает diff. Что изменилось — видно в коде, почему — нет.
  • Ссылки на задачу — в футере: Refs: #123.

Плохо: fix, правки, wip, update files. Хорошо: fix(auth): обновлять токен до истечения срока, а не после.

Формат Conventional Commits

Спецификация обязательными называет только типы feat и fix, остальные — общепринятое соглашение (их предлагают, например, конфиги commitlint):

ТипКогда использовать
featновая функциональность для пользователя
fixисправление бага
docsтолько документация
styleформатирование, без изменения логики
refactorизменение кода без новых функций и фиксов
perfулучшение производительности
testдобавление или правка тестов
buildсборка, зависимости
ciнастройки CI
choreпрочие служебные изменения

Область (scope) в скобках необязательна и показывает модуль: feat(api), fix(checkout).

Breaking changes

Несовместимое изменение помечается двумя способами — восклицательным знаком или футером:

feat(api)!: удалить устаревший эндпоинт /v1/orders

BREAKING CHANGE: клиенты должны перейти на /v2/orders.

Примеры

feat(search): добавить фильтр по цене
fix(payments): корректно обрабатывать повторный callback от провайдера
docs: описать запуск проекта в Docker
refactor(user): вынести валидацию в отдельный модуль
perf(catalog): кешировать список категорий

Зачем это нужно: changelog и версии

Структурированные сообщения можно разбирать машиной. Это связывает коммиты с семантическим версионированием (SemVer):

Коммиты с момента релизаНовая версия
только fixpatch: 1.4.2 → 1.4.3
есть featminor: 1.4.2 → 1.5.0
есть ! или BREAKING CHANGEmajor: 1.4.2 → 2.0.0

Инструменты вроде semantic-release, release-please или standard-version читают историю, вычисляют следующую версию, генерируют CHANGELOG.md с разделами «Features» и «Bug Fixes» и создают тег. Типы docs, chore, style в changelog обычно не попадают.

Дополнительный плюс — история становится удобной для поиска: git log --grep "^fix(payments)".

Как внедрить в команду

  1. Договоритесь о списке типов и областей и запишите их в README или CONTRIBUTING.
  2. Добавьте проверку: commitlint с конфигом @commitlint/config-conventional через git hook или в CI.
  3. Если используете squash merge, проверяйте заголовок PR — именно он станет сообщением коммита в main.
  4. Подключите автоматический релиз, когда формат приживется.

Частые ошибки

  • Все подряд помечают chore. Тогда changelog пустой, а версии не растут.
  • feat для внутренних изменений. feat — то, что заметит пользователь продукта или API.
  • Забытый BREAKING CHANGE. Потребители получат несовместимое обновление как minor.
  • Тип есть, смысла нет: fix: fix bug ничем не лучше, чем просто fix.

Частые вопросы

Нет. Спецификация не требует языка, но типы (feat, fix) остаются английскими, потому что на них опираются инструменты. Главное — один язык во всем проекте.

Поможем с этим

Если хотите не разбираться самим, а получить результат — этим мы занимаемся каждый день.

Обсудить проект

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.