- [Original blog post](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
Resources
1Install
npx skillscat add bnadlerjr/dotfiles/claude-skills-writing-git-commits Install via the SkillsCat registry.
Writing Git Commits
Write clear, professional Git commit messages following Tim Pope's style guide.
Quick Start
/commit # Invoke when ready to commit staged changes
/commit --amend # Amend the previous commit messageThe Iron Law
NEVER reference Claude, Anthropic, AI, or any AI attribution in commit messages.
- No "Co-Authored-By: Claude" lines
- No "Generated by AI" notes
- No "Claude suggested" comments
- No AI tools mentioned anywhere
This is non-negotiable. Violating this rule fails the entire commit.
Template Lookup (Dynamic)
Before writing a commit message, check for project-specific templates:
- Git config template:
git config commit.template - Repo root:
.gitmessagefile in repository root - Existing template comments:
.git/COMMIT_EDITMSG - Fallback: Tim Pope format (documented below)
If a project template exists, follow its conventions. Otherwise, use Tim Pope format.
Tim Pope Format
The Seven Rules
- Subject ~50 chars (hard max: 72)
- Capitalize the subject line
- No period at end of subject
- Imperative mood in subject ("Add" not "Added" or "Adds")
- Blank line separating subject from body
- Wrap body at 72 chars
- Body explains what/why, not how
The Completion Test
Every subject line must pass this test:
"If applied, this commit will [your subject line]"
Examples:
- "If applied, this commit will Add user authentication" ✓
- "If applied, this commit will Fixed the bug" ✗
- "If applied, this commit will Refactor payment module for clarity" ✓
Subject Line Verbs
| Verb | Use For |
|---|---|
| Add | New feature, file, or capability |
| Remove | Deleting code, files, or features |
| Fix | Bug fixes |
| Update | Changes to existing functionality |
| Refactor | Code restructuring without behavior change |
| Rename | Renaming files, variables, functions |
| Move | Relocating code or files |
| Extract | Breaking out code into new function/module |
| Simplify | Reducing complexity |
| Improve | Performance, readability, or UX enhancements |
| Replace | Swapping one implementation for another |
| Support | Adding capability for something |
| Handle | Adding case handling or error handling |
| Implement | Completing a feature or specification |
| Configure | Setting up config or environment |
| Document | Adding or updating documentation |
When to Include a Body
- Subject only: Single-purpose changes where the diff is self-explanatory
- Subject + body: Multi-file changes, non-obvious decisions, breaking changes
Body content should answer:
- What changed and why?
- What alternatives were considered?
- What are the consequences or side effects?
- Are there any caveats or known issues?
Workflow
Step 1: Gather Context
Use atomic-thought to decompose the changes:
What files changed?
What was the purpose of each change?
What's the unifying theme?Step 2: Draft Subject Line
Use chain-of-thought to craft the subject:
- Identify the primary action (verb)
- Identify the primary object (what was affected)
- Combine into imperative statement
- Check length (~50 chars)
- Apply completion test
Step 3: Draft Body (if needed)
For non-trivial changes:
- Explain what changed at a high level
- Explain why the change was necessary
- Note any consequences or caveats
- Keep lines at 72 characters
Step 4: Validate
Use self-consistency to verify:
- Subject passes completion test
- Subject is imperative mood
- Subject is capitalized, no period
- Subject ~50 chars (never >72)
- Blank line before body (if body exists)
- Body wraps at 72 chars
- Body explains what/why not how
- Zero AI attribution
Step 5: Commit
Format commit message using HEREDOC for proper formatting:
git commit -m "$(cat <<'EOF'
Subject line here
Body paragraph explaining what changed and why.
Wrap at 72 characters per line.
EOF
)"Examples
Good: Simple Change
Add null check in user validationGood: With Body
Refactor authentication to use JWT tokens
Replace session-based auth with stateless JWT tokens to support
horizontal scaling. Sessions required sticky load balancing which
complicated our deployment. JWTs allow any server to validate
requests independently.
Breaking change: existing sessions will be invalidated on deploy.Good: Bug Fix
Fix race condition in order processing
Multiple concurrent orders could decrement inventory below zero
because the check-then-update wasn't atomic. Use database-level
locking to ensure inventory never goes negative.
Fixes #1234Bad Examples
fixed bug # Not capitalized, not specific
Updated the code. # Period, vague
Add feature for handling users. # Period
adds new authentication system # Not capitalized, not imperative
WIP # Not descriptive
Misc fixes # Too vague
Co-Authored-By: Claude <...> # AI ATTRIBUTION - NEVER DO THISIssue References
Place issue references at the end of the body:
Fix memory leak in image processing
The resize operation wasn't releasing the source image buffer
after completion, causing memory to grow unbounded.
Fixes #456
Closes #457
Refs #400Breaking Changes
Call out breaking changes prominently:
Remove deprecated v1 API endpoints
BREAKING CHANGE: The /api/v1/* endpoints are removed. Clients must
migrate to /api/v2/* which has been available since release 2.0.
Migration guide: docs/migration-v1-to-v2.mdMultiple Related Changes
If a commit touches multiple things, the subject should capture the theme:
Improve error handling across payment flow
- Add retry logic for transient gateway failures
- Log detailed error context for debugging
- Return user-friendly error messages
- Add circuit breaker for repeated failuresSuccess Checklist
Before finalizing any commit message, verify:
- Subject passes: "If applied, this commit will [subject]"
- Subject uses imperative mood (Add/Fix/Update, not Added/Fixed/Updated)
- Subject starts with capital letter
- Subject has no trailing period
- Subject is ~50 characters (hard max 72)
- Blank line between subject and body
- Body lines wrap at 72 characters
- Body explains what/why, not how
- No AI attribution anywhere
- Issue references at end of body (if applicable)