0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Claude Code のコミットを100行以内に分けさせる

0
Posted at

Claude Code に「全モジュールに〜を追加して」と頼むと、数百行の変更が1つのコミットにまとまって出てきます。レビューする側は一度に読み切れません。AI が書く量が増えるほど、レビューの詰まりは「読む人の注意力」ではなく「変更の切り方」の問題になります。

変更を小さく分けさせる方法として、CLAUDE.md への指示と git の pre-commit フックを実際に動かし、コミットの大きさを測りました。

結論

  • 何もしないと:1コミット 298 行・426 行(2回とも一括)
  • CLAUDE.md に「1コミット100行以内」:2回とも6コミットに分割、最大 59 行・66 行。ただし依頼で「まとめて1つのコミットに」と言うと、1回は 139 行で上限を超えた(「あなたの指示を優先した」と説明つき)
  • git の pre-commit フックで100行超を拒否:2回とも、最初の一括コミットが拒否されたあと自分で6つに分割(最大 76 行・80 行)。「まとめて1つに」と言われても、2回ともコミットせずに止まって判断を求めた。--no-verify での回避は0回
  • ただしコミットを分けても PR 全体の行数は減りません(300〜430 行のまま)。PR 単位で絞りたいなら、PR の差分を測る仕組みが別に要ります

指示(CLAUDE.md)は「普段の分け方」を決めるのには効き、依頼とぶつかると負けることがあります。超えさせたくないなら、git フックのような外側の仕組みで止めるのが確実でした。

環境

  • 2026-10-11、Linux、Claude Code 2.1.296、git、Node.js 22(node --test)
  • claude -p "<依頼>" --allowedTools "Bash Edit Write Read Glob Grep" --max-turns 60(非対話モード、モデルは既定)
  • 毎回まっさらなリポジトリを作り直して実行

試した題材

src/ に同じ形の5モジュール(cart, user, order, invoice, shipping)があるだけのリポジトリです。各モジュールはこの4関数です。

// cart module
function create(data) { return { id: Date.now(), ...data }; }
function update(obj, patch) { return { ...obj, ...patch }; }
function total(items) { return items.reduce((s, i) => s + i.price * i.qty, 0); }
function find(list, id) { return list.find(x => x.id === id); }
module.exports = { create, update, total, find };

依頼文:

src/ の5つのモジュールすべてに、引数の入力検証(型・必須項目・負の数)とエラー処理を追加し、node:test で各モジュールのテストも書いてください。npm test が通ったら git にコミットしてください。

試した仕組み

1. CLAUDE.md に書く

# 変更の大きさ
- 1コミットの変更は追加・削除の合計100行以内にする(`git diff --cached --shortstat` で確認してからコミットする)
- 100行を超えそうなら、意味のまとまりごとに分けて複数のコミットにする

2. git の pre-commit フック

Claude Code の設定ではなく、git 自体の仕組みです。.git/hooks/pre-commit に置いて実行権限を付けます。

#!/bin/sh
# 1コミットの変更行数(追加+削除)が上限を超えたら拒否する
LIMIT=100
n=$(git diff --cached --numstat | awk '{a+=$1; d+=$2} END {print a+d+0}')
if [ "$n" -gt "$LIMIT" ]; then
  echo "pre-commit: この変更は ${n} 行です(上限 ${LIMIT} 行)。コミットを分割してください。" >&2
  exit 1
fi

.git/hooks/ は git で共有されないので、チームで使うなら husky などで配るか、git config core.hooksPath でリポジトリ内のディレクトリを指すようにします。

結果:分け方を指定しない依頼

行数はコミットごとの追加+削除(git show --numstat)。テストは実行後に npm test を回した結果です。

仕組み 回 コミット数 最大のコミット 合計 npm test
なし 1 1 298 行 298 行 pass 20 / fail 0
なし 2 1 426 行 426 行 pass 45 / fail 0
CLAUDE.md 1 6 59 行 304 行 pass 24 / fail 0
CLAUDE.md 2 6 66 行 372 行 pass 44 / fail 0
pre-commit 1 6 76 行 421 行 pass 20 / fail 0
pre-commit 2 6 80 行 427 行 pass 45 / fail 0

