Conventional Commit Messages
Opinionated conventional commit format. Spec-faithful; tightens a few style rules.
Format
<type>(<optional scope>): <description>
<optional body>
<optional footer>
- Header line ≤ 72 chars (subject + blank line is the visual unit).
- Blank line between header / body / footer (mandatory when any are present).
- Subject is the only required part.
Types
| Type |
Use for |
feat |
Add, adjust, or remove a user-facing/API feature |
fix |
Fix a feat bug |
refactor |
Restructure code without changing behavior |
perf |
refactor that specifically improves performance |
style |
Whitespace, formatting, semicolons — no behavior change |
test |
Add or correct tests |
docs |
Documentation only |
build |
Build tools, dependencies, project version |
ops |
Infra, deployment, CI/CD, monitoring, backups |
chore |
Initial commit, .gitignore, misc tasks |
Scope
- Optional. Project-defined (e.g.
api, cli, auth, shopping-cart).
- Do not use issue IDs as scopes — those belong in the footer.
- Keep short (≤ 20 chars is the gist's server-side rule of thumb).
Description (subject)
- Imperative, present tense: "change", not "changed"/"changes". Frame as "This commit will…".
- Lowercase first letter (no capital after the type/scope colon).
- No trailing period.
- Concise — one line, no body needed for trivial changes.
Ticket code
If the current branch name contains a ticket code (e.g., SDIT-1222), include it in the subject line after the colon:
<type>(<optional scope>): [<ticket>] <description>
How to extract:
- Run
git branch --show-current to get the branch name
- Match pattern
[A-Z]+-\d+ (e.g., SDIT-1222, FE-456)
- If found, prepend
[TICKET] to the description
Examples:
feat: [SDIT-1222] add category field to event model
fix: [SDIT-1296] add suffix in webhook tracing client name
refactor: [SDIT-1215] create empty webhook client with provided id and secret
If no ticket code in branch name, skip this step.
Body (optional)
- Wrap at ~72 cols.
- Imperative, present tense.
- Explain why, contrast with previous behavior. Omit for trivial changes.
Footer (optional)
- Reference issues:
Closes #123, Fixes JIRA-456.
- Breaking changes must start with
BREAKING CHANGE: (single line: space after colon; multi-line: two newlines after colon).
- See BREAKING CHANGES below.
Breaking changes
- Append
! before the colon in the subject: feat(api)!: remove status endpoint.
- Must also describe in the footer with
BREAKING CHANGE: — both, not either-or.
- Bumps major version.
Versioning hint
- Breaking change → major bump.
feat or fix → minor bump.
- Anything else (
refactor, chore, docs, …) → patch bump.
Examples
feat: add email notifications on new direct messages
feat(shopping cart): add the amazing button
fix(shopping-cart): prevent order an empty shopping cart
fix(api): fix wrong calculation of request body checksum
fix: add missing parameter to service call
The error occurred due to <reasons>.
perf: decrease memory footprint for unique visitors by using HyperLogLog
build: update dependencies
- Pick the right type from the table (most common mistake:
feat vs fix vs refactor).
- Pick a scope only if the project uses them; otherwise omit.
- Extract ticket code from branch name if present (see Ticket code section).
- Subject ≤ 72 chars, imperative, lowercase, no period.
- Body only if the why isn't obvious.
- Footer: issue refs and/or
BREAKING CHANGE: if applicable.
- Verify with the regex (the gist's server-side pre-receive rule):
^(feat|fix|refactor|style|test|docs|build|ops|chore|perf)(\(.{1,20}\))?!?: .{1,100}$
1---2name: conventional-commits3description: Write git commit messages following Conventional Commits spec. Covers format, types, scope, ticket codes from branch names, body, footer, and breaking changes. Use when composing commit messages.4---56# Conventional Commit Messages78Opinionated conventional commit format. Spec-faithful; tightens a few style rules.910## Format1112```13<type>(<optional scope>): <description>1415<optional body>1617<optional footer>18```1920- **Header line ≤ 72 chars** (subject + blank line is the visual unit).21- Blank line between header / body / footer (mandatory when any are present).22- Subject is the only required part.2324## Types2526| Type | Use for |27|---|---|28| `feat` | Add, adjust, or remove a user-facing/API feature |29| `fix` | Fix a `feat` bug |30| `refactor` | Restructure code without changing behavior |31| `perf` | `refactor` that specifically improves performance |32| `style` | Whitespace, formatting, semicolons — no behavior change |33| `test` | Add or correct tests |34| `docs` | Documentation only |35| `build` | Build tools, dependencies, project version |36| `ops` | Infra, deployment, CI/CD, monitoring, backups |37| `chore` | Initial commit, `.gitignore`, misc tasks |3839## Scope4041- Optional. Project-defined (e.g. `api`, `cli`, `auth`, `shopping-cart`).42- **Do not** use issue IDs as scopes — those belong in the footer.43- Keep short (≤ 20 chars is the gist's server-side rule of thumb).4445## Description (subject)4647- **Imperative, present tense**: "change", not "changed"/"changes". Frame as "This commit will…".48- **Lowercase first letter** (no capital after the type/scope colon).49- **No trailing period**.50- Concise — one line, no body needed for trivial changes.5152## Ticket code5354If the current branch name contains a ticket code (e.g., `SDIT-1222`), include it in the subject line after the colon:5556```57<type>(<optional scope>): [<ticket>] <description>58```5960**How to extract:**611. Run `git branch --show-current` to get the branch name622. Match pattern `[A-Z]+-\d+` (e.g., `SDIT-1222`, `FE-456`)633. If found, prepend `[TICKET]` to the description6465**Examples:**66```67feat: [SDIT-1222] add category field to event model68fix: [SDIT-1296] add suffix in webhook tracing client name69refactor: [SDIT-1215] create empty webhook client with provided id and secret70```7172If no ticket code in branch name, skip this step.7374## Body (optional)7576- Wrap at ~72 cols.77- Imperative, present tense.78- Explain **why**, contrast with previous behavior. Omit for trivial changes.7980## Footer (optional)8182- Reference issues: `Closes #123`, `Fixes JIRA-456`.83- **Breaking changes must** start with `BREAKING CHANGE:` (single line: space after colon; multi-line: two newlines after colon).84- See BREAKING CHANGES below.8586## Breaking changes8788- Append `!` **before** the colon in the subject: `feat(api)!: remove status endpoint`.89- **Must** also describe in the footer with `BREAKING CHANGE:` — both, not either-or.90- Bumps **major** version.9192## Versioning hint9394- Breaking change → **major** bump.95- `feat` or `fix` → **minor** bump.96- Anything else (`refactor`, `chore`, `docs`, …) → **patch** bump.9798## Examples99100```101feat: add email notifications on new direct messages102```103104```105feat(shopping cart): add the amazing button106```107108```109fix(shopping-cart): prevent order an empty shopping cart110```111112```113fix(api): fix wrong calculation of request body checksum114```115116```117fix: add missing parameter to service call118119The error occurred due to <reasons>.120```121122```123perf: decrease memory footprint for unique visitors by using HyperLogLog124```125126```127build: update dependencies128```1291301. Pick the right type from the table (most common mistake: `feat` vs `fix` vs `refactor`).1312. Pick a scope only if the project uses them; otherwise omit.1323. Extract ticket code from branch name if present (see Ticket code section).1334. Subject ≤ 72 chars, imperative, lowercase, no period.1345. Body only if the why isn't obvious.1356. Footer: issue refs and/or `BREAKING CHANGE:` if applicable.1367. Verify with the regex (the gist's server-side pre-receive rule):137 `^(feat|fix|refactor|style|test|docs|build|ops|chore|perf)(\(.{1,20}\))?!?: .{1,100}$`