commit-hygiene
Atomic commits, PR size limits, commit thresholds, stacked PRs
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o commit-hygiene.zip https://jpskill.com/download/21631.zip && unzip -o commit-hygiene.zip && rm commit-hygiene.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/21631.zip -OutFile "$d\commit-hygiene.zip"; Expand-Archive "$d\commit-hygiene.zip" -DestinationPath $d -Force; ri "$d\commit-hygiene.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
commit-hygiene.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
commit-hygieneフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
[Skill 名] commit-hygiene
コミット衛生スキル
目的: コミットをアトミックに保ち、PRをレビューしやすくし、git履歴をきれいに保ちます。変更が大きくなりすぎる前にコミットする時期をアドバイスします。
コア哲学
┌─────────────────────────────────────────────────────────────────┐
│ アトミックなコミット │
│ ───────────────────────────────────────────────────────────── │
│ 1つのコミットにつき1つの論理的な変更。 │
│ 各コミットは自己完結型でデプロイ可能であるべきです。 │
│ 説明に「and」が必要な場合は、分割してください。 │
├─────────────────────────────────────────────────────────────────┤
│ 小さなPRが勝利する │
│ ───────────────────────────────────────────────────────────── │
│ 変更行数400行未満 = 1時間未満でレビュー完了 │
│ 変更行数1000行超 = おそらく形式的な承認か放置される │
│ 小さなPR = より速いレビュー、より少ないバグ、より簡単なリバート │
├─────────────────────────────────────────────────────────────────┤
│ 早くコミットし、頻繁にコミットする │
│ ───────────────────────────────────────────────────────────── │
│ 動作するコードですか?コミットしてください。 │
│ テストはパスしていますか?コミットしてください。 │
│ 「完了」を待たずに、安定したポイントごとにコミットしてください。 │
└─────────────────────────────────────────────────────────────────┘
コミットサイズのしきい値
警告のしきい値 (コミットする時です!)
| メトリック | イエローゾーン | レッドゾーン | アクション |
|---|---|---|---|
| 変更ファイル数 | 5-10ファイル | 10ファイル超 | 今すぐコミット |
| 追加行数 | 150-300行 | 300行超 | 今すぐコミット |
| 削除行数 | 100-200行 | 200行超 | 今すぐコミット |
| 合計変更数 | 250-400行 | 400行超 | 今すぐコミット |
| 最終コミットからの時間 | 30-60分 | 60分超 | コミットを検討 |
理想的なコミットサイズ
┌─────────────────────────────────────────────────────────────────┐
│ 理想的なコミット │
│ ───────────────────────────────────────────────────────────── │
│ ファイル数: 1-5 │
│ 行数: 合計50-200行の変更 │
│ スコープ: 単一の論理的な作業単位 │
│ メッセージ: 1つのことを記述する │
└─────────────────────────────────────────────────────────────────┘
現在の状態を確認する (頻繁に実行)
クイックステータスチェック
# 何が変更されたかを確認 (ステージング済み + 未ステージング)
git status --short
# 変更されたファイルと行数をカウント
git diff --stat
git diff --cached --stat # ステージング済みのみ
# 合計を取得
git diff --shortstat
# 出力例: 8 files changed, 245 insertions(+), 32 deletions(-)
詳細な変更分析
# ファイル名を含む完全な差分サマリー
git diff --stat HEAD
# 数字のみ
git diff --numstat HEAD | awk '{add+=$1; del+=$2} END {print "+"add" -"del" total:"add+del}'
# 変更ファイル数
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
コミットするタイミング
コミットトリガー (いずれか1つ = コミット)
| トリガー | 例 |
|---|---|
| テストがパスする | テストがグリーンになったばかり → コミット |
| 機能が完了する | 関数を完成させた → コミット |
| リファクタリングが完了する | ファイル間で変数をリネームした → コミット |
| バグが修正される | 問題を修正した → コミット |
| コンテキストを切り替える前 | 他の作業に取り掛かる前 → コミット |
| クリーンなコンパイル | コードがコンパイル/lintがクリーン → コミット |
| しきい値に達する | 5ファイル超または200行超 → コミット |
次の場合はすぐにコミットしてください
- ✅ 赤だったテストがパスした
- ✅ 「大きな変更」を行おうとしている
- ✅ 30分以上コーディングしている
- ✅ リスクのあることを試そうとしている
- ✅ 現在の状態が「動作している」
次のことは待たないでください
- ❌ 「完璧な」コード
- ❌ すべての機能が完了すること
- ❌ 完全なテストカバレッジ
- ❌ 自分自身によるコードレビュー
- ❌ ドキュメントの完成
アトミックなコミットパターン
良いアトミックなコミット
✅ "サインアップフォームにメール検証を追加"
- 3ファイル: validator.ts, signup.tsx, signup.test.ts
- 120行変更
- 単一の目的: メール検証
✅ "ユーザー検索のnullポインタを修正"
- 2ファイル: userService.ts, userService.test.ts
- 25行変更
- 単一の目的: 1つのバグを修正
✅ "リファクタリング: PaymentProcessorクラスを抽出"
- 4ファイル: payment.ts → paymentProcessor.ts + types
- 180行変更
- 単一の目的: リファクタリング
悪いコミット (大きすぎる)
❌ "認証を追加し、バグを修正し、スタイルを更新"
- 25ファイル変更
- 800行変更
- 複数の目的が混在
❌ "WIP"
- スコープ不明
- 明確な目的がない
- レビュー/リバートが困難
❌ "更新"
- 15ファイル変更
- 機能、修正、リファクタリングが混在
- 適切にレビューできない
大きな変更を分割する
戦略1: レイヤー別
代わりに
(原文がここで切り詰められています) 📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
Commit Hygiene Skill
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
<type>: <description> (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"