git commit 時に実装を理解しているのか claude code に質問させる

に公開

背景

https://zenn.dev/buno15/articles/81096271c6ce6e
以前、AIエージェントを使用して実装を丸投げすると、コードの理解を怠るといった旨の記事を書きました。ざっくり要約すると以下の内容です。

  • AIエージェントに設計から実装までを丸投げした結果、動く成果物はできたものの、コードのロジックや全体像が頭の中に描けず、「自分が何を作ったのか理解できていない」状態に陥ってしまった。
  • コードの中身を把握していないため、トラブルシューティングで仮説が立てられず解決が遅延。また、なぜその実装にしたのかという「Why」が抜け落ち、チームへの説明やコードレビューの質も低下した。
  • AIは思考をサボるためのツールではなく、思考を広げるために使うべき。仕様や目的の言語化・理解は人間が責任を持ち、自分の言葉で説明できる状態を保った上でAIを活用する必要がある。

そこで、自分がAIに書かせたコードを理解するために、コミット時にAIに実装内容に関する質問リストを作らせて、自分の理解度をチェックするようにしてみました。

Gitの pre-commit フックを活用した「実装理解度チェック」の自動化

コミットのタイミングで自動的にコマンドを実行させるため、Gitの フック機能(Git Hooks) を導入しました。 .git/hooks ディレクトリ内に pre-commit という名前でスクリプトを保存することで、git commit 実行時に任意の処理を割り込ませることができます。

今回は、コミット前に「実装内容の自己理解」を深めるためのチェック工程をAIにサクッと書かせました。

  1. 差分の抽出: git diff --cached を使用し、ステージングされている(コミット予定の)変更内容を取得します。
  2. 質問の生成: claude -p を利用して、変更内容の実装意図に関する質問リストを自動生成します。
  3. エディタの起動: 生成された質問リストをMarkdownファイルにまとめ、私が普段利用している Cursor で開きます。
  4. コミットの制御: Markdown内に「コミットブロック行」を用意します。内容を確認し、その行を削除してファイルを保存・終了すれば、そのままコミットが続行される仕組みです。

これにより、機械的なコミットを防ぎ、実装意図を再確認する習慣を強制的に作ることができます。

{project root}/.git/hooks/pre-commit

#!/bin/bash
export LANG=ja_JP.UTF-8

# 1. 変更がない場合は終了
DIFF=$(git diff --cached)
if [ -z "$DIFF" ]; then exit 0; fi

CHECKLIST_FILE=".git/COMMIT_REVIEW.md"
# ⛔️ この行が残っているとコミットを阻止します
BLOCKER_LINE="⚠️_この行を消すとコミットされます_⚠️"

# 2. ファイル作成
echo "# 🛡️ コミット前確認" > "$CHECKLIST_FILE"
echo "以下のAI指摘を確認してください。" >> "$CHECKLIST_FILE"
echo "" >> "$CHECKLIST_FILE"

echo "$DIFF" | claude -p "
あなたはシニアエンジニアです。
以下のgit diffの内容を見て、実装者がこの変更をコミットする前に
自分自身に問いかけるべき「確認リスト」を3〜5項目、箇条書きで生成してください。
設計意図、なぜそのような実装にしたのか鋭い視点を含めてください。
コードのバグやエッジケースについても言及してください。
出力は箇条書きのリストのみにしてください。挨拶や前置きは不要です。
" >> "$CHECKLIST_FILE"

echo "" >> "$CHECKLIST_FILE"
echo "---------------------------------------------------------" >> "$CHECKLIST_FILE"
echo "## 🚀 アクション" >> "$CHECKLIST_FILE"
echo "内容を確認し、問題なければ**以下の行を削除して**保存・閉じてください。" >> "$CHECKLIST_FILE"
echo "" >> "$CHECKLIST_FILE"

# ブロッカー行を追加
echo "$BLOCKER_LINE" >> "$CHECKLIST_FILE"

# 3. Cursorで開く(待機モード)
cursor --wait "$CHECKLIST_FILE"

# 4. 判定ロジック
# ブロッカー行が「まだ存在する」なら中止、「消えている」なら実行
if grep -q "$BLOCKER_LINE" "$CHECKLIST_FILE"; then
    echo "❌ 解除行が残っているため、コミットを中止しました。"
    rm "$CHECKLIST_FILE"
    exit 1
else
    echo "✅ コミットを実行します。"
    rm "$CHECKLIST_FILE"
    exit 0
fi

感想

コミット毎に理解度チェックが走るので、常に実装意図を意識することができます。「なぜこの実装にしたのか?」と問われることで、設計の妥当性を再確認できます。一方明らかに軽微な変更の場合にも理解度チェックが走るので、少々手間が増えるのが欠点です。スキップ機能があると便利かもしれません。

Discussion