2026年9月9日時点の結論。Claude CodeにGit操作を任せるかどうかは、作業のたびに人が判断することではなく、settings.json の許可ルールで先に線を引いておくことだ。公式ドキュメントが権限設定の代表例として挙げているのも、Bash(git commit *) を許可し Bash(git push *) を拒否する形になっている。コミットまでは任せ、外に出す操作は人が押す。この線引きが決まれば、残りは既存の機能に載せるだけで済む。
Claude CodeにはGit専用のツールがない。git はBashツールから実行されるので、Git運用の安全性はそのままBashの権限設計になる。ここを決めずに使い始めると、「毎回承認を押すのが面倒だから全部許可した」か「怖いので何も任せない」のどちらかに寄る。前者は事故の準備であり、後者はエージェントを使う意味を削る。
この記事の要点
- 評価順:ルールは deny → ask → allow の順に見られ、先に一致したものが勝つ。具体的なルールが優先されるわけではない(Permissions)。
- 書き方:ワイルドカードはサブコマンドの後ろに置く。
Bash(git log *)はgit logだけ、Bash(git *)は全部のgitサブコマンドを許す。 - 規約の置き場所:コミットメッセージの書式や禁止事項は毎回のプロンプトではなく
CLAUDE.mdに置く。 - 歯止め:
push --forceやreset --hardのように取り返しがつかない操作は、拒否ルールとPreToolUse hookの二段で止める。 - 対象読者:チームでClaude Codeを使う開発者、テックリード、レビュー担当。
- 今日やること:セッションで
/permissionsを開き、いまgit系のルールが何本あるかを数える。
手順1|任せるGit操作と人が押す操作を先に決める
最初に決めるのは設定ファイルの中身ではなく、「戻せる操作か」という一点だ。Claude Codeが実行するgitコマンドは、履歴を読むだけのものから、リモートの状態を壊すものまで幅がある。戻せる操作は任せ、戻せない操作は人の指の下に置く。
| 操作 | 影響の範囲 | 既定の扱い | 推奨する設定 |
|---|---|---|---|
git status / git log / git diff |
ローカルの読み取りだけ | 承認を求められる | allow に入れる |
git add / git commit |
ローカル履歴。取り消せる | 承認を求められる | allow に入れる |
git checkout / git switch |
未コミットの変更を失う場合がある | 承認を求められる | ask に残す |
git push |
他人が見る場所が変わる | 承認を求められる | deny か ask |
git push --force / git reset --hard / git clean -f |
他人の作業や未保存の変更が消える | 承認を求められる | deny + hook |
Bashコマンドは既定で承認を求められるので、何も設定しなければ「毎回聞かれる」状態になる(Permissions)。ルールを書く目的は権限を増やすことではなく、聞かれる回数を減らしつつ、聞かずに通ってはいけないものを確実に止めることにある。

なお、承認ダイアログで「Yes, and don’t ask again」を選ぶと、そのルールはgitリポジトリのルートにある .claude/settings.local.json に保存される。サブディレクトリで起動したセッションでも、worktree内のセッションでも、同じリポジトリなら同じルールが効く。この解決がリポジトリルート基準になったのはv2.1.211以降で、それより前は起動したディレクトリだけを見ていた。
手順2|権限ルールを settings.json に書く
公式ドキュメントがそのまま載せている最小構成は次の形だ。npmスクリプトとコミットは聞かずに実行し、pushは拒否する。
{
"permissions": {
"allow": [
"Bash(npm run lint)",
"Bash(npm run test *)",
"Bash(git commit *)"
],
"deny": [
"Bash(git push *)"
]
}
}
ここで押さえるべき挙動が3つある。
- 評価順は deny → ask → allow。先に一致したルールで結果が決まり、ルールの具体性は順番を変えない。
- 広い拒否は狭い許可に勝つ。
Bash(aws *)のような拒否があると、Bash(aws s3 ls)という許可があっても通らない。拒否ルールに例外を持たせることはできない。 - ツール名だけの拒否は意味が違う。
Bashとだけ書くとツールごとClaudeの視界から消える。Bash(rm *)のように範囲を絞った書き方なら、ツールは使えるまま該当コマンドだけが止まる。

