こんにちは。ikedaです。

昨今、生成AIにコードを書かせる開発が当たり前になってきました。書く速度は確かに上がっています。 一方で、その成果物を人間がレビューする負荷は、むしろ上がっている気がします。理由のひとつがコミット履歴です。AIは細かくコミットしがちで、放っておくと履歴が追いにくくなります。

この記事では、AIを使った開発でレビューしやすさを保つために自分が気をつけていることと、その対策をまとめます。 やること自体は「作業中は細かく、レビューに出す前に意味のかたまりへ整える」というだけで、目新しい話ではありません。ただ、AIを使うとこの整形がサボられやすいので、そこをどう仕組みで埋めるかを中心に書きます。

コミットの粒度をどう考えているか

出発点はシンプルで、コミット粒度はレビューしやすい粒度にしたい、という願いです。ただこれを突き詰めると、少し整理が必要になります。

PRを見るとき、コミットが細かすぎると、結局は全コミットの差分をまとめて比較することになります。レビューの単位は、多くの場合コミットではなくPR全体だからです。typo修正のような小さな変更ならコミットが細かくても気になりませんが、機能追加のように差分が大きくなりやすい変更だと、履歴が散らかっていると一気につらくなります。

私は差分が大きいときこそ、意味のかたまりで分割したい派です。例えば「リファクタ → 土台の追加 → 機能本体 → テスト」とコミットが分かれていれば、レビュアーはコミットを順に追うだけで、書き手の思考の道筋を再現できます。私は大きい変更ほど、順番に意味があると考えています。

「細かいコミット」自体は悪ではない

一方で細かいコミットには、差分の見やすさとは別の場面で効く価値があります。

  • git bisect で問題箇所を二分探索するとき
  • git revert で特定の変更だけ巻き戻すとき
  • git blame で「なぜこの行がこうなったか」を追うとき
  • レビューで「この一連の変更だけ意図を知りたい」とき

つまり履歴は、差分を眺めるためだけにあるのではなく、あとから変更を辿り、戻し、説明するための記録でもあります。PRを上から下まで読む体験だけを基準にすると、この価値を見落としてしまいます。 なので問題は「細かいこと」そのものではなく、作業中の粒度のまま出してしまうこと、だと考えます。そのため後でレビュー用に整えるときも、コミット数を減らすことを目的とするのではなく、ひとつひとつを意味のかたまりとして自己完結させることを目的とします。数を潰すのではなく区切り直す、と考えれば、ここで挙げた bisect・revert・blame の価値も損なわずに済みます。

作業用とレビュー用の粒度を分ける

やっていることはシンプルで、作業中の粒度とレビュー用の粒度を分けるだけです。これ自体は昔から言われている話だと思います。 作業中は細かくコミットしてもよく、むしろ細かいほうが、手戻りや部分的なやり直し、git bisect に有利です。そのうえで、レビューに出す前(push する前)に、コミットを意味のかたまりへ整えています。

作業ログとレビュー用の履歴は、別ものとして割り切ります。前者は自分のための足跡なので、多少散らかっていて構いません。一方、後者はレビュアーに読ませる成果物なので、書き手が責任を持って編集する。この2つを分けて考えるだけで、悩みの大半はなくなります。

生成AI時代は、この工程の重要性が増している

ここまでは人間の手作業でも成り立つ話ですが、生成AIを使うと事情が一段シビアになります。

AIはステップごとに動作確認しながら進める性質上、各ステップを区切ってコミットするのが自然で、結果として「wip」「fix」「やっぱり戻す」といったコミットを量産しがちです。これ自体は前述のとおり悪ではありません。問題は、AIが整形工程を行わないことです。明示的に指示しない限り、散らかった作業コミットのままレビューに出すことになります。

裏を返せば、AIを使うほど「出す前に意味のかたまりへ整える」工程の価値は上がります。人間が手で細かくコミットしていた時代より、AI時代のほうがこの整形が効きます。そこで、整形を省略させない仕組みを人間の側で用意しておきます。

具体的な対策

対策は二段構えにしています。なるべく散らからせない上流の工夫と、最後に確実に整える下流の工夫です。

