Claude-skill-registry git-commits
Best practices for creating high-quality Git commits. Covers commit message conventions (Conventional Commits), atomic commits, staging strategies, and when to amend vs create new commits. Helps AI agents generate clean, meaningful commit history.
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/git-commits-daleseo-git-skills" ~/.claude/skills/majiayu000-claude-skill-registry-git-commits && rm -rf "$T"
manifest:
skills/data/git-commits-daleseo-git-skills/SKILL.mdsource content
Git Commit Best Practices
Purpose: This skill teaches AI agents to create high-quality commits with clear messages, proper granularity, and effective use of the staging area.
Core Principles
- Atomic Commits - One logical change per commit
- Clear Messages - Follow Conventional Commits format
- Meaningful History - Each commit tells a story
- Smart Staging - Stage only what belongs together
Commit Message Format
Conventional Commits Structure
<type>(<scope>): <subject> <body> <footer>
Type Categories
# ✓ CORRECT: Use these standard types feat: # New feature for the user fix: # Bug fix docs: # Documentation changes style: # Formatting, missing semicolons, etc. (no code change) refactor: # Code change that neither fixes a bug nor adds a feature perf: # Performance improvement test: # Adding or updating tests chore: # Maintenance tasks, dependencies, config # Examples: feat(auth): add password reset functionality fix(api): handle null response in user endpoint docs(readme): update installation instructions refactor(parser): simplify token extraction logic
Subject Line Guidelines
# ✓ GOOD: Clear, concise, imperative mood feat(auth): add OAuth2 login support fix(cart): prevent duplicate items docs(api): document rate limiting # ✗ BAD: Vague, past tense, too long feat(auth): added some authentication stuff fix(cart): fixed a bug docs(api): updated the documentation to include information about rate limiting
Rules:
- Use imperative mood ("add" not "added" or "adds")
- No period at the end
- Keep under 50 characters
- Capitalize first letter after type
- Be specific about what changed
Body Guidelines
# ✓ GOOD: Explains WHY and context feat(cache): add Redis caching layer Improves API response time by 80% for frequently accessed data. Uses Redis with 1-hour TTL for user profile and product catalog endpoints. Falls back to database if Redis is unavailable. Related to performance optimization initiative. # ✗ BAD: Just repeats the subject feat(cache): add Redis caching layer Added Redis caching.
When to include body:
- Why the change was needed
- How it solves the problem
- Any important implementation decisions
- Side effects or limitations
- Related issues or context
When to skip body:
- Self-explanatory changes (e.g., "fix(typo): correct variable name")
Footer Guidelines
# Breaking changes feat(api): change user endpoint response format BREAKING CHANGE: User API now returns camelCase instead of snake_case. Migration guide: https://docs.example.com/migration/v2 # Issue references fix(auth): prevent token expiration race condition Closes #123 Refs #456 # Co-authors feat(search): implement full-text search Co-authored-by: Jane Doe <jane@example.com>
Atomic Commits
What is an Atomic Commit?
Definition: One commit = one logical change
# ✓ GOOD: Atomic commits git commit -m "feat(auth): add login endpoint" git commit -m "feat(auth): add logout endpoint" git commit -m "test(auth): add login tests" # ✗ BAD: Non-atomic commit git commit -m "feat(auth): add login, logout, password reset, and tests"
Benefits
- Easy to review - Reviewer focuses on one change
- Easy to revert - Undo specific change without affecting others
- Easy to cherry-pick - Apply specific change to another branch
- Clear history - Each commit has clear purpose
How to Create Atomic Commits
# ✓ CORRECT: Stage related changes only # You made changes to auth.js, api.js, and tests.js # Commit 1: Feature implementation git add src/auth.js src/api.js git commit -m "feat(auth): add token refresh mechanism" # Commit 2: Tests git add tests/auth.test.js git commit -m "test(auth): add token refresh tests" # ✗ WRONG: Stage everything together git add . git commit -m "feat(auth): add token refresh and tests"
Decision Tree: Should This Be One Commit?
Does this change have a single, clear purpose? ├─ YES → Can it be described in one sentence? │ ├─ YES → One commit ✓ │ └─ NO → Multiple commits │ └─ NO → Multiple commits Examples: ├─ "Add login validation" → One commit ✓ ├─ "Add login and signup" → Two commits └─ "Add login, fix bug, update docs" → Three commits
Staging Strategies
Strategy 1: Partial File Staging
# You changed multiple things in one file # Only stage the lines related to current commit git add -p src/app.js # Interactive prompts: # y - stage this hunk # n - don't stage this hunk # s - split into smaller hunks # e - manually edit the hunk # Then commit only staged changes git commit -m "feat(app): add error handling" # Stage and commit remaining changes separately git add -p src/app.js git commit -m "refactor(app): extract validation logic"
Strategy 2: Multiple Commits from Unstaged Work
# ✓ WORKFLOW: Create multiple atomic commits from current changes # Check what changed git status git diff # Commit 1: Feature A git add src/feature-a.js src/utils.js git commit -m "feat(feature-a): implement feature A" # Commit 2: Feature B git add src/feature-b.js git commit -m "feat(feature-b): implement feature B" # Commit 3: Tests git add tests/ git commit -m "test: add tests for features A and B"
Strategy 3: Amend Last Commit
# Use case: You forgot to include a file in the last commit # ✓ CORRECT: Amend if commit is NOT pushed yet git add forgotten-file.js git commit --amend --no-edit # OR update the commit message too git commit --amend -m "feat(auth): add login endpoint and middleware" # ✗ WRONG: Amend if commit is already pushed # This rewrites history and causes problems for collaborators # If already pushed, create new commit instead: git add forgotten-file.js git commit -m "feat(auth): add missing middleware file"
Common Workflows
Workflow 1: Making a Feature Commit
# 1. Check current state git status git diff # 2. Stage related changes only git add src/feature.js src/api.js # 3. Review what will be committed git diff --staged # 4. Commit with conventional format git commit -m "feat(feature): add user profile customization Allows users to customize avatar, bio, and theme preferences. Settings are persisted to user preferences API endpoint. Closes #234" # 5. Verify commit git log -1 --stat
Workflow 2: Making Multiple Atomic Commits
# You worked on multiple things, now need to commit separately # 1. Check all changes git status # 2. First commit: Core feature git add src/core.js git commit -m "feat(core): add data validation layer" # 3. Second commit: API integration git add src/api.js git commit -m "feat(api): integrate validation with endpoints" # 4. Third commit: Tests git add tests/ git commit -m "test(validation): add comprehensive validation tests" # 5. Fourth commit: Documentation git add docs/ git commit -m "docs(validation): document validation rules"
Workflow 3: Fixing a Bug
# ✓ GOOD: Clear bug fix commit git add src/buggy-file.js git commit -m "fix(cart): prevent duplicate items on double-click Added debounce to 'Add to Cart' button and server-side duplicate check. Prevents race condition when users click rapidly. Fixes #567" # Include: # - What the bug was # - How you fixed it # - Issue reference
Workflow 4: Amending vs New Commit Decision
Did I already push this commit? ├─ NO → Safe to amend │ └─> git commit --amend │ └─ YES → Create new commit instead └─> git commit -m "fix: ..." Is this a fixup for recent commit? └─> Consider git commit --fixup=<sha> Then use git rebase -i --autosquash before pushing
Workflow 5: Refactoring Commits
# ✓ GOOD: Separate refactoring from behavior changes # Commit 1: Pure refactor (no behavior change) git add src/parser.js git commit -m "refactor(parser): extract token validation to separate function No behavior change. Makes code more testable and readable." # Commit 2: Behavior change git add src/parser.js git commit -m "feat(parser): add support for nested tokens Now supports tokens in format {{parent.child.value}}" # Why separate? # - Easy to verify refactor doesn't change behavior # - Easy to revert feature without losing refactor # - Clear history
Common Mistakes to Avoid
Mistake 1: Vague Commit Messages
# ✗ BAD: No context git commit -m "update" git commit -m "fix bug" git commit -m "changes" git commit -m "wip" # ✓ GOOD: Clear and specific git commit -m "feat(auth): add JWT token expiration check" git commit -m "fix(api): handle null values in user profile endpoint" git commit -m "refactor(parser): simplify regex patterns" git commit -m "docs(readme): add Docker setup instructions"
Mistake 2: Mixing Unrelated Changes
# ✗ BAD: Multiple unrelated changes in one commit git add . git commit -m "feat: add login, fix cart bug, update docs" # ✓ GOOD: Separate commits git add src/auth.js git commit -m "feat(auth): add OAuth login support" git add src/cart.js git commit -m "fix(cart): prevent negative quantities" git add docs/ git commit -m "docs(api): update authentication endpoints"
Mistake 3: Committing Debug Code
# ✗ BAD: Leaving console.log, debugger statements git add src/app.js # Contains console.log debugging git commit -m "feat(app): add feature" # ✓ GOOD: Review before committing git diff --staged # Check for debug code # Remove debug statements git add src/app.js git commit -m "feat(app): add feature"
Mistake 4: Too Large or Too Small Commits
# ✗ TOO LARGE: Entire feature in one commit git commit -m "feat(auth): complete authentication system" # 50 files changed, 2000+ lines # ✗ TOO SMALL: Meaningless micro-commits git commit -m "add semicolon" git commit -m "fix typo" git commit -m "add newline" # ✓ GOOD: Right-sized atomic commits git commit -m "feat(auth): add login endpoint" git commit -m "feat(auth): add logout endpoint" git commit -m "feat(auth): add token refresh mechanism" git commit -m "test(auth): add authentication tests"
Mistake 5: Amending Pushed Commits
# ✗ DANGEROUS: Amending after push git push origin feature-branch # Oh, forgot a file! git add forgotten.js git commit --amend --no-edit git push --force origin feature-branch # ← Causes problems! # ✓ SAFE: New commit instead git push origin feature-branch # Oh, forgot a file! git add forgotten.js git commit -m "feat(auth): add missing validation helper" git push origin feature-branch
Commit Message Templates
Template for Features
feat(<scope>): <what you added> <why this feature is needed> <how it works (if not obvious)> <any limitations or considerations> Closes #<issue-number>
Template for Bug Fixes
fix(<scope>): <what you fixed> <what was wrong> <how you fixed it> <why this approach> Fixes #<issue-number>
Template for Refactoring
refactor(<scope>): <what you refactored> No behavior change. <why refactor was needed> <what improved (readability, performance, maintainability)>
Integration with AI Code Generation
When AI agents generate code that needs committing:
1. Analyze Changes Before Committing
# ✓ CORRECT: Check what changed git status git diff # Determine: # - Is this one logical change or multiple? # - What type of change? (feat, fix, refactor, etc.) # - What scope? (auth, api, ui, etc.)
2. Create Appropriate Commit Message
# ✓ GOOD: AI-generated message with context git commit -m "feat(api): add rate limiting middleware Implements token bucket algorithm with 100 requests/minute limit. Returns 429 status with Retry-After header when limit exceeded. Addresses security requirement from issue #789" # ✗ BAD: Generic AI message git commit -m "add rate limiting"
3. Split Large Changes
# If AI generated multiple files for different purposes: # ✓ CORRECT: Separate commits git add src/rate-limiter.js git commit -m "feat(api): add rate limiting middleware" git add tests/rate-limiter.test.js git commit -m "test(api): add rate limiter tests" git add docs/api.md git commit -m "docs(api): document rate limiting" # ✗ WRONG: One large commit git add . git commit -m "add rate limiting with tests and docs"
Quick Reference Checklist
Before every commit, ask:
- Is this one logical change?
- Did I stage only related files?
- Is my commit message in Conventional Commits format?
- Does the subject line clearly describe what changed?
- Did I explain why (not just what) in the body?
- Did I remove debug code and comments?
- Is this commit NOT already pushed? (if planning to amend)
- Would this be easy to review?
- Would this be easy to revert if needed?
Advanced: Commit Message Psychology
Good commit messages answer:
- What changed? (Subject line)
- Why was it needed? (Body - business reason)
- How does it work? (Body - technical approach)
- What are the side effects? (Body - impacts)
# ✓ EXCELLENT: Answers all questions feat(search): implement fuzzy search algorithm Users frequently make typos in search queries, resulting in zero results and poor experience. Implemented Levenshtein distance-based fuzzy matching with tolerance of 2 characters. Performance impact: ~50ms additional latency for searches, acceptable given improved user experience. Results are cached for 5 minutes. Closes #456
Summary
Key Principles:
- One commit = one logical change (atomic commits)
- Use Conventional Commits format (type, scope, clear subject)
- Explain why, not just what (meaningful commit messages)
- Stage strategically (use
for partial staging)git add -p - Never amend pushed commits (creates new commit instead)
Quick Command Reference:
git add <file> # Stage specific file git add -p <file> # Stage parts of file interactively git diff --staged # Review what will be committed git commit -m "type(scope): msg" # Commit with message git commit --amend --no-edit # Amend last commit (if not pushed) git log -1 --stat # Verify last commit
Remember: Commits are documentation of your project's history. Write them for humans who will read them 6 months from now.