Agent skill
git-commit-practices
CRITICAL: ALWAYS activate this skill at the start of ANY task in a git repository. ALWAYS activate this skill when the user asks you to commit. Check git status first - if on feature/topic branch, activate immediately. If on master/main, create a feature branch first, then activate. If not in git repo, skip. This skill guides continuous atomic commits throughout work sessions. Key trigger: ANY task involving code changes in a git repo. Plan commits during planning phase, execute continuously during implementation. Commit early, commit often - one concern per commit. Never batch commits at the end. (project, gitignored)
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/productivity/git-commit-practices
SKILL.md
Git Commit Practices
CRITICAL: Commit early, commit often, one concern per commit!
This skill ensures you follow proper git commit practices to maintain clean, reviewable git history.
Automatic Activation Workflow
This skill should be automatically activated based on git repository status:
Workflow Steps
-
Check if in git repository - At the start of any work session or task
bashgit status # or git branch --show-current -
If in a git repository:
- On a feature/topic branch → Activate this skill and follow commit-early-often practices
- On master/main branch → Create a new branch with a descriptive name, then activate this skill
- Use the skill throughout the session - Make atomic commits after each logical change
-
If NOT in a git repository:
- Skip this skill (git commit practices don't apply)
Branch Creation When on master/main
If you find yourself on the master or main branch:
# Create a new descriptive branch
git checkout -b feature-name
# Examples of good branch names:
# - fix-parser-error
# - add-export-feature
# - refactor-authentication
# - update-documentation
Then activate this skill and proceed with atomic commits.
Integration into Workflow
This means:
- Proactively check
git statuswhen starting work - Automatically activate this skill when in a git repo on a feature branch
- Create branches when on master/main before making any commits
- Make atomic commits throughout the work session, not just at the end
- Skip the skill entirely when not in a git repository
Example:
Task starts → Check git status → On feature branch → Activate skill →
Work on change → Complete logical unit → Commit → Continue working
Planning Commit Milestones
During the planning phase, before implementation begins, identify commit milestones. Commits should be planned, not an afterthought.
Workflow
- When creating a task plan - Identify natural commit points
- Mark commit milestones - Note where atomic commits should occur
- Execute continuously - Commit at each milestone as you reach it
Example: Planning a Feature
Task: "Add user authentication"
Bad approach (commits as afterthought):
Plan:
1. Add user model
2. Add API endpoint
3. Add UI component
4. Add tests
[Then at end: "Now let's commit everything"]
Good approach (commits planned upfront):
Plan with commit milestones:
1. Add user model → COMMIT: "Add user authentication data model"
2. Add API endpoint → COMMIT: "Add user authentication API endpoint"
3. Add UI component → COMMIT: "Add user authentication UI component"
4. Add tests → COMMIT: "Add user authentication tests"
Integration with TodoWrite
When using TodoWrite tool, each todo item is a potential commit milestone:
Todo: "Add input validation to form"
├── Implementation work
├── Verify it works
└── COMMIT immediately → Mark todo completed
Never batch commits at task completion.
Core Principle: Atomic Commits
Each commit should represent one logical change - a single fix, feature, or refactoring that can be understood, reviewed, and reverted independently.
Benefits of Atomic Commits
- Easier code review - Reviewers can understand one change at a time
- Safer reverts - Can undo specific changes without losing other work
- Clearer history - Git log tells the story of the project
- Better debugging - Git bisect works effectively
- Professional workflow - Industry standard practice
When to Commit
✅ Commit Immediately After
- Fixing a single bug - One bug, one commit
- Completing a logical unit - Function works, tests pass
- Refactoring one aspect - Before and after are both working states
- Adding one feature component - Each independent piece
- Updating documentation - Separate from code changes
- Making configuration changes - Isolated from feature work
- Quoted all variables in one file - Before moving to next file
- Fixed one specific issue - Don't bundle unrelated fixes
❌ Don't Wait Until
- You've fixed "everything"
- The entire feature is complete
- You've made changes to many files
- End of the day/session
- You remember to commit
Commit Granularity Guide
Perfect Granularity Examples
Scenario: Fixing critical bugs in grading scripts
Bad (what you did):
✗ One commit: "Fix critical bugs in grading scripts"
- Fixed timestamp bug
- Fixed undefined variable
- Fixed SSH injection
- Quoted all variables everywhere
(5 files, 90 insertions, 88 deletions)
Good (what you should have done):
✓ Commit 1: "Fix terminal grading timestamp format mismatch"
modules/terminal/grading/grade.sh.nw | 2 +-
✓ Commit 2: "Fix LaTeX grading undefined variable reference"
modules/latex/grading/grade.sh.nw | 8 ++++----
✓ Commit 3: "Fix SSH command injection in common.sh"
adm/grading/common.sh.nw | 3 ++-
✓ Commit 4: "Quote variables in common.sh for safety"
adm/grading/common.sh.nw | 12 ++++++------
✓ Commit 5: "Quote variables in git grading script"
modules/git/grading/grade.sh.nw | 8 ++++----
✓ Commit 6: "Quote variables in latex grading script"
modules/latex/grading/grade.sh.nw | 12 ++++++------
✓ Commit 7: "Quote variables in ssh grading script"
modules/ssh/grading/grade.sh.nw | 6 +++---
✓ Commit 8: "Quote variables in terminal grading script"
modules/terminal/grading/grade.sh.nw | 10 +++++-----
More Examples
Scenario: Adding a new feature
✓ Commit 1: "Add user authentication data model"
✓ Commit 2: "Add user authentication API endpoint"
✓ Commit 3: "Add user authentication UI component"
✓ Commit 4: "Add user authentication tests"
✓ Commit 5: "Add user authentication documentation"
Scenario: Refactoring
✓ Commit 1: "Extract validation logic to separate function"
✓ Commit 2: "Rename ambiguous variable names for clarity"
✓ Commit 3: "Remove unused imports and dead code"
What Constitutes "One Logical Change"?
A single logical change is one conceptual modification that can be described with a single purpose statement, even if it touches multiple files or locations.
Example: Replacing magic numbers with constants
Bad (too granular - split what should be one commit):
✗ Commit 1: "Define threshold constants at module level"
✗ Commit 2: "Use constants for command-line argument defaults"
✗ Commit 3: "Use constants for function parameter defaults"
✗ Commit 4: "Use constants in documentation"
Good (single logical change):
✓ One commit: "Replace hardcoded threshold values with named constants"
- Define DEFAULT_THRESHOLD_FIXED and DEFAULT_THRESHOLD_PERCENT
- Update argument parser defaults to use constants
- Update function parameter defaults to use constants
- Update documentation to reference constants
Why this is one commit:
- Single conceptual change: "eliminate magic numbers"
- Changes are not independently useful (defining constants without using them accomplishes nothing)
- Would never want to revert just part of this change
- Reviewer understands the complete picture in one diff
Contrast with truly independent changes:
✓ Commit 1: "Add --threshold-fixed option"
(Independent: adds new functionality)
✓ Commit 2: "Add --threshold-percent option"
(Independent: adds different functionality)
✓ Commit 3: "Replace hardcoded values with constants"
(Independent: refactoring that doesn't add features)
Rule of thumb: If you can't describe the change without using "and" to link unrelated concepts, it should be multiple commits. But if "and" connects steps of the same change, it's one commit.
- "Add user model and update constants" → Two commits
- "Define constants and use them everywhere" → One commit
Workflow for Multiple Changes
Step-by-Step Process
When you have multiple fixes to make:
-
Fix the first issue
bash# Make the change vim file1.nw # Verify it works (if applicable) make # Commit immediately git add file1.nw git commit -m "Fix specific issue in file1" -
Fix the second issue
bash# Make the change vim file2.nw # Commit immediately git add file2.nw git commit -m "Fix specific issue in file2" -
Continue for each issue
- Never batch multiple fixes
- Each commit should be independently reviewable
Interactive Staging for Mixed Changes
If you've already made multiple changes (not ideal but happens):
# Stage changes selectively
git add -p file.nw
# Review what's staged
git diff --staged
# Commit the staged portion
git commit -m "First logical change"
# Repeat for remaining changes
git add -p file.nw
git commit -m "Second logical change"
Commit Message Guidelines
Format
Short summary (50 chars or less)
Detailed explanation if needed:
- What changed
- Why it changed
- Impact or implications
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Summary Line Rules
- Imperative mood: "Fix bug" not "Fixed bug" or "Fixes bug"
- Capitalize first word: "Add feature" not "add feature"
- No period at end: "Update docs" not "Update docs."
- Be specific: "Fix timestamp mismatch in terminal grading" not "Fix bug"
- Stay under 50 characters when possible
Good vs Bad Messages
Bad:
✗ "Fix stuff"
✗ "Updates"
✗ "WIP"
✗ "Fixed various issues"
✗ "Changes to multiple files"
Good:
✓ "Fix timestamp format mismatch in terminal grading"
✓ "Remove undefined variable from check_student"
✓ "Quote variables in common.sh for space safety"
✓ "Add error handling for missing config file"
Proactive Reminders
During Planning Phase
When creating a plan (using plan mode or TodoWrite):
- Identify commit milestones - Each major step should have a planned commit
- Include commit messages - Plan what each commit will say
- Map todos to commits - One todo = one commit (approximately)
This ensures commits are intentional, not an afterthought.
After Reading Multiple Files
If you read multiple files to understand an issue:
- Don't fix them all at once
- Fix the first one and commit
- Then move to the next
After Making a Plan
If you create a todo list with multiple items:
- Commit after completing each todo item
- Don't wait until all items are complete
- Each item should ideally be one commit
When User Says "Fix all..."
If user requests fixing multiple issues:
- Clarify: "I'll fix these one at a time and commit each separately"
- Proceed sequentially: Fix, commit, next
- Update user: "Fixed X (committed), now working on Y"
Red Flags (Stop and Commit)
Watch for these signs you should commit NOW:
- Multiple file changes - If you've modified 3+ files, you've probably done multiple things
- Large diffs - If
git diffoutput is long, break it up - Mixed concerns - If commit message needs "and", split it
- Time passing - If 15+ minutes since last commit, commit something
- Before switching tasks - Always commit current work before starting new work
- After "done" - When you think "that works", commit it
Exception: When to Combine
Very rarely, commits can be combined IF:
- Mechanical changes - Same operation applied everywhere (e.g., "Rename function X to Y across codebase")
- Tiny fixes - Fixing typos in multiple places
- Broken state - Change #1 breaks build and change #2 fixes it (but avoid this situation)
Default rule: When in doubt, commit separately.
Integration with TodoWrite
When using TodoWrite tool:
Todo item completed → Commit immediately → Mark todo as completed
Not:
Complete all todos → One big commit → Mark all completed
Branch Safety: Never Commit Directly to main/master
CRITICAL: Before making any commits, verify you're on the correct branch.
Pre-Commit Branch Check
# Always check current branch first
git branch --show-current
Rules:
- ✅ NEVER commit directly to
mainormasterbranches - ✅ ALWAYS work on a feature/topic branch
- ✅ ASK the user about the branch if uncertain
Branch Workflow
Before starting work:
# Check current branch
git branch --show-current
# If on main/master, ask user:
# "I see you're on the main branch. Should I create a feature branch
# or switch to an existing one before making changes?"
If user hasn't specified a branch:
- Ask which branch to use
- Suggest creating a descriptive branch name based on the work
- Wait for confirmation before committing
Example dialogue:
User: "Please fix the bug in authentication.py"
Assistant: "I see you're currently on the main branch. Should I create
a new branch like 'fix-authentication-bug' for these changes, or would
you like to use an existing branch?"
Creating Feature Branches
# Create and switch to new branch
git checkout -b feature-name
# Verify you're on the new branch
git branch --show-current
Branch naming conventions:
- Use descriptive names:
fix-auth-bugnotfix1 - Use hyphens:
add-user-featurenotadd_user_feature - Be specific:
fix-timestamp-parsingnotfixes
Checking Branch Suitability
Before committing to an existing branch, verify it's suitable for the current work:
When you're about to commit changes:
- Check the current branch name
- Assess if the work matches the branch purpose
- If uncertain or mismatched, ask the user
When to ask about branching:
- Current branch name doesn't match the work being done
- Example: On
fix/calendar-stdlib-shadowingbut working on a different issue
- Example: On
- Work is independent and could be a separate PR
- Example: Removing duplicate code (separate concern from renaming modules)
- Preferring to branch from master/main for independence
- Allows PRs to be merged independently without dependencies
Example dialogue:
Assistant: "I notice we're on branch 'fix/calendar-stdlib-shadowing' which is for
renaming the calendar module. The current fix (removing duplicate format_canvas_time)
is a separate concern. Should I:"
Options presented to user:
1. "Create new branch from master" - For independent PR, cleaner separation
2. "Create new branch from current" - If this fix depends on the rename
3. "Use current branch" - Group related cleanup together in one PR
Benefits of proper branching:
- Independent PRs - Each fix can be reviewed and merged separately
- Clearer history - Branch names accurately describe their changes
- Easier rollback - Can revert one fix without affecting others
- Better collaboration - Multiple people can work on different branches
Branching strategy preference:
- Branch from master/main when possible - Makes PRs independent
- Branch from feature branch only when - The new work depends on uncommitted changes
- Use current branch only when - Changes are closely related and belong together
Exception: Repository-Specific Workflows
Some repositories may allow direct commits to main (e.g., personal notes, documentation repos). In these cases:
- User will explicitly confirm it's acceptable
- Still follow atomic commit practices
- Consider the repository's workflow
Checklist for Each Commit
Before committing, verify:
- On correct branch - Not on main/master (unless explicitly approved)
- This commit represents ONE logical change
- The commit message clearly describes what changed
- All related changes are included (nothing missing)
- No unrelated changes are included (nothing extra)
- The code works/builds at this commit (if applicable)
- The commit can be understood independently
- No generated files - If literate programming project, verify no .py/.tex files with .nw sources are staged
Special Case: Literate Programming Projects
CRITICAL WARNING: In literate programming projects (using noweb, .nw files), NEVER commit generated files.
Pre-Commit Validation for Literate Projects
Before committing in a project with .nw files:
# Check what's staged
git diff --staged --name-only
# Look for generated files that shouldn't be committed
# A file is generated if there's a corresponding .nw file
Common Mistake: Committing Generated Files
BAD - Committing generated files:
✗ git add src/module.py # Generated from module.nw - DO NOT COMMIT
✗ git add src/module.tex # Generated from module.nw - DO NOT COMMIT
✗ git commit -m "Update module"
GOOD - Only committing source:
✓ git add src/module.nw # Source file - OK to commit
✓ git commit -m "Update module to add new feature"
Identifying Generated Files
A .py or .tex file is generated (DO NOT COMMIT) if:
- There's a corresponding .nw file with same base name
- It's listed in a Makefile as a target from notangle/noweave
- The project uses literate programming
A .py file is source (OK to commit) if:
- No .nw file exists with same name
- It's a hand-written file (like some
__init__.pyfiles) - It's explicitly marked as an exception in .gitignore
Fixing Accidentally Committed Generated Files
If you discover generated files in git:
# Untrack but keep in working directory
git rm --cached path/to/generated.py
git rm --cached path/to/generated.tex
# Update .gitignore to prevent future accidents
# Then commit the .gitignore changes
git add .gitignore
git commit -m "Remove generated files from version control"
# Regenerate fresh files from .nw sources
make
Integration with Literate Programming Workflow
In literate programming projects:
- Edit .nw files - Make changes to literate source
- Regenerate code - Run
makeornotangleto generate .py/.tex - Test the changes - Verify generated code works
- Commit ONLY .nw - Never commit the generated files
- Let .gitignore work - Ensure .gitignore covers all generated files
Recovery from Large Commits
If you've already made a large commit with multiple concerns:
Option 1: Accept and Move Forward
- Learn from it for future commits
- Don't amend/rewrite if already pushed
Option 2: Split with Interactive Rebase (if not pushed)
# Reset to before the commit
git reset HEAD~1
# Stage and commit each logical piece
git add -p
git commit -m "First logical change"
git add -p
git commit -m "Second logical change"
Summary
Remember:
- Commit early and often - After each logical unit of work
- One concern per commit - Each commit is independently reviewable
- Good messages - Future you (and reviewers) will thank you
- Before refactoring - Save working state first
- Stop and commit - When any red flag appears
The mantra: "Working state reached → Commit now → Continue working"
Didn't find tool you were looking for?