commit-hygiene

安装量: 111
排名: #7697

安装

npx skills add https://github.com/alinaqi/claude-bootstrap --skill commit-hygiene

Commit Hygiene Skill

Load with: base.md

Purpose: Keep commits atomic, PRs reviewable, and git history clean. Advise when it's time to commit before changes become too large.

Core Philosophy ┌─────────────────────────────────────────────────────────────────┐ │ ATOMIC COMMITS │ │ ───────────────────────────────────────────────────────────── │ │ One logical change per commit. │ │ Each commit should be self-contained and deployable. │ │ If you need "and" to describe it, split it. │ ├─────────────────────────────────────────────────────────────────┤ │ SMALL PRS WIN │ │ ───────────────────────────────────────────────────────────── │ │ < 400 lines changed = reviewed in < 1 hour │ │ > 1000 lines = likely rubber-stamped or abandoned │ │ Smaller PRs = faster reviews, fewer bugs, easier reverts │ ├─────────────────────────────────────────────────────────────────┤ │ COMMIT EARLY, COMMIT OFTEN │ │ ───────────────────────────────────────────────────────────── │ │ Working code? Commit it. │ │ Test passing? Commit it. │ │ Don't wait for "done" - commit at every stable point. │ └─────────────────────────────────────────────────────────────────┘

Commit Size Thresholds Warning Thresholds (Time to Commit!) Metric Yellow Zone Red Zone Action Files changed 5-10 files > 10 files Commit NOW Lines added 150-300 lines > 300 lines Commit NOW Lines deleted 100-200 lines > 200 lines Commit NOW Total changes 250-400 lines > 400 lines Commit NOW Time since last commit 30-60 min > 60 min Consider committing Ideal Commit Size ┌─────────────────────────────────────────────────────────────────┐ │ IDEAL COMMIT │ │ ───────────────────────────────────────────────────────────── │ │ Files: 1-5 │ │ Lines: 50-200 total changes │ │ Scope: Single logical unit of work │ │ Message: Describes ONE thing │ └─────────────────────────────────────────────────────────────────┘

Check Current State (Run Frequently) Quick Status Check

See what's changed (staged + unstaged)

git status --short

Count files and lines changed

git diff --stat git diff --cached --stat # Staged only

Get totals

git diff --shortstat

Example output: 8 files changed, 245 insertions(+), 32 deletions(-)

Detailed Change Analysis

Full diff summary with file names

git diff --stat HEAD

Just the numbers

git diff --numstat HEAD | awk '{add+=$1; del+=$2} END {print "+"add" -"del" total:"add+del}'

Files changed count

git status --porcelain | wc -l

Pre-Commit Check Script

!/bin/bash

scripts/check-commit-size.sh

Thresholds

MAX_FILES=10 MAX_LINES=400 WARN_FILES=5 WARN_LINES=200

Get stats

FILES=$(git status --porcelain | wc -l | tr -d ' ') STATS=$(git diff --shortstat HEAD 2>/dev/null) INSERTIONS=$(echo "$STATS" | grep -oE '[0-9]+ insertion' | grep -oE '[0-9]+' || echo 0) DELETIONS=$(echo "$STATS" | grep -oE '[0-9]+ deletion' | grep -oE '[0-9]+' || echo 0) TOTAL=$((INSERTIONS + DELETIONS))

echo "📊 Current changes: $FILES files, +$INSERTIONS -$DELETIONS ($TOTAL total lines)"

Check thresholds

if [ "$FILES" -gt "$MAX_FILES" ] || [ "$TOTAL" -gt "$MAX_LINES" ]; then echo "🔴 RED ZONE: Commit immediately! Changes are too large." echo " Consider splitting into multiple commits." exit 1 elif [ "$FILES" -gt "$WARN_FILES" ] || [ "$TOTAL" -gt "$WARN_LINES" ]; then echo "🟡 WARNING: Changes getting large. Commit soon." exit 0 else echo "🟢 OK: Changes are within healthy limits." exit 0 fi

