Claude-skill-registry clean-commits
Use when committing code - ensures atomic, descriptive commits that leave the codebase in a merge-ready state at every point
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/clean-commits-troykelly-claude-skills" ~/.claude/skills/majiayu000-claude-skill-registry-clean-commits && rm -rf "$T"
manifest:
skills/data/clean-commits-troykelly-claude-skills/SKILL.mdsource content
Clean Commits
Overview
Every commit is atomic, descriptive, and leaves code in a working state.
Core principle: Anyone should be able to checkout any commit and have working code.
Announce at use: "I'm committing with a descriptive message following clean-commits standards."
Commit Message Format
Structure
[type](scope): Short description (max 72 chars) [Optional body - what and why, not how] [Optional footer - issue references, breaking changes] Refs: #[ISSUE_NUMBER]
Types
| Type | Use For |
|---|---|
| New feature |
| Bug fix |
| Documentation only |
| Formatting, no code change |
| Code restructuring |
| Adding/fixing tests |
| Maintenance, dependencies |
Examples
feat(auth): Add user registration endpoint Implement POST /api/users/register with email validation, password hashing, and duplicate detection. - Validates email format and uniqueness - Hashes password with bcrypt - Returns user object without password Refs: #123
fix(auth): Prevent redirect loop on expired session Session expiry was triggering redirect to login, which checked session, found expired, and redirected again. Now clears session cookie before redirecting. Refs: #456
test(auth): Add integration tests for registration Cover success case, duplicate email, invalid format, and weak password scenarios. Refs: #123
Atomic Commits
What Makes a Commit Atomic
| Atomic | Not Atomic |
|---|---|
| One logical change | Multiple unrelated changes |
| Passes all tests | Breaks tests |
| Complete feature slice | Half-implemented feature |
| Can be reverted cleanly | Reverts would break things |
Signs of Non-Atomic Commits
- Commit message uses "and" to describe multiple things
- Diff includes unrelated files
- Some tests fail after commit
- "WIP" in commit message
Splitting Large Changes
If you have multiple changes, commit them separately:
# Stage specific files git add src/auth/register.ts git add src/auth/register.test.ts git commit -m "feat(auth): Add registration endpoint" # Stage next logical unit git add src/auth/login.ts git add src/auth/login.test.ts git commit -m "feat(auth): Add login endpoint"
Working State Requirement
Every commit must leave the codebase in a state where:
- All tests pass
- Build succeeds
- Application runs
- No TypeScript errors
- No linting errors
Before committing:
# Run tests pnpm test # Check build pnpm build # Check types pnpm typecheck # Check lint pnpm lint
If any fail, fix before committing.
Commit Frequency
Commit Often
- After each passing test in TDD cycle
- After each refactoring step
- After completing a logical unit
Don't Wait Too Long
| Too Infrequent | Just Right |
|---|---|
| "Implement entire feature" | "Add user model" |
| "Fix all bugs" | "Fix session expiry redirect" |
| "Update everything" | "Update auth dependencies" |
Small is Good
Smaller commits are:
- Easier to review
- Easier to revert
- Easier to bisect
- Easier to understand
The Commit Process
1. Stage Selectively
# Review what changed git diff # Stage specific files git add [specific files] # Or stage interactively git add -p
2. Review Staged Changes
# See what will be committed git diff --staged
3. Write Descriptive Message
# Short message (if simple) git commit -m "fix(auth): Handle null user in session check" # Long message (if complex) git commit # Opens editor for full message
4. Verify After Commit
# Check commit looks right git show --stat # Verify tests still pass pnpm test
Commit Message Body
When to include a body:
- Why the change was made (not just what)
- Context that isn't obvious from code
- Trade-offs or alternatives considered
- Breaking changes if any
Body Examples
refactor(api): Extract validation middleware Validation logic was duplicated across 12 endpoints. Extracted to reusable middleware that can be composed. Alternative considered: validation library. Rejected because our rules are domain-specific.
fix(data): Use optimistic locking for updates Race condition was causing lost updates when two users edited the same record simultaneously. BREAKING CHANGE: Update operations now require version field in request body.
Issue References
Always reference the issue:
# In commit message Refs: #123 # Or if commit closes the issue Closes: #123
Amending Commits
When to Amend
- Typo in message (if not pushed)
- Forgot to stage a file (if not pushed)
# Amend last commit (before push only!) git add forgotten-file.ts git commit --amend
When NOT to Amend
- After pushing to remote
- Changing commits others have based work on
Revert, Don't Delete
If a commit was wrong:
# Create a new commit that undoes the change git revert [commit-sha] # DON'T rewrite history on shared branches # DON'T force push to fix mistakes
Checklist
Before each commit:
- Tests pass
- Build succeeds
- Change is atomic (one logical unit)
- Message follows format
- Message describes why, not just what
- Issue is referenced
- No "WIP" or placeholder messages
Integration
This skill is called by:
- Throughout developmentissue-driven-development
- Before creating PRpr-creation
This skill enforces:
- Reviewable history
- Revertible changes
- Clear project narrative