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にGit運用を任せる — 巨大コミットを防ぐコミット戦略の型

0
Posted at

Claude Codeに機能を一気に実装させたあと、コミットを任せると、だいたいこうなります。

  • git add -A && git commit -m "fix" で全部まとめて1コミット
  • 1コミットの中にリファクタ・新機能・バグ修正・フォーマット変更が全部入っている
  • 後から「あの変更どこで入れた?」と探しても、巨大な差分に埋もれて見つからない
  • レビューしようにも、+800 −300 行の差分を前に手が止まる
  • いざ revert したいのに、戻したい変更と戻したくない変更が同じコミットに同居している

コードの中身は悪くないのに、コミットの切り方が雑なせいで履歴がゴミになる。これはClaude Codeに限らず、AIに実装を任せるときに必ずぶつかる問題です。

原因はモデルの能力ではありません。「どういう単位でコミットしてほしいか」を伝えていないだけです。Claudeはデフォルトでは「とりあえず全部コミットしておく」を選びます。指示しなければ、人間が一番ラクをするときと同じ選択をするのです。

この記事では、Claude CodeにGit運用を任せつつ、意味のある単位で・レビューしやすく・あとで戻せるコミットを作らせるための型を紹介します。すべてコピペして今日から試せます。


なぜ「巨大コミット」がそんなに悪いのか

「動けばいいじゃん」と思うかもしれません。でも巨大コミットは、未来の自分とチームに確実にツケを回します。

巨大コミットで失うもの 具体的に何が起きるか
revert の安全性 バグった変更だけ戻したいのに、同じコミットの正常な変更まで巻き戻る
bisect の精度 git bisect で原因コミットを特定しても、中に10個の変更が入っていて結局どれが犯人か分からない
レビューのしやすさ +800行の差分は誰も真面目に読まない。「LGTM」と雑に通る
履歴の説明力 git log を見ても何をやったか分からない。「fix」「update」「wip」が並ぶ
cherry-pick の自由度 「この修正だけ別ブランチに持っていきたい」が不可能になる

逆に言えば、コミットを意味のある単位で切れているだけで、上のすべてが手に入ります。Gitの強力な機能(revert / bisect / cherry-pick)は、コミットがきれいに切られて初めて使えるのです。

そしてここが重要なのですが、Claude Codeは指示さえあればこれを完璧にやれます。人間が面倒でサボる「こまめなコミット」を、AIは淡々と実行できる。これはむしろAIに任せたほうが品質が上がる領域です。


型1: 「1コミット = 1つの意図」をルールとして渡す

コミット分割の原則はたった1つです。1つのコミットには1つの意図だけを入れる

「意図」とは、コミットメッセージの本文を読まなくても、要約1行で説明しきれる単位のことです。

良い単位(1コミット1意図):
  - ユーザー検索APIを追加
  - 検索APIのバリデーションエラー処理を修正
  - 検索結果コンポーネントのスタイル調整

悪い単位(複数意図が混在):
  - 検索機能まわりいろいろ

これをClaude Codeに守らせるには、CLAUDE.md か、実装を頼むときの指示にルールとして明記します。

CLAUDE.md に書く例:

## コミット規約

- 1コミット = 1つの意図。複数の関心事を1コミットに混ぜない
- リファクタリングと機能追加は必ず別コミットに分ける
- フォーマット・import整理だけの変更は独立したコミットにする
- コミット前に `git diff --staged` の内容が
  コミットメッセージ1行で説明しきれるか自問する

ポイント: 「リファクタと機能追加を分ける」を明示するのが効きます。AIは1回の実装でリファクタと新機能を同時にやりがちで、それをまとめてコミットしてしまうのが巨大コミットの最大要因だからです。

Before(指示なし):

あなた: 「ユーザー検索機能を実装してコミットして」

Claude: (実装後)
$ git add -A
$ git commit -m "add user search"

→ 検索API・バリデーション・UIコンポーネント・
   ついでに直した既存のlintエラーが全部1コミット

After(1コミット1意図を指示):

あなた: 「ユーザー検索機能を実装して。コミットは
        『1コミット1意図』で分割してください」

Claude: (実装後)
$ git add src/api/search.ts
$ git commit -m "feat(api): ユーザー検索エンドポイントを追加"

$ git add src/api/validation.ts
$ git commit -m "feat(api): 検索クエリのバリデーションを追加"

$ git add src/components/SearchResults.tsx
$ git commit -m "feat(ui): 検索結果コンポーネントを追加"

同じ実装でも、後者は git log を見ただけで何をやったか分かります。そして3つ目だけ revert する、といった操作も自由にできます。


型2: Conventional Commits で型を固定する

「意味のあるメッセージを書いて」だけだと、人によって(AIの気分によって)ブレます。フォーマットを固定するなら Conventional Commits が定番です。