When to Commit Commit Triggers (Any One = Commit) Trigger Example Test passes Just got a test green → commit Feature complete Finished a function → commit Refactor done Renamed variable across files → commit Bug fixed Fixed the issue → commit Before switching context About to work on something else → commit Clean compile Code compiles/lints clean → commit Threshold hit > 5 files or > 200 lines → commit Commit Immediately If ✅ Tests are passing after being red ✅ You're about to make a "big change" ✅ You've been coding for 30+ minutes ✅ You're about to try something risky ✅ The current state is "working" Don't Wait For ❌ "Perfect" code ❌ All features done ❌ Full test coverage ❌ Code review from yourself ❌ Documentation complete Atomic Commit Patterns Good Atomic Commits ✅ "Add email validation to signup form" - 3 files: validator.ts, signup.tsx, signup.test.ts - 120 lines changed - Single purpose: email validation

✅ "Fix null pointer in user lookup" - 2 files: userService.ts, userService.test.ts - 25 lines changed - Single purpose: fix one bug

✅ "Refactor: Extract PaymentProcessor class" - 4 files: payment.ts → paymentProcessor.ts + types - 180 lines changed - Single purpose: refactoring

Bad Commits (Too Large) ❌ "Add authentication, fix bugs, update styles" - 25 files changed - 800 lines changed - Multiple purposes mixed

❌ "WIP" - Unknown scope - No clear purpose - Hard to review/revert

❌ "Updates" - 15 files changed - Mix of features, fixes, refactors - Impossible to review properly

Splitting Large Changes Strategy 1: By Layer Instead of one commit with: - API endpoint + database migration + frontend + tests

Split into: 1. "Add users table migration" 2. "Add User model and repository" 3. "Add GET /users endpoint" 4. "Add UserList component" 5. "Add integration tests for user flow"

Strategy 2: By Feature Slice Instead of one commit with: - All CRUD operations for users

Split into: 1. "Add create user functionality" 2. "Add read user functionality" 3. "Add update user functionality" 4. "Add delete user functionality"

Strategy 3: Refactor First Instead of: - Feature + refactoring mixed

Split into: 1. "Refactor: Extract validation helpers" (no behavior change) 2. "Add email validation using new helpers" (new feature)

Strategy 4: By Risk Level Instead of: - Safe changes + risky changes together

Split into: 1. "Update dependencies" (safe, isolated) 2. "Migrate to new API version" (risky, separate)

PR Size Guidelines Optimal PR Size Metric Optimal Acceptable Too Large Files 1-10 10-20 > 20 Lines changed 50-200 200-400 > 400 Commits 1-5 5-10 > 10 Review time < 30 min 30-60 min > 60 min PR Size vs Defect Rate ┌─────────────────────────────────────────────────────────────────┐ │ RESEARCH FINDINGS (Google, Microsoft studies) │ │ ───────────────────────────────────────────────────────────── │ │ PRs < 200 lines: 15% defect rate │ │ PRs 200-400 lines: 23% defect rate │ │ PRs > 400 lines: 40%+ defect rate │ │ │ │ Review quality drops sharply after 200-400 lines. │ │ Large PRs get "LGTM" rubber stamps, not real reviews. │ └─────────────────────────────────────────────────────────────────┘

When PR is Too Large

Check PR size before creating

git diff main --stat git diff main --shortstat

If too large, consider:

1. Split into multiple PRs (stacked PRs)

2. Create feature flag and merge incrementally

3. Use draft PR for early feedback

Commit Message Format Structure : (50 chars max)

[optional body - wrap at 72 chars]

[optional footer]

Types Type Use For feat New feature fix Bug fix refactor Code change that neither fixes nor adds test Adding/updating tests docs Documentation only style Formatting, no code change chore Build, config, dependencies Examples feat: Add email validation to signup form

fix: Prevent null pointer in user lookup

refactor: Extract PaymentProcessor class

test: Add integration tests for checkout flow

chore: Update dependencies to latest versions

Git Workflow Integration Pre-Commit Hook for Size Check

!/bin/bash

.git/hooks/pre-commit

MAX_LINES=400 MAX_FILES=15

FILES=$(git diff --cached --name-only | wc -l | tr -d ' ') STATS=$(git diff --cached --shortstat) INSERTIONS=$(echo "$STATS" | grep -oE '[0-9]+ insertion' | grep -oE '[0-9]+' || echo 0) DELETIONS=$(echo "$STATS" | grep -oE '[0-9]+ deletion' | grep -oE '[0-9]+' || echo 0) TOTAL=$((INSERTIONS + DELETIONS))

