Claude CodeのPerforce p4 edit対応 — CLAUDE_CODE_PERFORCE_MODE
CLAUDE_CODE_PERFORCE_MODEを1にすると、書き込みビットの無いファイルへのEditが失敗してp4 editを促します。設定場所と、Claudeに自分でp4 editさせる運用を扱います。
CLAUDE_CODE_PERFORCE_MODEは何を止める環境変数か
CLAUDE_CODE_PERFORCE_MODEは、Perforce管理下のリポジトリでClaude Codeがファイルを黙って上書きしないようにする環境変数です。値に1を入れると有効になります。
有効なとき、Edit・Write・NotebookEditの3ツールは、対象ファイルにオーナーの書き込みビットが無いと失敗します。失敗メッセージにはp4 edit <file>のヒントが付きます。環境変数の説明には、この仕組みの狙いが「Perforceの変更追跡をバイパスさせない」ことだと書かれています。
背景はPerforceの作法にあります。Perforceは同期したファイルの書き込みビットを外し、p4 editで開くまで読み取り専用にしておきます。普通のエディタなら保存時に書き込み不可と気づけます。そこで書き込みビットを足して強行する経路が残っていると、変更追跡を飛ばせてしまいます。書き込みビットを手で足して編集すると、ファイルは変わっているのにPerforceには「開かれていない」状態が残ります。変更追跡から外れる、という意味です。
このモードを入れると、ツール側が書き込み前に止まります。Claudeに「先にp4 editで開く」という手順を踏ませる安全装置です。
追加されたのはv2.1.98(2026年4月9日付)で、変更履歴には「読み取り専用ファイルへのEdit・Write・NotebookEditがp4 editのヒント付きで失敗し、黙って上書きしなくなる」という趣旨で記載されています。経緯はClaude Code v2.1.98の解説にもあります。
このモードで変わること
- 値は
1で有効。対象はEdit・Write・NotebookEditの3ツール - 書き込みビットの無いファイルでは失敗し、
p4 edit <file>のヒントが出る - すでに
p4 editで開いてあり書き込める状態のファイルは、止まる条件に当たらない
有効にする場所
設定場所は2通りです。環境変数の置き方は他のCLAUDE_CODE_*変数と同じで、どちらでも効きます。
シェルから渡す場合は、起動前にexportします。
export CLAUDE_CODE_PERFORCE_MODE=1
claudeチームで揃えたいなら、settings.jsonのenvキーに書くほうが確実です。起動方法に関係なく反映され、プロジェクトの.claude/settings.jsonに置けば、リポジトリを取得した全員に適用されます。
{
"env": {
"CLAUDE_CODE_PERFORCE_MODE": "1"
}
}ファイルごとの適用範囲は次のとおりです。
| 置き場所 | 効く範囲 |
|---|---|
~/.claude/settings.json | 効く範囲自分の全プロジェクト |
.claude/settings.json | 効く範囲プロジェクトの全員(ソース管理に入る) |
.claude/settings.local.json | 効く範囲自分だけ・このプロジェクトだけ |
| 管理設定 | 効く範囲組織全体 |
PerforceとGitを併用している人は、Perforceのワークスペースだけに効かせたいはずです。全プロジェクト共通の~/.claude/settings.jsonには書かず、該当リポジトリの.claude/settings.jsonかsettings.local.jsonに置くと、Git管理のプロジェクトで意図せず書き込み保護が走る事態を避けられます。
envに書く値は文字列で、"1"のように引用符で囲みます。
設定の全体像はClaude Code設定ガイドに整理してあります。
失敗したあとの流れ
有効にした状態で、同期直後のファイルをClaudeに編集させると、次の順に進みます。
Perforceモードでの編集の流れ
- 1
Claudeが編集を試みる
Editツールが対象ファイルの書き込みビットを見ます。
- 2
ツールが失敗する
書き込みビットが無いため、
p4 edit <file>のヒント付きで失敗します。 - 3
ファイルを開く
あなたが、またはClaudeが
p4 editでファイルを開きます。Perforceが書き込みビットを戻します。 - 4
編集をやり直す
書き込める状態になったファイルへ、同じ編集が通ります。
3手目をだれが担うかで、運用が変わります。人間が毎回p4 editを打つのは、複数ファイルにまたがる修正では手間です。Claudeに任せる設計を、次の2節で扱います。
Claudeに自分でp4 editさせる
失敗メッセージにはヒントが付くので、Claudeは多くの場合それを読んで次の手を考えます。ただし毎回確実とは限りません。ルールとして明文化しておくと、試行錯誤のターンが減ります。
CLAUDE.mdに手順を書く
プロジェクトのCLAUDE.mdに、短い規約を置きます。
## Perforce の扱い
- このリポジトリは Perforce 管理下。ファイルを編集する前に `p4 edit <file>` で開く
- Edit / Write が「p4 edit」のヒント付きで失敗したら、該当ファイルを `p4 edit` で開いてから同じ編集をやり直す
- 新規ファイルは作成後に `p4 add <file>` する(勝手にサブミットはしない)3行目のp4 addは、環境変数の仕様に含まれる話ではありません。Perforceの一般的な手順を、このリポジトリの運用ルールとして書き足したものです。自分のチームの方針に合わせて消して構いません。
変更リストを分けたいとき
Perforceでは、開いたファイルをどの変更リストに入れるかをp4 edit -c <変更リスト番号> <file>で指定できます。これはPerforce側の機能で、Claude Codeの環境変数とは無関係です。ただしCLAUDE.mdに「このタスクの変更リストは番号○○。p4 editには必ず-c ○○を付ける」と書いておけば、Claudeが開くファイルを1つの変更リストにまとめられます。タスクごとにレビュー単位を揃えたいチームでは、モードを入れるだけでなくこの一行まで規約にしておくと、後工程が楽になります。
p4 editの許可ルールを足す
Claudeがp4 editをBashで呼ぶと、通常は権限の確認が出ます。頻繁に出て煩わしいなら、p4 editだけを許可するルールを足します。
{
"permissions": {
"allow": ["Bash(p4 edit *)"]
}
}ルールはコマンド全体に対するワイルドカード一致です。p4 submitやp4 revertまで通さないよう、許可はp4 editに絞っておくと安全です。
失敗の前にhookで開く
「失敗してから開く」の往復を省きたいなら、PreToolUseフックが使えます。ツールが動く前にp4 editを走らせ、書き込める状態にしておく発想です。
フックの設定例です。Edit|Write|NotebookEditのどれにも反応させます。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write|NotebookEdit",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/p4-open.sh"
}
]
}
]
}
}スクリプトは標準入力のJSONからパスを取り出し、書き込めないファイルだけを開きます。
#!/bin/bash
# .claude/hooks/p4-open.sh
FILE=$(jq -r '.tool_input.file_path // .tool_input.notebook_path // empty')
if [ -n "$FILE" ] && [ -e "$FILE" ] && [ ! -w "$FILE" ]; then
p4 edit "$FILE" >&2
fi
exit 0jqが必要です。公式のフック例も同じ作りで、jqをPATHに通しておく前提です。パスのキーは、EditとWriteでfile_path、NotebookEditでnotebook_pathです。両方を//でつなぐことで、3ツールを1本のスクリプトで扱えます。
この例は、公式のフック例の書き方に沿って組んだものです。手元のPerforce環境で、次の3点を確かめてから共有してください。
p4 editが書き込みビットを戻し、続くEditが通ること- ロック済み・他のワークスペースで開かれているファイルで、フックが失敗しても
exit 0でツールの流れを止めないこと(止めたいならexit 2に変える) - 大きなワークスペースで、毎回の
p4呼び出しが遅くならないこと
フックの全体像はClaude Code Hooks完全ガイドで扱っています。
フックを足すときの注意
フックでの自動オープンは、Perforceモードの意図と引き換えです。モードは「Claudeに手順を意識させる」ためのものでした。フックで機械的に開くと、人間が気づかないうちに大量のファイルが開かれます。意図したファイルだけを開きたい場合は、フックにパスの絞り込みを入れるか、CLAUDE.mdの規約だけで運用するほうが向きます。
効かない範囲を知っておく
環境変数の説明が挙げる対象は、Edit・Write・NotebookEditの3ツールだけです。それ以外の書き込み経路について、この変数の説明は何も述べていません。
| 経路 | モードの対象か |
|---|---|
| Edit / Write / NotebookEdit | モードの対象か対象(書き込みビットが無いと失敗) |
| Bashコマンドによる書き換え(リダイレクトなど) | モードの対象か環境変数の説明に記載なし |
| すでに書き込み可能なファイル | モードの対象か書き込みビットがあるため止まらない |
| 新規作成するファイル | モードの対象か説明に扱いの記載なし |
Bash経由の書き換えを止めたいなら、権限ルールかフックでBash側も見張る必要があります。モードを入れたから安全、と思い込まないほうが堅実です。
もう1点、worktreeとの関係があります。Claude Codeのworktree隔離は既定でgitを使います。Perforceのような別のバージョン管理で使うには、WorktreeCreateとWorktreeRemoveのフックで作成と削除のロジックを自前で用意する必要があります。フックが既定の動作を置き換えるため、.worktreeincludeも処理されません。Perforceモードとは別の話ですが、同じ環境で並列作業を考えるなら押さえておく点です。
導入前に決めておくこと
モードの有効化は1行ですが、運用を決めずに入れると、失敗の往復が増えて作業が遅くなります。入れる前に次の4点を合意しておくと、導入後の揉め事が減ります。
| 決めること | 選択肢 |
|---|---|
| 開く担当 | 選択肢人間が開く / Claudeが開く / フックが開く |
| 設定の置き場所 | 選択肢プロジェクト共通の.claude/settings.json / 個人のsettings.local.json |
| 許可ルール | 選択肢Bash(p4 edit *)だけを許可 / 毎回確認 |
| 変更リストの扱い | 選択肢既定の変更リスト / タスクごとに番号を指定 |
編集が失敗するときの切り分け
Perforceモードを入れたあと、編集に失敗したときは原因が複数ありえます。
- ヒントに
p4 edit <file>が出ている: モードが働いた結果です。ファイルを開けば解決します - ヒントが出ず権限エラーになる: モードではなく、ファイル権限や権限ルールの問題の可能性があります
- ヒントが出ないまま上書きされた: 環境変数が届いていないか、書き込み可能なファイルだった可能性があります。
envの置き場所と値の1を見直します - 設定を変えたのに反映されない: シェル由来の変数は起動時に読まれます。settings.jsonの
envは保存時に実行中のセッションへ反映されます
効いているかの確認は単純です。モードを切り替えた直後は、設定の置き場所と値をあわせて見直すと原因を絞れます。p4 syncした直後で、まだ開いていないファイルを小さく編集させます。失敗してヒントが出れば有効です。
まとめ
CLAUDE_CODE_PERFORCE_MODE=1は、Perforceの「開いてから編集する」作法をClaude Codeに守らせるための変数です。設定自体はenvに1行で済みます。難しいのは、失敗したあとの運用のほうです。
人が毎回p4 editを打つ運用はすぐ疲れます。CLAUDE.mdに手順を書き、p4 editだけを許可しておけば、Claudeが自分で開いて編集をやり直せます。自動で開きたいチームはPreToolUseフックが選べますが、意図しないファイルまで開く点に注意が要ります。Bash経由の書き換えは説明の対象外なので、別の手当てが必要です。