ワイルドカードはサブコマンドの後ろに置く
git log --oneline main の場合、git はプログラム名で、何をするかを決めているのは log というサブコマンドだ。Claude Codeは最初の * より前を文字どおり照合するので、* をどこに置くかで意味が変わる。
| ルール | 一致する例 | 一致しない例 |
|---|---|---|
Bash(git log * main) |
git log --oneline main / git log -5 main |
git log main / git push origin main |
Bash(git * main) |
git merge main / git push origin main |
git log |
Bash(git * main) の * はサブコマンドの位置に立つので、pushもmergeも通る。さらに -c のようにgitに別プログラムを実行させるオプションまで含まれる。サブコマンドの前に * を置いた許可ルールは起動時に警告が出るので、その警告を消すために書き方を直す。
書いても効かない書き方3つ
Bash(command:rm *):Bashの主要入力であるcommandをパラメータ指定で照合しようとする書き方は、複合コマンドで回避できてしまうため無視され、起動時に警告が出る。Bash(rm *)と書く。Bash(git:* push)::*は末尾でだけ「後方ワイルドカード」として認識される。途中に書いたコロンはただの文字として扱われ、gitコマンドに一致しない。末尾に書くBash(git:*)はBash(git *)と同じ意味になる。- リダイレクト先の思い込み:
Bash(git commit *)が許可するのはコマンドであって、> fileの書き込み先ではない。出力のリダイレクト先はEditの許可・拒否ルールや作業ディレクトリの側で判定される。
拒否とaskのルールは、サブシェルやコマンド置換、for ループの中に入れ子になったコマンドにも効く。Bash(git clean *) をaskにしておけば、cd /tmp && git clean -f のような書き方でも聞かれる。逆に、複合コマンドを「もう聞かないで」で承認すると、承認が必要だったサブコマンドごとに別々のルール(1コマンドにつき最大5本)が保存される点は把握しておきたい。チーム共通の設計はClaude Code権限設計ガイドに整理してある。
手順3|コミット規約は CLAUDE.md に置く
「コミットメッセージは日本語の命令形で、1行目は50文字以内、Issue番号を末尾に付ける」といった規約は、毎回プロンプトに書くものではない。プロジェクトの CLAUDE.md に書けば、そのリポジトリで起動したセッション全部に効く。置き場所は ./CLAUDE.md か ./.claude/CLAUDE.md のどちらでもよく、バージョン管理に入れてチームで共有する(How Claude remembers your project)。
最初の1本は /init で作れる。既存のCLAUDE.mdがある場合、/init は上書きせずに改善案を出す。作った後は次の3点を守る。
- 200行以内に保つ。長いファイルはコンテキストを食い、指示の遵守率も落ちる。
- 長い手順は分ける。git運用の細かい手順が膨らんだら
@docs/git-instructions.mdの形で読み込むか、パス単位で読み込むルールに切り出す。 - 個人の好みは分ける。コミットの署名や個人的な省略コマンドは
CLAUDE.local.md(.gitignore対象)に置く。
読み込まれているかどうかは /context の「Memory files」で確認できる。「規約を書いたのに守らない」という相談の多くは、ファイルがそもそも読み込まれていないか、200行を大きく超えて埋もれているかのどちらかだ。
手順4|取り返しのつかない操作は hook で止める
拒否ルールはコマンド文字列の照合なので、書き漏らした形は通ってしまう。「絶対に走らせたくない操作」がある場合は、PreToolUse hookでもう一段止める。hookはツール実行の直前に走るシェルスクリプトで、permissionDecision に deny を返すとそのツール呼び出しを止められる(Automate actions with hooks)。
設定側は、matcher でBashに絞り、if 条件でさらにコマンドの形を絞る。次は公式ドキュメントの構成例(rm を対象にした例)を、gitのpushに置き換えた形だ。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"if": "Bash(git push *)",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-force-push.sh",
"args": []
}
]
}
]
}
}
スクリプト側は標準入力のJSONからコマンドを取り出し、条件に当たれば拒否を返す。当たらなければ exit 0 で通常の権限フローに戻す。
#!/bin/bash
# .claude/hooks/block-force-push.sh
COMMAND=$(jq -r '.tool_input.command')
if echo "$COMMAND" | grep -qE '(--force|-f)([[:space:]]|$)'; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: "force push is blocked by project policy"
}
}'
else
exit 0
fi
jq を使うので、実行環境に入れてPATHを通しておく。スクリプトには実行権限(chmod +x)が要る。設定が読み込まれているかは /hooks で確認する。フォーマットやテストを走らせる使い方を含めた全体像はClaude Code Hooks実践ガイドにまとめてある。