if [ "$TOTAL" -gt "$MAX_LINES" ]; then echo "❌ Commit too large: $TOTAL lines (max: $MAX_LINES)" echo " Consider splitting into smaller commits." echo " Use 'git add -p' for partial staging." exit 1 fi

if [ "$FILES" -gt "$MAX_FILES" ]; then echo "❌ Too many files: $FILES (max: $MAX_FILES)" echo " Consider splitting into smaller commits." exit 1 fi

echo "✅ Commit size OK: $FILES files, $TOTAL lines"

Partial Staging (Split Large Changes)

Stage specific hunks interactively

git add -p

Stage specific files

git add path/to/specific/file.ts

Stage with preview

git add -N file.ts # Intent to add git diff # See what would be added git add file.ts # Actually add

Unstage If Too Large

Unstage everything

git reset HEAD

Unstage specific files

git reset HEAD path/to/file.ts

Stage just what you need for THIS commit

git add -p

Claude Integration Periodic Check During Development

Claude should run this check after every significant change:

Quick status

git diff --shortstat HEAD

Thresholds for Claude to advise committing:

Condition Claude Action

5 files changed Suggest: "Consider committing current changes" 200 lines changed Suggest: "Changes are getting large, commit recommended" 10 files OR > 400 lines Warn: "⚠️ Commit now before changes become unmanageable" Test just passed Suggest: "Good checkpoint - commit these passing tests" Refactoring complete Suggest: "Refactoring done - commit before adding features" Claude Commit Reminder Messages 📊 Status: 7 files changed, +180 -45 (225 total) 💡 Approaching commit threshold. Consider committing current work.


📊 Status: 12 files changed, +320 -80 (400 total) ⚠️ Changes are large! Commit now to keep PRs reviewable. Suggested commit: "feat: Add user authentication flow"


📊 Status: 3 files changed, +85 -10 (95 total) ✅ Tests passing. Good time to commit! Suggested commit: "fix: Validate email format on signup"

Stacked PRs (For Large Features)

When a feature is genuinely large, use stacked PRs:

┌─────────────────────────────────────────────────────────────────┐ │ STACKED PR PATTERN │ │ ───────────────────────────────────────────────────────────── │ │ │ │ main ─────────────────────────────────────────────────────────│ │ └── PR #1: Database schema (200 lines) ← Review first │ │ └── PR #2: API endpoints (250 lines) ← Review second │ │ └── PR #3: Frontend (300 lines) ← Review third │ │ │ │ Each PR is reviewable independently. │ │ Merge in order: #1 → #2 → #3 │ └─────────────────────────────────────────────────────────────────┘

Creating Stacked PRs

Create base branch

git checkout -b feature/auth-schema

... make changes ...

git commit -m "feat: Add users table schema" git push -u origin feature/auth-schema gh pr create --base main --title "feat: Add users table schema"

Create next branch FROM the first

git checkout -b feature/auth-api

... make changes ...

git commit -m "feat: Add authentication API endpoints" git push -u origin feature/auth-api gh pr create --base feature/auth-schema --title "feat: Add auth API endpoints"

And so on...

Checklist Before Every Commit Changes are for ONE logical purpose Tests pass (if applicable) Lint/typecheck pass < 10 files changed < 400 lines total Commit message describes ONE thing Before Creating PR Total lines < 400 (ideal < 200) All commits are atomic No "WIP" or "fixup" commits PR title describes the change Description explains why, not just what Red Flags (Stop and Split) ❌ Commit message needs "and" ❌ > 10 files in one commit ❌ > 400 lines in one commit ❌ Mix of features, fixes, and refactors ❌ "I'll clean this up later" Quick Reference Thresholds Files: ≤ 5 = 🟢 | 6-10 = 🟡 | > 10 = 🔴 Lines: ≤ 200 = 🟢 | 201-400 = 🟡 | > 400 = 🔴 Time: ≤ 30min = 🟢 | 30-60min = 🟡 | > 60min = 🔴

Commands

Quick status

git diff --shortstat HEAD

Detailed file list

git diff --stat HEAD

Partial staging

git add -p

Check before PR

git diff main --shortstat

Commit Now If ✅ Tests just passed ✅ > 200 lines changed ✅ > 5 files changed ✅ About to switch tasks ✅ Current state is "working"

返回排行榜