Commit Message
Write a concise commit message. Follow the Conventional Commits format. No fluff. Why over what.
Workflow
1. Choose the diff source
If the user provides a raw git diff output, use it as the diff to analyze.
Otherwise, run git status to see staged/unstaged files; detect no changes at all.
Then:
- If Staged non-empty: Analyze only
git diff --staged. Do not include unstaged changes, even if they exist.
- If Staged empty: Analyze
git diff (unstaged changes).
- If Both empty: Rely on the user's description; if none was provided, say there is nothing to commit and do not invent a message.
2. Gather the Change Context
When the user provides a description, intent, scope, issue link, or other context in their message:
- The selected diff is the source of truth for what changed.
- User context clarifies why, scope, or nuances not visible in the diff.
- Do not contradict the diff; if context and diff diverge, follow the diff and briefly note the mismatch.
Infer from the selected diff and any plain descriptions of changes:
- What changed — files, functions, logic affected by the changes
- Why it changed — bug fix, new feature, refactor, performance, etc.
- Who/what triggered it — issue number, user request, tech debt, etc.
3. Write the Commit Message
Follow this structure:
<type>(<optional scope>): <short imperative summary>
<body — the story: why this change was made, what problem it solves>
<footer — issue refs, breaking change notices>
Apply Rules, Examples, and Auto-Clarity below.
Rules
Commit Types:
| Type |
Use When |
feat |
A new feature or capability is added |
fix |
A bug or incorrect behavior is corrected |
refactor |
Code restructured without changing behavior |
perf |
A change that improves performance |
docs |
Documentation only changes |
test |
Adding or updating tests |
build |
Changes to build system or dependencies |
ci |
CI/CD pipeline changes |
style |
Formatting, whitespace, missing semicolons (no logic change) |
chore |
Other changes that don't modify source or test files |
revert |
Reverting a previous commit |
Subject line (first line):
- Use a correct commit type from the list above
- Add
! for breaking changes
- Use imperative mood: "add", "fix", "remove" — not "added", "adds", "adding", or "fixes"
- Max 72 characters
- No period at the end of the subject line
- Lowercase after the colon
Body (only if needed):
- Skip entirely when subject is self-explanatory
- Add body only for: non-obvious why
- Explain the why, not the what (the diff already shows the what)
- Keep lines under 100 characters
- Bullets with
- not *
Footer:
- Add footer only for: breaking changes, short migration notes, linked issues
- Reference issues:
Closes #123, Fixes #456, Refs #789
- Mark breaking changes:
BREAKING CHANGE: <description>
What NEVER goes in:
- "This commit does X", "I", "we", "now", "currently" — the diff says what
- "As requested by..." — use Co-authored-by trailer
- "Generated with Claude Code" or any AI attribution — unless the user's own rule requires an
Assisted-by/AI-attribution trailer, then add it as a trailer
- Emoji (unless project convention requires)
- Restating the file name when scope already says it
Examples
Diff: new endpoint for user profile with body explaining the why
feat(api): add GET /users/:id/profile
Mobile client needs profile data without the full user payload
to reduce LTE bandwidth on cold-launch screens.
Closes #128
Diff: breaking API change
feat(api)!: rename /v1/orders to /v1/checkout
BREAKING CHANGE: clients on /v1/orders must migrate to /v1/checkout
before 2026-06-01. Old route returns 410 after that date.
Auto-Clarity
Always include body/footer for: breaking changes, security fixes, data migrations, anything reverting a prior commit. Never compress these into subject-only — future debuggers need the context.
4. Generate Output
Return the message in a code block ready to paste (see Boundaries).
Multiple Commits from One Diff
If the diff contains logically separate changes, split them into multiple commit messages and tell the user. Use this heuristic:
- Different files with unrelated purposes → likely separate commits
- Same file but distinct concerns (e.g., bug fix + refactor) → suggest splitting
- Everything tightly coupled → one commit is fine
Boundaries
Only generates the commit message. Follow Workflow. Does not run git commit, does not stage files, does not amend. Output the message as a code block ready to paste.
1---2name: commit-message3description: Generates commit messages from git diffs and user-provided change context. Use when user says "write commit message", "generate commit", or invokes "/commit-message". Auto-triggers when committing changes.4---56# Commit Message78Write a concise commit message. Follow the Conventional Commits format. No fluff. Why over what.910## Workflow1112### 1. Choose the diff source1314If the user provides a raw `git diff` output, use it as the diff to analyze.1516Otherwise, run `git status` to see staged/unstaged files; detect no changes at all.1718Then:19201. If **Staged non-empty**: Analyze **only** `git diff --staged`. Do not include unstaged changes, even if they exist.212. If **Staged empty**: Analyze `git diff` (unstaged changes).223. If **Both empty**: Rely on the user's description; if none was provided, say there is nothing to commit and do not invent a message.2324### 2. Gather the Change Context2526When the user provides a description, intent, scope, issue link, or other context in their message:2728- The selected diff is the source of truth for **what** changed.29- User context clarifies **why**, scope, or nuances not visible in the diff.30- Do not contradict the diff; if context and diff diverge, follow the diff and briefly note the mismatch.3132Infer from the selected diff and any plain descriptions of changes:33341. **What changed** — files, functions, logic affected by the changes352. **Why it changed** — bug fix, new feature, refactor, performance, etc.363. **Who/what triggered it** — issue number, user request, tech debt, etc.3738### 3. Write the Commit Message3940Follow this structure:4142```43<type>(<optional scope>): <short imperative summary>4445<body — the story: why this change was made, what problem it solves>4647<footer — issue refs, breaking change notices>48```4950Apply `Rules`, `Examples`, and `Auto-Clarity` below.5152#### Rules5354**Commit Types:**5556| Type | Use When |57| ------ | ---------- |58| `feat` | A new feature or capability is added |59| `fix` | A bug or incorrect behavior is corrected |60| `refactor` | Code restructured without changing behavior |61| `perf` | A change that improves performance |62| `docs` | Documentation only changes |63| `test` | Adding or updating tests |64| `build` | Changes to build system or dependencies |65| `ci` | CI/CD pipeline changes |66| `style` | Formatting, whitespace, missing semicolons (no logic change) |67| `chore` | Other changes that don't modify source or test files |68| `revert` | Reverting a previous commit |6970**Subject line (first line):**7172- Use a correct commit type from the list above73- Add `!` for breaking changes74- Use imperative mood: "add", "fix", "remove" — not "added", "adds", "adding", or "fixes"75- Max 72 characters76- No period at the end of the subject line77- Lowercase after the colon7879**Body (only if needed):**8081- Skip entirely when subject is self-explanatory82- Add body only for: non-obvious **why**83- Explain the **why**, not the **what** (the diff already shows the what)84- Keep lines under 100 characters85- Bullets with `-` not `*`8687**Footer:**8889- Add footer only for: breaking changes, short migration notes, linked issues90- Reference issues: `Closes #123`, `Fixes #456`, `Refs #789`91- Mark breaking changes: `BREAKING CHANGE: <description>`9293**What NEVER goes in:**9495- "This commit does X", "I", "we", "now", "currently" — the diff says what96- "As requested by..." — use Co-authored-by trailer97- "Generated with Claude Code" or any AI attribution — unless the user's own rule requires an `Assisted-by`/AI-attribution trailer, then add it as a trailer98- Emoji (unless project convention requires)99- Restating the file name when scope already says it100101#### Examples102103- Diff: new endpoint for user profile with body explaining the why104105 ```106 feat(api): add GET /users/:id/profile107108 Mobile client needs profile data without the full user payload109 to reduce LTE bandwidth on cold-launch screens.110111 Closes #128112 ```113114- Diff: breaking API change115116 ```117 feat(api)!: rename /v1/orders to /v1/checkout118119 BREAKING CHANGE: clients on /v1/orders must migrate to /v1/checkout120 before 2026-06-01. Old route returns 410 after that date.121 ```122123#### Auto-Clarity124125Always include body/footer for: breaking changes, security fixes, data migrations, anything reverting a prior commit. Never compress these into subject-only — future debuggers need the context.126127### 4. Generate Output128129Return the message in a code block ready to paste (see `Boundaries`).130131---132133## Multiple Commits from One Diff134135If the diff contains **logically separate changes**, split them into multiple commit messages and tell the user. Use this heuristic:136137- Different files with unrelated purposes → likely separate commits138- Same file but distinct concerns (e.g., bug fix + refactor) → suggest splitting139- Everything tightly coupled → one commit is fine140141## Boundaries142143Only generates the commit message. Follow `Workflow`. Does not run `git commit`, does not stage files, does not amend. Output the message as a code block ready to paste.