Writing Git Commit Messages
Workflow
Detect project convention. Check for commitlint.config.*, .czrc,
.commitlintrc.*, or commit conventions in CONTRIBUTING.md. If found,
follow that convention. Otherwise, default to Conventional Commits.
Analyze the change. Read the diff (or context) to understand the scope
and purpose. Identify whether it's a single logical change or should be
split into multiple commits.
Choose the type. Pick the most accurate type: feat, fix, docs,
style, refactor, perf, test, build, ci, chore.
Choose the scope (optional). Use a short noun for the affected area
(e.g., auth, api, parser). Omit if the change is cross-cutting.
Write the subject line. Follow the format type(scope): description:
- Imperative mood ("Add", not "Added")
- ≤50 characters total
- No trailing period
- Lowercase description after the colon (Conventional Commits standard);
if the project omits a type prefix, capitalize the first word instead
Write the body (for non-trivial changes). Explain what changed and
why — not how. Wrap at 72 characters.
Add footers as needed: Fixes #123, BREAKING CHANGE: ...,
Co-authored-by: ....
When executing git commit from the shell, use this method only
(to guarantee real newlines and avoid literal \\n in history):
git commit -F- <<'EOF'
<type>(<scope>): <description>
<body wrapped at 72 chars>
<optional footer(s)>
EOF
Format
<type>(<scope>): <description>
[body — what & why, wrapped at 72 chars]
[footer(s)]
Breaking changes
Indicate with ! after the type/scope OR a BREAKING CHANGE: footer:
feat(api)!: change response format for /users
BREAKING CHANGE: The `email` field is now nested under `contact`.
Common mistakes
- Vague subjects (
fix stuff, update code, WIP) — always state what
the commit does.
- "and" in the subject — split into separate atomic commits.
- Wrong type — don't use
fix for refactors, feat for tests, or
chore as a catch-all.
- Missing "why" — the diff shows how; the body must explain why.
- Secrets in messages — never include credentials; git history is permanent.
Examples
Simple feature:
feat(parser): add support for nested arrays
Bug fix with context:
fix(auth): prevent session fixation on login
The session ID was not regenerated after successful authentication,
allowing an attacker with a known session ID to hijack the session.
Fixes #1234
Breaking change:
refactor!: drop support for Node 14
BREAKING CHANGE: Node 14 reached EOL in April 2023. The minimum
supported version is now Node 18.
Reference material
- Fundamental rules & message anatomy: references/01-rules-and-format.md
- Conventional Commits spec, types, alternatives & anti-patterns: references/02-conventional-commits-and-alternatives.md
- Enforcement tooling, AI-assisted messages & templates: references/03-tooling-and-automation.md
- Signed commits, DCO & quick reference: references/04-signing-and-dco.md
1---2name: writing-git-commit-messages3description: Writes and reviews git commit messages following Conventional Commits and the seven fundamental rules. Produces well-formatted, atomic, automation-friendly commit messages. Use when writing a commit message, reviewing commit messages, committing code changes, or when the user mentions git commits, commit messages, or changelogs.4---56# Writing Git Commit Messages78## Workflow9101. **Detect project convention.** Check for `commitlint.config.*`, `.czrc`,11 `.commitlintrc.*`, or commit conventions in `CONTRIBUTING.md`. If found,12 follow that convention. Otherwise, default to Conventional Commits.132. **Analyze the change.** Read the diff (or context) to understand the scope14 and purpose. Identify whether it's a single logical change or should be15 split into multiple commits.163. **Choose the type.** Pick the most accurate type: `feat`, `fix`, `docs`,17 `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`.184. **Choose the scope** (optional). Use a short noun for the affected area19 (e.g., `auth`, `api`, `parser`). Omit if the change is cross-cutting.205. **Write the subject line.** Follow the format `type(scope): description`:21 - Imperative mood ("Add", not "Added")22 - ≤50 characters total23 - No trailing period24 - **Lowercase** description after the colon (Conventional Commits standard);25 if the project omits a type prefix, capitalize the first word instead266. **Write the body** (for non-trivial changes). Explain *what* changed and27 *why* — not *how*. Wrap at 72 characters.287. **Add footers** as needed: `Fixes #123`, `BREAKING CHANGE: ...`,29 `Co-authored-by: ...`.308. **When executing `git commit` from the shell, use this method only**31 (to guarantee real newlines and avoid literal `\\n` in history):3233 ```bash34 git commit -F- <<'EOF'35 <type>(<scope>): <description>3637 <body wrapped at 72 chars>3839 <optional footer(s)>40 EOF41 ```4243## Format4445```46<type>(<scope>): <description>4748[body — what & why, wrapped at 72 chars]4950[footer(s)]51```5253## Breaking changes5455Indicate with `!` after the type/scope OR a `BREAKING CHANGE:` footer:5657```58feat(api)!: change response format for /users5960BREAKING CHANGE: The `email` field is now nested under `contact`.61```6263## Common mistakes6465- **Vague subjects** (`fix stuff`, `update code`, `WIP`) — always state what66 the commit does.67- **"and" in the subject** — split into separate atomic commits.68- **Wrong type** — don't use `fix` for refactors, `feat` for tests, or69 `chore` as a catch-all.70- **Missing "why"** — the diff shows *how*; the body must explain *why*.71- **Secrets in messages** — never include credentials; git history is permanent.7273## Examples7475**Simple feature:**76```77feat(parser): add support for nested arrays78```7980**Bug fix with context:**81```82fix(auth): prevent session fixation on login8384The session ID was not regenerated after successful authentication,85allowing an attacker with a known session ID to hijack the session.8687Fixes #123488```8990**Breaking change:**91```92refactor!: drop support for Node 149394BREAKING CHANGE: Node 14 reached EOL in April 2023. The minimum95supported version is now Node 18.96```9798## Reference material99100- **Fundamental rules & message anatomy**: [references/01-rules-and-format.md](references/01-rules-and-format.md)101- **Conventional Commits spec, types, alternatives & anti-patterns**: [references/02-conventional-commits-and-alternatives.md](references/02-conventional-commits-and-alternatives.md)102- **Enforcement tooling, AI-assisted messages & templates**: [references/03-tooling-and-automation.md](references/03-tooling-and-automation.md)103- **Signed commits, DCO & quick reference**: [references/04-signing-and-dco.md](references/04-signing-and-dco.md)