拒否ルールとhookは役割が違う。拒否ルールは「設定に書いた形」を止め、hookは「実行しようとしている文字列を自分のコードで判定して」止める。壊れたら戻せない操作については、両方を書いておくほうがいい。
手順5|差分の確認を /diff → /code-review に固定する
Claudeが編集した内容を人が読む順番を、セッションの作法として固定しておく。まず /diff で作業ツリーの変更を見る。ここにはClaudeがそれまでに加えた編集も含まれる。
次に /code-review を走らせる。現在の差分を対象にバグと整理の余地を見て、--fix を付ければ指摘の適用まで進む。PR番号やブランチ、パスを渡せばその対象を見る(/code-review high 1234 のように書く)。/review は同じコマンドの別名で、--comment を付けるとGitHubのPRにインラインコメントとして投稿できる。深く見たいときは /code-review ultra でクラウド側の多エージェントレビューに回す(Code Review)。
- 正しさを見たい →
/code-review - セキュリティを見たい →
/security-review - 整理の余地だけ見たい →
/simplify(バグは見ない)
/diff の読み方と、レビューで拾う観点の分け方はClaude Code /diff活用とClaude Codeでコードレビューを効率化する実践ガイドで扱っている。
手順6|PRまで通してセッションとPRを結ぶ
PRの作成は gh pr create(GitLabなら glab mr create)で行う。Claudeがこのコマンドで作ったPRは、そのセッションと結び付けて記録される。後から claude --from-pr 1234 と打てば、そのPRに紐づくセッションだけに絞ったセッション選択画面が開く。PRのURLを /resume の検索に貼っても同じ場所にたどり着ける(Common workflows)。
「どういう意図でこの差分になったのか」を後から追えるかどうかは、レビューの速さに直結する。PR本文をClaudeに書かせる場合も、提出前に人が読み、リスクや検討事項を挙げさせてから出す。Issueからの流れをまとめて自動化する形はClaude Code×Issue駆動開発にある。

リポジトリのイベントに合わせて動かしたいなら、GitHub Actions側にClaude Codeを置く選択肢もある。ローカルの未コミットの変更を触る作業はローカル、PRが開いたら走らせたい作業はCI、と置き場所を分けるのが素直だ。
手順7|並行作業は worktree、定型は claude -p に寄せる
同じリポジトリで並行して作業させると、編集がぶつかる。claude --worktree <名前>(短縮形は -w)を使うと、リポジトリルート下の .claude/worktrees/<名前>/ に新しいチェックアウトが作られ、worktree-<名前> というブランチでセッションが始まる(Worktrees)。
- worktreeは新しいチェックアウトなので、依存関係のインストールなど環境の初期化が別途要る。
.envのようにgit管理外のファイルを毎回持ち込みたいときは.worktreeincludeに書く。- 対話実行にはワークスペースの信頼が必要で、そのディレクトリで一度も起動していないと
--worktreeはエラーで終わる。-pの非対話実行はこの確認を通らない。 - コミットが1つもないリポジトリでは、基準ブランチを解決できずに失敗する。
並列運用の設計そのものはClaude Code×git worktree並列開発ガイドにまとめてある。
定型のGit作業は対話セッションに置かず、claude -p の非対話実行に寄せる。標準入力と標準出力が普通のUnixコマンドと同じように使えるので、CIやpre-commitフックから呼べる。
git log --oneline -20 | claude -p "summarize these recent commits"
「毎朝オープンPRを見る」のように定期的に走らせたい仕事は、スケジュール実行の枠組み側に置く。自律実行になる分、成功の条件と結果の出し先をプロンプトに明記しておく必要がある。
失敗パターンと回避策
- ❌ すべて許可にして承認を消す → ⭕ 読み取りとコミットだけ許可し、外に出る操作はaskかdenyに残す。承認の回数を減らす目的なら、
git statusgit loggit diffを許可するだけで体感はかなり変わる。 - ❌
Bash(git *)を許可に入れる → ⭕ サブコマンドごとに書く。git *はpushもresetも、gitに任意のプログラムを実行させる-cも含む。 - ❌ 拒否ルールだけで満足する → ⭕ 取り返しがつかない操作はPreToolUse hookでも止める。ルールは書いた形しか止められない。
- ❌ コミット規約を毎回プロンプトで渡す → ⭕
CLAUDE.mdに置き、/contextで読み込みを確認する。プロンプトで渡した規約はセッションが変われば消える。
想定モデル|受託開発チームのGit運用設計
実在の顧客事例ではなく、上の7手順を1つのチームに当てはめた想定モデルとして読んでほしい。数値は前提を置いた設計例で、測定値ではない。
前提:受託開発の5人チーム、GitHub、mainブランチ保護あり、レビューは2名承認。
- 線引き:読み取り系とコミットは許可。
git pushはask、--forceを含むpushはdenyとhookの二段。 - 設定の置き場所:チーム共通のルールはリポジトリの
.claude/settings.jsonに入れてコミットする。個人が承認ダイアログで足したルールは.claude/settings.local.jsonに残るので、.gitignoreの扱いを最初に決めておく。 - 規約:
CLAUDE.mdにコミットメッセージの形式、ブランチ名の規則、触ってはいけないディレクトリを書く。長い運用手順は別ファイルに切り出して読み込む。 - レビュー:Claudeが差分を作ったら
/diff→/code-review→ 人のレビューの順に固定する。PRへの指摘投稿は--commentに任せてもよいが、マージ判断は人が持つ。 - 並行:緊急のバグ修正が入ったら
claude -w hotfixで別チェックアウトに逃がす。
この形にすると、承認ダイアログは1日に何度も出るものではなくなり、出たときは「本当に人が見るべき操作」に絞られる。承認の回数が減ったかどうかは、/permissions に並ぶルールの数と、拒否ルールに当たったログの2つで振り返る。
まとめ|今日からの3手

