Context
- Current git status: !
git status --short
- Diff summary (file + line counts): !
git diff HEAD --stat
- Current branch: !
git branch --show-current
- Recent commits (for style matching): !
git log --oneline -10
The full diff is intentionally NOT loaded above. Read hunks on demand with git diff HEAD -- <file> for only the files you need to inspect to write the message and decide splits. Do not run git diff HEAD with no path filter.
Your task
Create atomic, self-contained commits with terse, exact messages. Conventional Commits format. No fluff. Why over what.
Commit Splitting
Split into multiple commits when changes involve:
- Different concerns — unrelated parts of the codebase
- Different types — mixing feat/fix/refactor/tests/docs/config
- Different file patterns — source vs docs vs config
- Large changesets — break down for reviewability
Each commit must build and make sense on its own. If all changes relate to one concern, a single commit is fine.
Message Rules
Subject line:
<type>(<scope>): <imperative summary> — <scope> optional
- Types:
feat, fix, refactor, perf, docs, test, chore, build, ci, style, revert
- Imperative mood: "add", "fix", "remove" — not "added", "adds", "adding"
- ≤50 chars when possible, hard cap 72
- No trailing period
- Match project convention for capitalization after the colon (check recent commits above)
Body (only if needed):
- Skip entirely when the subject is self-explanatory
- Add body only for: non-obvious why, breaking changes, migration notes, linked issues
- Wrap at 72 chars
- Bullets
- not *
- Reference issues/PRs at end:
Closes #42, Refs #17
Auto-clarity — always include body for: breaking changes, security fixes, data migrations, revert commits. Never compress these into subject-only; future debuggers need the context.
Breaking changes: mark subject with ! and add a BREAKING CHANGE: footer explaining the migration.
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.
What NEVER goes in:
- "This commit does X", "I", "we", "now", "currently" — the diff says what
- "As requested by..." — use
Co-authored-by: trailer instead
- AI attribution: "Generated with Claude Code", co-authorship footers, 🤖 emoji
- Emoji unless project convention requires
- Restating the filename when the scope already covers it
Examples
Trivial change, no body needed:
fix(auth): handle expired refresh token
Non-obvious why — body explains motivation:
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
Breaking 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.
HEREDOC Format
git commit -m "$(cat <<'EOF'
<type>(<scope>): <subject>
<body if needed>
EOF
)"
Staging Rules
- Stage specific files by name — do NOT use
git add -A or git add .
- NEVER stage files that may contain secrets:
.env, .env.*, credentials.json, *.key, *.pem, *.p12, id_rsa*, token.json, secret*. Warn the user and skip them.
- If all changes are already staged, do not re-stage them.
Edge Cases
- No changes (nothing staged, nothing modified): say so and stop. Do not create an empty commit.
- Only untracked files that look like generated artifacts (
dist/, node_modules/, *.log): warn the user instead of committing them.
- If the user says "normal mode" or "verbose commit": allow a longer, descriptive style for this commit only.
1---2name: commit3description: Creates atomic git commits with terse, exact Conventional Commits messages, splitting changes by concern and staging files individually.4---56## Context78- Current git status: !`git status --short`9- Diff summary (file + line counts): !`git diff HEAD --stat`10- Current branch: !`git branch --show-current`11- Recent commits (for style matching): !`git log --oneline -10`1213The full diff is intentionally NOT loaded above. Read hunks on demand with `git diff HEAD -- <file>` for only the files you need to inspect to write the message and decide splits. Do not run `git diff HEAD` with no path filter.1415## Your task1617Create atomic, self-contained commits with terse, exact messages. Conventional Commits format. No fluff. Why over what.1819### Commit Splitting2021Split into multiple commits when changes involve:2223- **Different concerns** — unrelated parts of the codebase24- **Different types** — mixing feat/fix/refactor/tests/docs/config25- **Different file patterns** — source vs docs vs config26- **Large changesets** — break down for reviewability2728Each commit must build and make sense on its own. If all changes relate to one concern, a single commit is fine.2930### Message Rules3132**Subject line:**33- `<type>(<scope>): <imperative summary>` — `<scope>` optional34- Types: `feat`, `fix`, `refactor`, `perf`, `docs`, `test`, `chore`, `build`, `ci`, `style`, `revert`35- Imperative mood: "add", "fix", "remove" — not "added", "adds", "adding"36- ≤50 chars when possible, hard cap 7237- No trailing period38- Match project convention for capitalization after the colon (check recent commits above)3940**Body (only if needed):**41- Skip entirely when the subject is self-explanatory42- Add body only for: non-obvious *why*, breaking changes, migration notes, linked issues43- Wrap at 72 chars44- Bullets `-` not `*`45- Reference issues/PRs at end: `Closes #42`, `Refs #17`4647**Auto-clarity — always include body for:** breaking changes, security fixes, data migrations, revert commits. Never compress these into subject-only; future debuggers need the context.4849**Breaking changes:** mark subject with `!` and add a `BREAKING CHANGE:` footer explaining the migration.5051```52feat(api)!: rename /v1/orders to /v1/checkout5354BREAKING CHANGE: clients on /v1/orders must migrate to /v1/checkout55before 2026-06-01. Old route returns 410 after that date.56```5758**What NEVER goes in:**59- "This commit does X", "I", "we", "now", "currently" — the diff says what60- "As requested by..." — use `Co-authored-by:` trailer instead61- AI attribution: "Generated with Claude Code", co-authorship footers, 🤖 emoji62- Emoji unless project convention requires63- Restating the filename when the scope already covers it6465### Examples6667Trivial change, no body needed:68```69fix(auth): handle expired refresh token70```7172Non-obvious why — body explains motivation:73```74feat(api): add GET /users/:id/profile7576Mobile client needs profile data without the full user payload77to reduce LTE bandwidth on cold-launch screens.7879Closes #12880```8182Breaking change:83```84feat(api)!: rename /v1/orders to /v1/checkout8586BREAKING CHANGE: clients on /v1/orders must migrate to /v1/checkout87before 2026-06-01. Old route returns 410 after that date.88```8990### HEREDOC Format9192```93git commit -m "$(cat <<'EOF'94<type>(<scope>): <subject>9596<body if needed>97EOF98)"99```100101### Staging Rules102103- Stage specific files by name — do NOT use `git add -A` or `git add .`104- NEVER stage files that may contain secrets: `.env`, `.env.*`, `credentials.json`, `*.key`, `*.pem`, `*.p12`, `id_rsa*`, `token.json`, `secret*`. Warn the user and skip them.105- If all changes are already staged, do not re-stage them.106107### Edge Cases108109- No changes (nothing staged, nothing modified): say so and stop. Do not create an empty commit.110- Only untracked files that look like generated artifacts (`dist/`, `node_modules/`, `*.log`): warn the user instead of committing them.111- If the user says "normal mode" or "verbose commit": allow a longer, descriptive style for this commit only.