CLAUDE.md の場合は最初から分けてコミットしました。pre-commit の場合は、まず全部を1つにコミットしようとして拒否され(pre-commit: この変更は 421 行です(上限 100 行))、そのメッセージを見て分け直しています。分け方はどれも同じ形で、git log はこうなりました(pre-commit の1回目):

40753ab Add input validation and tests to user module
 2 files changed, 72 insertions(+), 4 deletions(-)
fd80012 Add input validation and tests to shipping module
 2 files changed, 72 insertions(+), 4 deletions(-)
9b51e0b Add input validation and tests to order module
 2 files changed, 72 insertions(+), 4 deletions(-)
e0b307d Add input validation and tests to invoice module
 2 files changed, 72 insertions(+), 4 deletions(-)
2cf7f7d Add input validation and tests to cart module
 2 files changed, 72 insertions(+), 4 deletions(-)
7684f9e Add shared input validation helpers
 1 file changed, 41 insertions(+)

共通の検証関数を先に1コミット、そのあとモジュールごとに「実装+テスト」で1コミットずつ。レビューしやすい単位です。

結果:依頼が「まとめて1つ」と言った場合

依頼文の最後を「npm test が通ったら、全部まとめて1つのコミットにしてください。」に変えました。

仕組み 回 結果
CLAUDE.md 1 1コミット 139 行(上限超え)
CLAUDE.md 2 1コミット 95 行(上限内に収めた)
pre-commit 1 コミットせずに停止(変更はステージ済み)
pre-commit 2 コミットせずに停止

CLAUDE.md で上限を超えた回の最終応答は、こう説明していました。

このコミットは追加119行・削除20行の計139行で、CLAUDE.md の「1コミット100行以内」を超えています。あなたが「1つのコミットに」と明示したので、そちらを優先(以下略)

pre-commit の回はこうです。

コミットは作成されていません。pre-commit フックが「変更が300行で、上限は100行」として拒否しました。(中略)「全部まとめて1つのコミット」というご指示は、このフックの上限と両立しません。--no-verify でフックを回避するのは、チームのルールを破ることになるのでやっていません。どう進めるか、選んでください。

CLAUDE.md の指示は、目の前の依頼とぶつかると依頼が優先されることがあります。pre-commit フックは超えさせない代わりに、作業が止まって人に判断が戻ります。どちらが望ましいかは運用しだいですが、「上限を必ず守らせたい」なら後者です。

コミットを分けても PR は小さくならない

上の表の「合計」を見てください。分割した場合も 304〜427 行で、何もしない場合と変わりません。コミット単位で読めるようにはなりますが、1つの PR として出せばレビューする量は同じです。

PR そのものを小さくしたいなら、次のどれかが必要です(いずれも今回は試していません)。

  • 依頼を最初から小さくする(「cart モジュールだけ」「共通の検証関数だけ」)
  • push する前に main との差分の合計行数を測り、上限を超えたら止める(pre-push フック)
  • CI で PR の差分行数を測り、超えたら失敗させる

まとめ

やりたいこと 効いたもの
普段から小さくコミットさせる CLAUDE.md の指示(2/2)、pre-commit フック(2/2)
依頼で「まとめて」と言われても上限を守らせる pre-commit フック(2/2 で停止)。CLAUDE.md は 1/2 で超過
PR 全体を小さくする コミット分割では減らない。依頼の粒度か、PR 単位の検査が要る

試していないこと

  • Claude Code の PreToolUse フック(git commit の実行前に行数を測って止める)。git の pre-commit と違い Claude Code の外では効きませんが、Claude だけに課したいときの選択肢です
  • スキル(.claude/skills/)で分割の手順を持たせる方法
  • PR 単位の上限(pre-push フック、CI)
  • 各条件2回だけで、題材も「同じ形の5モジュール」という分けやすいものです。分けにくい変更(1ファイルの大きな書き換えなど)では結果が変わりえます

チームで共有する CLAUDE.md の下書きは、質問に答えるだけで作れる無料ツールでも作れます:https://acerola-tools.acerola.workers.dev/?from=qiita-claude-code-commit-size-guard
本記事は Zenn にも掲載しています:https://zenn.dev/acerola_jp/articles/claude-code-commit-size-guard

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?