/permissionsを開き、現状のgit系ルールを書き出す。1本もなければ、読み取り3つとコミットの許可から書く。CLAUDE.mdにコミットメッセージの規約を1節足し、/contextで読み込みを確認する。push --forceを止めるPreToolUse hookを1本置き、/hooksで読み込みを確認する。
3つとも設定ファイルの編集だけで終わる。順番は「許可 → 規約 → 歯止め」で、逆にすると歯止めの範囲が決まらない。
FAQ
Claude CodeにはGit専用のコマンドがありますか?
Git操作専用のツールはなく、git はBashツールから実行されます。そのため、Gitの制御は権限ルール(Bash(...))とhookで行います。差分の確認には /diff、レビューには /code-review(別名 /review)という組み込みの入口があります。
許可ルールを書いたのに毎回聞かれます。なぜですか?
3つの原因が多いです。1つ目は評価順で、同じコマンドに一致するaskルールがあると、より具体的な許可ルールがあってもaskが勝ちます。2つ目はワイルドカードの位置で、サブコマンドの前に * を置いた許可ルールは起動時に警告が出ます。3つ目は設定ファイルの場所で、/permissions や claude doctor で実際に読み込まれているルールを確認してください。
git push は許可しても大丈夫ですか?
保護されていないブランチへの通常のpushであれば、チームの合意があれば許可の対象になります。ただし --force を含む形は別扱いにしてください。拒否ルールだけでなくPreToolUse hookでも止める二段構えを推奨します。公式ドキュメントの設定例でも、git commit を許可しつつ git push は拒否する形が示されています。
承認ダイアログで「もう聞かないで」を選んだルールはどこに残りますか?
gitリポジトリのルートにある .claude/settings.local.json に保存されます。worktree内で承認した場合も、メインのチェックアウト側に解決されて保存されます。複合コマンドを承認した場合は、承認が必要だったサブコマンドごとに別々のルールとして保存されます(1コマンドにつき最大5本)。
コミット規約はCLAUDE.mdとhookのどちらに書くべきですか?
文章で伝わる規約(メッセージの形式、ブランチ名、粒度)はCLAUDE.mdです。機械的に判定できて、破られたら困るもの(禁止コマンド、保護パスへの書き込み)はhookです。CLAUDE.mdは指示であって強制ではないので、事故に直結する項目をCLAUDE.mdだけに書かないでください。
参考・出典
- Anthropic「Permissions」(deny→ask→allowの評価順、
Bash(git commit *)/Bash(git push *)の設定例、ワイルドカードの位置、settings.local.jsonの保存先) - Anthropic「Automate actions with hooks」(PreToolUseの
matcherとif、permissionDecisionの返し方) - Anthropic「How Claude remembers your project」(CLAUDE.mdの置き場所・200行の目安・
@によるインポート・CLAUDE.local.md) - Anthropic「Run parallel sessions with worktrees」(
--worktree/-w、.claude/worktrees/<name>/、.worktreeinclude) - Anthropic「Common workflows」(
claude --from-pr、claude -pのパイプ実行、スケジュール実行の置き場所) - Anthropic「Commands reference」(
/diff・/code-review・/review・/security-review・/permissions・/hooksの定義) - Anthropic「Code Review」(差分レビューの効力レベルとPR対象の指定)
著者プロフィール
佐藤傑(さとう・すぐる)。株式会社Uravation代表取締役。X(@SuguruKun_ai)フォロワー約10万人。100社以上の企業向けAI研修・導入支援。著書『AIエージェント仕事術』『Claude仕事術』(SBクリエイティブ・シリーズ累計50,000部突破)。SBクリエイティブ「ビジネス+IT」ほかで生成AI連載を執筆。