上流:AIにマシな粒度で刻ませる

一番手軽なのは、プロジェクトの CLAUDE.md(AIに常時読ませる指示ファイル)に方針を書いておくことです。たとえば次のような数行を置きます。

## コミット方針
- 論理的な作業単位ごとにコミットする
- conventional commits 形式(feat:, fix:, refactor: など)
- 指示がない限り push しない

「論理的な作業単位ごと」と書いておくと、1行ごとに刻むことも、最後まで溜め込むこともなく、ほどよい区切りでコミットしてくれます。

下流:push 前に意味のかたまりへ整える

それでも作業の過程では wip コミットが残ります。そこで push 前に整形します。手順は CLAUDE.md にまとめておき、AIにも人間にも同じ手順を踏ませます。

ここで一点注意があります。手で整形するなら git rebase -i が定番ですが、-iはエディタを立ち上げて人間が pick/squash を編集する前提のコマンドで、AIにそのまま実行させるのは向きません。AIに任せるなら、エディタを介さない形にしておくほうが確実です。一番単純なのは git reset <base> で一旦コミットをほどき、そこから意味のかたまりごとに git add して git commit し直す方法です。rebase -i の対話操作を避けられるぶん、AIにも扱いやすくなります。

例えば以下のような感じです。

## push 前のコミット整形
- push する前に、wip/fix/typo コミットを意味のかたまりへ整理する
- まずバックアップ用ブランチを切る: git branch backup/<branch>
- git reset <base> でコミットをほどく(変更はワークツリーに戻る)
- 意味のかたまりごとに git add(部分的に拾うなら git add -p)→ git commit し直す
- 整形後、git diff <base>..HEAD が整形前と一致するか確認する(取りこぼし防止)
- まだ push していない前提なので force-push は不要
- もし upstream が既にある場合は、一旦止めて確認する

工夫点は安全側に倒すことです。履歴の書き換えは壊すと痛いので、「うまく分ける」ことより「壊さない・戻せる」ことを優先します。

  • 整形前にバックアップを作り(git branch backup/<branch>)、失敗したら git reset --hard backup/<branch> で戻す
  • 整形後に正味の差分が変わっていないか確認する。git diff <base>..HEAD が整形前と一致していれば、取りこぼしはありません。

skill にするという選択肢

整形手順が育ってきたら、Claude Code の skill として切り出す手もあります。skill は呼ばれたときだけ中身が読まれるので、整形しないセッションではコンテキストを消費しません。

ただし skill は description にマッチして初めて発動します。簡単なタスクだと呼ばれないこともあるので、「確実に効かせたい」なら常駐する CLAUDE.md のほうが向いています。手順が数行のうちは CLAUDE.md、preview 機能や分割ロジックなどを盛り込んで長くなってきたら skill へ引っ越す、という順序が現実的だと思います。

ちなみに、コミット整形や rebase を支援する skill は、コミュニティのマーケットプレイスにいくつか存在します。自分で作り込む前に、既存のもので要件を満たせるか見てみるのも手です。多くは「複数コミットを1つに潰す(squash)」方向に寄っているので、「意味のかたまりへ分け直したい」用途を重視するなら、その観点で選ぶといいです。

まとめ

AIと開発するときに人間のレビュー負荷を下げるために意識しているのは、結局これだけです。

  • コミット粒度はレビューしやすさを基準に考える
  • ただし「作業中の粒度」と「レビュー用の粒度」は分ける
  • 作業中は細かくていい(手戻りや bisect に有利)
  • レビュー(push)に出す前に、意味のかたまりへ整える
  • AIは整形を行わないので、この工程はAI時代こそ大事
  • 対策は二段構え:上流は CLAUDE.md で誘導、下流は push 前に意味のかたまりへ整形(履歴整形)
  • 整形は安全第一(バックアップ・差分チェック・push 前だけ)

履歴は、未来の自分とレビュアーへのメモのようなものです。AIで書くのが速くなったものの、現時点では、品質管理の観点でまだ人間が介在する必要性を感じています。人間が読みやすく保つための工夫をし、今後もAIの力を最大限生かす仕組みを整えていきたいです。