Commit Message Writing
Every commit: valid Conventional Commit, atomic, on the right short-lived branch.
Required workflow
git status --shortandgit diff --stat.- Verify you're on a short-lived branch dedicated to one feature, bug, fix, or coding area. If not, create/switch first.
- Confirm the changes are one logical unit. If mixed, split before committing.
- Confirm automated tests appropriate to the scope will run.
- Pick the most specific commit type.
- Write the message:
<type>[optional scope][!]: <imperative lowercase description>
[optional body]
[optional footer(s)]
- Validate with
scripts/validate_commit_message.pybefore committing.
Hard rules
- One short-lived branch per feature, bug, fix, or distinct coding area.
- Keep branches narrow, merge back quickly, avoid long-lived divergence.
- Every PR must have robust automated tests so bugs are caught early.
- Always include a lowercase type followed by
:. - Imperative, lowercase description, no trailing period, ≤72 chars.
- Body: one blank line after description. Footers: one blank line after body.
- Footer format:
Token: value. Hyphens in tokens exceptBREAKING CHANGE. - Use
!and/orBREAKING CHANGE:footer for breaking changes. - Never use
WIP,misc,update, or vague summaries.
Types
| Type | When | SemVer |
|---|---|---|
feat |
new feature | minor |
fix |
bug fix | patch |
refactor |
restructure, no behavior change | none |
perf |
performance improvement | none (patch if fixes bug) |
docs |
documentation only | none |
test |
tests only | none |
build |
build system / deps | none |
ci |
CI/CD changes | none |
chore |
maintenance / tooling | none |
style |
formatting only | none |
revert |
revert prior commit | depends |
Scope
Use a consistent noun for the dominant area. Omit only when truly cross-cutting. Never multiple scopes in one commit line.
Splitting rules
Split when:
- feature + bug fix
- code + formatting-only cleanup
- deps/build + application logic
- refactor + standalone behavior change
- generated files + loosely coupled source
One type, one intent per commit. If you can't describe it that way, split.
Validation
python3 scripts/validate_commit_message.py --message "feat(auth): add otp fallback"