形式はシンプルです。

<type>(<scope>): <説明>

[本文(任意)]

[フッター(任意)]

type でよく使うのは次のあたりです。

type 用途
feat 新機能 feat(auth): ログイン画面を追加
fix バグ修正 fix(api): null参照でクラッシュする問題を修正
refactor 挙動を変えないコード整理 refactor(user): 重複ロジックを共通関数に抽出
test テストの追加・修正 test(api): 検索の異常系テストを追加
docs ドキュメントのみ docs: READMEにセットアップ手順を追記
chore ビルド・依存・設定 chore: eslintを9系に更新
style フォーマットのみ(挙動不変) style: prettierでフォーマット

これをCLAUDE.mdに入れておけば、Claude Codeは毎回この型でコミットしてくれます。

## コミットメッセージ規約

Conventional Commits 形式を厳守する:
  <type>(<scope>): <日本語の説明>

- type は feat / fix / refactor / test / docs / chore / style から選ぶ
- scope は変更したモジュール名(api / ui / auth など)
- 説明は「何をしたか」を50字以内で。「〜を追加」「〜を修正」の形
- 挙動を変えない整形は必ず refactor か style にする(feat にしない)

この type を正しく付けさせるだけで、副次的な効果があります。Claudeが「この変更は feat なのか refactor なのか」を考える過程で、コミットの分割も自然と適切になるのです。1コミットの中に feat と refactor が混ざっていると type が決められないので、AIが自分で「分けるべきだ」と気づきます。

補足: チームで運用するなら commitlint + husky で機械的に強制する手もありますが、個人開発ならCLAUDE.mdに書くだけで十分機能します。


型3: レビューしやすい差分を「作らせる」指示

レビューしやすさは、コミットの切り方だけでなく差分そのものの作り方で決まります。同じ機能でも、差分の出し方しだいでレビュー負荷は大きく変わります。

レビュアー(あなた自身を含む)が一番つらいのは、「機能変更」と「無関係な変更」が同じ差分に混ざっているケースです。

読みにくい差分の例:
  関数Aのバグを1行直したかったのに、
  同じコミットでファイル全体がprettierで再フォーマットされ、
  +120 −118 行の差分になる
  → 本質の1行がノイズに埋もれて見えない

これを避けるための指示を、実装を頼むときに添えます。

レビューしやすい差分を作ってください。具体的には:

1. 無関係なフォーマット変更を機能変更と混ぜない
   (フォーマットだけなら別コミット style: で分ける)
2. 変数名の一括リネームなど大量の機械的変更は
   独立したコミットにする
3. 1コミットの差分が大きくなりそうなら、
   コミットを分割できないか先に提案する

さらに効くのが、コミット前に差分のサマリーを出させることです。

あなた: 「コミットする前に、これから作る各コミットの
        『type / 対象ファイル / 1行説明』を一覧で見せて。
        OKと言ったらコミットして」

これで「コミットしてから中身を確認する」のではなく「コミット計画をレビューしてから実行する」流れになります。Before/Afterで比べると差は歴然です。

Before:

Claude: (勝手に5ファイルを1コミット)
        "update search feature"
あなた: (git show してから)「これ分けてほしかった…」
        → git reset して切り直し(手戻り発生)

After:

Claude: コミット計画です。承認をお願いします:
  1. feat(api):     src/api/search.ts        検索APIを追加
  2. feat(api):     src/api/validation.ts    クエリ検証を追加
  3. test(api):     tests/search.test.ts     検索のテストを追加
あなた: 「OK、その通りに」
        → 手戻りゼロで意図通りのコミット

計画を先に見るので、手戻りが消えます。


型4: やってはいけない巨大コミットのパターンを名指しで禁止する

「良いコミット」をルール化するのと同じくらい、「やってはいけないパターン」を名指しで禁止するのが効果的です。AIは禁止事項を明示されると守りやすくなります。

CLAUDE.md にアンチパターンを列挙しておきます。

## コミットで禁止すること

-`git add -A` / `git add .` で無差別にステージしない
      → 関係するファイルだけを明示的に add する
- ❌ 1コミットに「機能追加 + リファクタ + フォーマット」を混ぜない
- ❌ "fix" "update" "wip" "various changes" など
      中身が分からないメッセージを使わない
- ❌ 100行を大きく超える差分を1コミットにしない
      (超えそうなら分割案を先に提示する)
- ❌ 生成物・ログ・.env など追跡すべきでないファイルをコミットしない
- ❌ 動作確認していないコードを "動く" 前提でコミットしない

特に1つ目の git add -A 禁止 は強力です。巨大コミットのほとんどは「全部まとめて add する」習慣から生まれます。これを禁じて「関係ファイルだけを明示的に add する」を強制すると、コミットは自然と意味のある単位に近づきます。

