Commit messages: Conventional Commits, повелительное наклонение
Тема дорожной карты · Английский для IT
🔊 Словарь терминов с произношением →
Сообщение коммита — самый короткий и самый долгоживущий технический текст, который пишет инженер: его прочитают при ревью, при поиске причины бага через год и при генерации changelog. В англоязычной практике сложились три правила. Первое: заголовок в повелительном наклонении, как будто вы отдаёте приказ коду: Add retry logic, Fix null check, Remove dead code, а не Added, Fixed, Removing. Проверка: заголовок должен продолжать фразу If applied, this commit will… — If applied, this commit will add retry logic. Второе: заголовок до 50–72 символов, без точки в конце, с заглавной буквы (или со строчной после типа в Conventional Commits). Третье: тело коммита, если оно есть, объясняет «почему», а не «что» — «что» видно из диффа. Стандарт Conventional Commits добавляет структуру: type(scope): description, где type — один из feat (новая функциональность), fix (исправление), docs, style (форматирование), refactor, perf (производительность), test, build, ci, chore (рутина), revert; scope — область в скобках; восклицательный знак после типа или строка BREAKING CHANGE: в теле обозначают несовместимое изменение. Пример: feat(auth)!: require MFA for admin accounts.
Как произносится
Commit message /kəˈmɪt ˈmɛsɪdʒ/, imperative /ɪmˈpɛrətɪv/ («импЕрэтив», повелительное наклонение), mood /muːd/ (наклонение; не путать с mode), subject line /ˈsʌbdʒɪkt laɪn/ (заголовок), body /ˈbɒdi/ (тело), scope /skoʊp/, breaking change /ˌbreɪkɪŋ ˈtʃeɪndʒ/, conventional /kənˈvɛnʃənəl/, chore /tʃɔːr/ («чор», рутинная задача), fixup /ˈfɪksʌp/, amend /əˈmɛnd/ (дополнить последний коммит), squash /skwɒʃ/, trailer /ˈtreɪlər/ (служебная строка в конце тела коммита).
Как употребляется
Хорошие заголовки:
fix(api): return 404 instead of 500 for unknown user idfeat(export): add CSV export for the user listrefactor(db): extract connection pooling into a moduleperf(search): cache tokenizer between requestsdocs(readme): document the STAGE_URL variablechore(deps): bump axios to 1.7.2revert: "feat(export): add CSV export"
Тело, объясняющее «почему»: The previous implementation opened a new connection per request, which exhausted the pool under load. Pooling brings p95 from 800 ms down to 120 ms.
Слова для ссылок на тикеты: Closes #123, Fixes #45, Refs #67, Related to JIRA-890. Служебные строки в конце тела (трейлеры): Signed-off-by, Reviewed-by, Tested-by.
Ловушки
Первая ловушка — прошедшее время: Fixed the bug, Added tests — распространённый стиль, но Git и большинство гайдов предпочитают повелительное наклонение, потому что так пишут сгенерированные сообщения самого Git (Merge branch, Revert). Вторая — бессодержательные заголовки: fix, update, wip, changes, asdf; в истории они бесполезны. Третья — «что» вместо «почему» в теле: Changed timeout from 30 to 60 видно из диффа, а Upstream API takes up to 45 s under load — нет. Четвёртая — точка в конце заголовка и заголовок длиннее 72 символов: обрезается в интерфейсах. Пятая — русский язык в коммитах международного проекта: читатель без кириллицы увидит нечитаемую строку. Шестая — неверный тип: feat для исправления или fix для рефакторинга ломает автогенерацию версии по semver, потому что feat поднимает minor, fix — patch, а ! — major.