mcpField
C
commit-hygiene

commit-hygiene

github.com/alinaqi开发711334 次安装2 周前更新
代码仓库

关于 commit-hygiene

commit-hygiene 是帮助开发者保持 Git 提交精简、变更聚焦并让 PR 易于审查的技能。它通过变更规模阈值、提交时机提示和拆分策略规范开发过程。

主要功能

  1. 01按文件数和代码行数评估变更规模
  2. 02提示适合提交的时机
  3. 03指导将大型变更拆分为原子提交
  4. 04提供 PR 大小和提交信息规范
  5. 05支持分块暂存与提交前检查
  6. 06为 Claude 提供定期提交提醒规则

适用场景

  1. 01开发过程中判断何时创建检查点提交
  2. 02将跨层或多功能变更拆分提交
  3. 03创建 PR 前检查变更规模
  4. 04用 git add -p 选择提交内容

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/alinaqi/maggy --skill commit-hygiene

安装后在 Claude Code 中输入/commit-hygiene确认已加载。

详细介绍

提交规范技能

目的: 保持提交原子化、PR 易于审查,并维护整洁的 Git 历史。在变更规模过大之前,及时提醒提交。


核心理念

┌─────────────────────────────────────────────────────────────────┐
│  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.           │
└─────────────────────────────────────────────────────────────────┘

提交规模阈值

警告阈值(该提交了!)
指标黄色区间红色区间操作
变更文件数5-10 个文件> 10 个文件立即提交
新增行数150-300 行> 300 行立即提交
删除行数100-200 行> 200 行立即提交
总变更行数250-400 行> 400 行立即提交
距上次提交的时间30-60 分钟> 60 分钟考虑提交
理想提交规模
┌─────────────────────────────────────────────────────────────────┐
│  IDEAL COMMIT                                                    │
│  ─────────────────────────────────────────────────────────────  │
│  Files: 1-5                                                      │
│  Lines: 50-200 total changes                                     │
│  Scope: Single logical unit of work                              │
│  Message: Describes ONE thing                                    │
└─────────────────────────────────────────────────────────────────┘

检查当前状态(经常运行)

快速状态检查
# 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(-)
详细变更分析
# 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
提交前检查脚本
#!/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

何时提交

提交触发条件(满足任意一项即可提交)
触发条件示例
测试通过刚让测试变绿 → 提交
功能完成完成一个函数 → 提交
重构完成在多个文件中重命名变量 → 提交
Bug 修复修复问题 → 提交
切换上下文前准备开始处理其他事情 → 提交
编译通过代码顺利通过编译/lint 检查 → 提交
达到阈值> 5 个文件或 > 200 行 → 提交
以下情况应立即提交
  • ✅ 测试从失败变为通过
  • ✅ 即将进行“大幅变更”
  • ✅ 已连续编码 30 分钟以上
  • ✅ 即将尝试有风险的操作
  • ✅ 当前状态“可用”
不要等到
  • ❌ 代码“完美”
  • ❌ 所有功能都完成
  • ❌ 测试覆盖率完整
  • ❌ 自己完成代码审查
  • ❌ 文档编写完成

原子提交模式

良好的原子提交
✅ "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
不好的提交(规模过大)
❌ "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

拆分大型变更

策略 1:按层拆分
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"
策略 2:按功能切片拆分
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"
策略 3:先重构
Instead of:
  - Feature + refactoring mixed

Split into:
  1. "Refactor: Extract validation helpers" (no behavior change)
  2. "Add email validation using new helpers" (new feature)
策略 4:按风险等级拆分
Instead of:
  - Safe changes + risky changes together

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

PR 规模指南

最佳 PR 规模
指标最佳可接受过大
文件数1-1010-20> 20
变更行数50-200200-400> 400
提交数1-55-10> 10
审查时间< 30 分钟30-60 分钟> 60 分钟
PR 规模与缺陷率
┌─────────────────────────────────────────────────────────────────┐
│  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.          │
└─────────────────────────────────────────────────────────────────┘
PR 过大时
# 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

提交消息格式

结构
<type>: <description> (50 chars max)

[optional body - wrap at 72 chars]

[optional footer]
类型
类型用途
feat新功能
fixBug 修复
refactor既不修复问题也不添加功能的代码变更
test添加/更新测试
docs仅更新文档
style格式调整,不涉及代码变更
chore构建、配置、依赖项
示例
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 工作流

提交前钩子:检查规模
#!/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"
部分暂存(拆分大型变更)
# 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 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 集成

开发期间定期检查

Claude 应在每次重大变更后运行此检查:

# Quick status
git diff --shortstat HEAD

Claude 提醒提交的阈值:

条件Claude 操作
变更文件数 > 5建议:“考虑提交当前变更”
变更行数 > 200建议:“变更规模正在增大,建议提交”
文件数 > 10 或行数 > 400警告:“⚠️ 请立即提交,避免变更变得难以管理”
测试刚刚通过建议:“这是个不错的检查点——提交这些通过测试的变更”
重构完成建议:“重构已完成——添加功能前先提交”
Claude 提交提醒消息
📊 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"

堆叠式 PR(适用于大型功能)

如果某项功能确实规模很大,请使用堆叠式 PR:

┌─────────────────────────────────────────────────────────────────┐
│  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                                   │
└─────────────────────────────────────────────────────────────────┘
创建堆叠式 PR
# 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...

检查清单

每次提交前
  • 更改只涉及一个逻辑目的
  • 测试通过(如适用)
  • Lint/类型检查通过
  • 修改文件数 < 10
  • 总行数 < 400
  • 提交消息只描述一件事
创建 PR 前
  • 总行数 < 400(理想情况下 < 200)
  • 所有提交都是原子性的
  • 没有“WIP”或“fixup”提交
  • PR 标题描述了更改
  • 描述解释了原因,而不只是说明做了什么
危险信号(停止并拆分)
  • ❌ 提交消息中需要使用“和”
  • ❌ 单次提交涉及 > 10 个文件
  • ❌ 单次提交涉及 > 400 行
  • ❌ 混合了功能、修复和重构
  • ❌ “我以后再整理”

快速参考

阈值
Files:  ≤ 5 = 🟢  |  6-10 = 🟡  |  > 10 = 🔴
Lines:  ≤ 200 = 🟢  |  201-400 = 🟡  |  > 400 = 🔴
Time:   ≤ 30min = 🟢  |  30-60min = 🟡  |  > 60min = 🔴
命令
# 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
符合以下情况时立即提交
  • ✅ 测试刚刚通过
  • ✅ 更改行数 > 200
  • ✅ 更改文件数 > 5
  • ✅ 即将切换任务
  • ✅ 当前状态为“可用”

评论

支持 Markdown