巨大コミットの典型と、その分割例を表にするとこうです。

巨大コミット(NG) 分割後(OK)
feat: ダッシュボード一式 で+900行 feat(api): 集計エンドポイントfeat(ui): グラフ表示feat(ui): フィルタUItest: 集計のテスト
fix: いろいろ修正 で5ファイル fix(auth): セッション切れの判定を修正 / fix(api): 検索の空配列対応 を別コミットに
機能追加と全ファイル再フォーマットが同居 style: 全体フォーマット を先に独立コミット → その上に feat: を載せる

3つ目の「フォーマットを先に別コミット」は実用的なテクニックです。先にフォーマットだけコミットしておけば、そのあとの機能コミットの差分が本質だけになり、劇的に読みやすくなります。Claudeにもこの順序を指示できます。


型5: 既存の作業をきれいなコミットに「切り直させる」

ここまでは「最初からきれいにコミットする」話でした。でも現実には、もう作業が終わっていて差分がぐちゃぐちゃという状況のほうが多いはずです。

そういうときは、Claude Codeにコミットの切り直しを任せられます。作業ツリーに未コミットの変更が溜まっている状態から始めます。

あなた: 「いまの未コミットの変更を、意味のある単位の
        複数コミットに分けてください。

        手順:
        1. まず git status と git diff で全体を把握
        2. 変更を『意図』ごとにグループ分けして一覧で見せる
        3. 私がOKしたら、グループごとに
           git add <該当ファイル> → commit で順にコミット
        4. Conventional Commits 形式で」

Claudeは差分を読み、たとえばこう提案してきます。

Claude: 現在の変更を3グループに分けられます:

  グループA(機能追加):
    src/api/search.ts, src/api/validation.ts
    → feat(api): ユーザー検索エンドポイントを追加

  グループB(リファクタ):
    src/utils/format.ts
    → refactor(utils): 日付整形ロジックを共通化

  グループC(テスト):
    tests/search.test.ts
    → test(api): 検索エンドポイントのテストを追加

  この3コミットに分けてよいですか?

1ファイルの中に複数の意図が混ざっている場合は、git add -p(ハンク単位のステージング)を使うようにも指示できます。

あなた: 「1ファイルの中に機能修正とフォーマットが混ざっている。
        git add -p でハンク単位に分けて、機能修正と
        フォーマットを別コミットにして」

これで「すでに散らかった作業ツリー」からでも、きれいな履歴に整えられます。コミットの切り直しは、人間がやると面倒で時間がかかる作業の筆頭です。だからこそAIに任せる価値が大きい。

注意: すでにリモートにpush済みのコミットを rebase で書き換えるのは、共有ブランチでは事故のもとです。切り直しは「まだpushしていないローカルの変更」に限定するよう、CLAUDE.mdに書いておくと安全です。


まとめ: Claude CodeにGit運用を任せる5つの型

要点
1. 1コミット1意図 リファクタと機能追加を必ず分ける。要約1行で説明できる単位に
2. Conventional Commits type/scope を固定。type を考える過程で分割も適切になる
3. レビューしやすい差分 フォーマットを混ぜない。コミット計画を先にレビューさせる
4. 巨大コミットを名指し禁止 git add -A 禁止・100行超は分割案を先に提示
5. コミットの切り直し 散らかった作業ツリーを意図ごとに再構成させる

Claude Codeのコミットが雑になるのは、モデルが下手だからではありません。「どういう単位で・どう書いてほしいか」を伝えていないだけです。

逆に言えば、CLAUDE.md にコミット規約を数行書いておくだけで、Claudeは人間がサボりがちな「こまめで意味のあるコミット」を淡々と実行してくれます。これはAIに任せたほうがむしろ品質が上がる、数少ない領域の1つです。

まずは「型1: 1コミット1意図」と「型4: git add -A 禁止」の2つだけでも、CLAUDE.md に追記してみてください。次に実装を頼んだとき、git log の見え方が変わるはずです。


補足: 試すための無料リポジトリ

本記事の内容を実際のプロジェクトで試すには、土台となるCLAUDE.mdとフォルダ構成があるとスムーズです。私が使っているスターター構成を無料で公開しています。

無料スターター(GitHub):
https://github.com/noguso245-jpg/claude-code-skills-starter

さらに踏み込んで、ワークフローやサブエージェント設計を「実行可能なスキルファイル」としてまとめたパッケージも用意しています。手元で /コマンド として呼び出せる形です。

まずは無料リポジトリから試して、もっと体系的に使いたくなったら検討してもらえれば十分です。記事の内容だけでも効果は出ます。


最新のTipsはXでも発信しています: @k___n___t_1125

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?