Skip to Content
ユーザーガイド機能Worktree
# ワークツリー > 現在のセッションを離れずに、一時的な [git worktree](https://git-scm.com/docs/git-worktree) で実験的な作業を分離します。モデルが広範囲にわたる編集を行おうとしていて、それをメインチェックアウトから分離しておきたい場合や、サブエージェントを独自のサンドボックスで作業させたい場合に便利です。 ## クイックスタート ### ワークツリー内でセッションを開始する (`--worktree` フラグ) 最初からセッション全体をワークツリー内で実行することが分かっている場合は、起動時に `--worktree` を指定します。 ```bash # 自動生成のスラッグ (例: tender-jemison-037f0a) qwen --worktree # 明示的な名前 qwen --worktree my-feature # `=` 形式 (下のヒントを参照——位置プロンプトも同時に渡す場合に推奨) qwen --worktree=my-feature # PR 参照 — `origin` から refs/pull/<N>/head をフェッチ qwen --worktree=#4174 qwen --worktree https://github.com/QwenLM/qwen-code/pull/4174 # 以前の --worktree セッションを再開 — 既存のディレクトリに再アタッチ qwen --resume <session-id> --worktree=my-feature

ヒント — ベアの --worktree の後に位置プロンプトを続けると曖昧になります。 --worktree はオプショナルな値を受け取るため、qwen --worktree "say hi" とすると yargs が "say hi" をスラッグとして消費し(スペースがあるため)拒否します。代わりに以下のいずれかを使用してください。

  • qwen --worktree=my-feature "say hi"= で明示的なスラッグ → 常に動作)
  • qwen "say hi" --worktree(位置プロンプトを先に、フラグを後に → 自動スラッグ)
  • qwen --worktree --approval-mode yolo "say hi"(間に他のフラグを挟むことでベア形式が確定)

ヒント — qwen --resume --worktree foo(セッションIDなし)を初回使用すると、空のピッカーが表示されます。 ピッカーは選択したワークツリーのセッションストレージにスコープされます。そのワークツリー外で開始されたセッションはリストに表示されません。foo 内で開始されたセッションを再開するには、qwen --resume <id> --worktree foo を直接使用してください。CLI は foo/ ディレクトリを再作成するのではなく、既存のものに再アタッチします。

process.cwd() とモデルのワークスペースは、最初のターンが実行される前にワークツリーに切り替えられます。Ctrl+C を2回押して終了すると、終了ダイアログ がワークツリーを保持するか削除するかを尋ねます。

--worktree フラグは --acp / --experimental-acp と組み合わせることはできません。ACP ホスト(Zed など)の場合は、代わりに loadSession / newSession リクエストの cwd としてワークツリーパスを渡してください。

またはセッション中に依頼する

代わりに、既存のセッション内で Qwen Code に自然言語でワークツリーを作成するよう依頼することもできます。

> start a worktree called experiment-a Worktree experiment-a created on branch worktree-experiment-a .qwen/worktrees/experiment-a

この時点から、モデルはすべてのファイル編集とシェルコマンドを .qwen/worktrees/experiment-a/ 経由でルーティングします。元の作業ディレクトリは触れられません。

完了したら:

> exit the worktree and remove it Removed worktree experiment-a (branch worktree-experiment-a)

後で戻ってきたい場合は、ワークツリーをディスク上に保持して終了するよう依頼します:

> exit the worktree but keep it Kept worktree experiment-a at .qwen/worktrees/experiment-a

ワークツリーが使用されるタイミング

ワークツリーは、以下の4つの独立した経路でアクティブになります。

トリガー動作
--worktree を指定して起動CLI はモデルターンが実行される前にワークツリーを作成し、セッションの chdir をその中に設定します。PR 形式(#N、完全なURL)は最初にフェッチします。
セッション中に明示的にワークツリーを依頼モデルが enter_worktree を呼び出します。以降のファイル編集はその中で行われます。
明示的に離れるよう依頼モデルが keep または remove を指定して exit_worktree を呼び出します。
モデルが分離機能を有効にしてサブエージェントを起動使い捨てのワークツリー(agent-<hex>)が自動的に作成され、エージェントに差分がない場合はクリーンアップされます。

セッション中の2つのツール(enter_worktree / exit_worktree)は、意図的に明示的な言い回しの背後にゲートされています。「このバグを修正して」や「ブランチを作成して」と言っても、これらは トリガーされません。「ワークツリーを使って」「ワークツリーを開始して」「ワークツリー内で」などと言う必要があります。--worktree CLI フラグにはそのようなガードはなく、指定されると常にワークツリーを作成します。

作成されるもの

Qwen が管理するすべてのワークツリーは、プロジェクトの .qwen ディレクトリの下に配置されます。

<repoRoot>/.qwen/worktrees/<slug>/ # 作業ディレクトリ ↳ branch worktree-<slug> # 現在のブランチから作成
  • スラッグ — 英字、数字、ドット、アンダースコア、ハイフン。最大64文字。名前を指定しない場合、<形容詞>-<名詞>-<6桁16進数> のスラッグが自動生成されます(例: tender-jemison-037f0a)。PR 参照の場合は pr-<N> が生成されます。
  • ブランチ — 常に worktree-<slug> で、ワークツリーを要求した時点でチェックアウトしているブランチから分岐されます(メインの作業ツリーの HEAD であるとは限りません)。PR ワークツリーの場合、ブランチは worktree-pr-<N> で、ローカルブランチではなく FETCH_HEAD(GitHub 側の PR の先端)をベースとします。
  • フック — ワークツリーの core.hooksPath は自動的にメインリポジトリの .husky/(優先)または .git/hooks/ を指すように設定されるため、ワークツリー内のコミットでも既存の pre-commit / commit-msg フックがトリガーされます。
  • オプションのシンボリックリンクworktree.symlinkDirectories にリストされたディレクトリ(設定 を参照)は、メインリポジトリから新しいワークツリーにシンボリックリンクされるため、node_modules などの重いディレクトリを再インストールせずに再利用できます。

汎用ワークツリーパスは 設定できません<repoRoot>/.qwen/worktrees/ の下に置かれなければなりません。これにより、再起動時や古いクリーンアップスイープ時に CLI がそれを見つけることができます。(無関係の agents.arena.worktreeBaseDir 設定は、Agent Arena ワークツリーのみを制御し、~/.qwen/arena/ 以下の別のパスツリーを使用します。)

フッターとステータス行

ワークツリーがアクティブな場合、フッターは独自の行に薄いインジケーターを表示します。

⎇ worktree-experiment-a (experiment-a)

カスタムステータス行スクリプト を使用している場合、そのスクリプトは stdin にパイプされる JSON ペイロード内で worktree オブジェクトも受け取ります。

{ "worktree": { "name": "experiment-a", "path": "/path/to/repo/.qwen/worktrees/experiment-a", "branch": "worktree-experiment-a", "original_cwd": "/path/to/repo", "original_branch": "main" } }

ペイロードフィールドはワークツリーがアクティブな場合 のみ 存在するため、null チェック (input.worktree?.name) で十分です。

カスタムステータス行ですでにワークツリー情報を表示している場合は、重複を避けるために組み込みのフッター行を非表示にできます。設定 を参照してください。

終了ダイアログ (Ctrl+C / Ctrl+D)

ワークツリーがアクティブな状態で終了ショートカットを2回押すと、CLI を閉じる代わりに ワークツリー終了ダイアログ が開きます。

⎇ Active worktree: "experiment-a" (worktree-experiment-a) • 2 new commit(s) on worktree-experiment-a • 3 uncommitted file(s) Removing the worktree will discard everything above. What would you like to do? ○ Keep worktree (exit without deleting) ○ Remove worktree and branch (discards 2 commit(s), 3 file(s)) ○ Cancel (stay in session)

ダイアログは開いた時点でワークツリーの状態を検査し(git status --porcelain + git rev-list <baseHEAD>..HEAD)、両方のカウントを表示するため、破棄される内容を正確に把握できます。ESC でキャンセルされます。

git status 自体が失敗した場合(例: インデックス破損、CLI の下でワークツリーディレクトリが削除された)、ダイアログは ⚠ Could not measure worktree state 警告を表示し、カウントが信頼できない可能性があります。根本的なリポジトリの問題を診断するまでは、Keep または Cancel を選択してください。

--resume 復元

アクティブなワークツリーのバインディングは、セッションのトランスクリプトと共にサイドカーファイルに永続化されます。

<chatsDir>/<sessionId>.worktree.json

--resume <sessionId> で CLI を起動するか(/resume からセッションを選択)、インタラクティブTUIヘッドレス -pACP/Zed モードのいずれでも、以下の3つの動作が一貫して行われます。

  1. サイドカーが読み込まれ、ワークツリーディレクトリがディスク上にまだ存在することが確認されます。
  2. 存在する場合、モデルは次のプロンプトで一回限りのリマインダーを受け取ります。
    [Resumed] Active worktree: "<slug>" at <path> (branch: <branch>). Continue using this path for all file operations.
  3. ワークツリーディレクトリがセッション間で削除された場合、古くなったサイドカーは自動的にクリーンアップされます — エラーは発生せず、再開はワークツリーコンテキストなしで続行されます。

各モードは独自の注入メカニズムを選択しますが、ユーザーから見える動作は同じです。

モードメカニズム
インタラクティブ (TUI)INFO 履歴アイテム + 次のユーザープロンプトへのシステムリマインダープレフィックス
ヘッドレス (-p)プロンプトへの <system-reminder> プレフィックス + 出力ストリーム内の worktree_restored JSON システムイベント
ACP (例: Zed)次の prompt() 呼び出しに添付される保留通知

モデルは自動的にワークツリーに chdir されるわけでは ありません — リマインダーによって、ワークツリーパスを通じて編集をルーティングし続けるようになります。

サブエージェントの分離

agent ツールはオプションの isolation: "worktree" パラメーターを受け入れます。設定されている場合、Qwen Code はサブエージェントが開始される前に <repoRoot>/.qwen/worktrees/agent-<7hex>/ に一時的なワークツリーを作成し、以下の動作をします。

  • 変更がない場合 → エージェント終了時にワークツリーは自動的に削除されます。
  • 変更がある場合 → ワークツリーは保持され、そのパスとブランチがエージェントの結果に追加されます。例:
    …agent output… [worktree preserved: /path/to/.qwen/worktrees/agent-3f2a1b9 (branch worktree-agent-3f2a1b9)]
    差分をレビューし、手動でマージまたは削除してください。

2つの制約:

  • isolation: "worktree" には subagent_type が必要です。フォークされたサブエージェント(subagent_type なし)は親の会話コンテキスト全体を再利用するため、それらを分離すると意図と作業ツリーが分断されます。
  • バックグラウンドエージェント(run_in_background: true)は分離と問題なく動作します。クリーンアップはエージェントが完了を報告したときに実行されます。

自動的な古いワークツリーのクリーンアップ

クラッシュや --no-cleanup シャットダウンを生き延びた一時的なエージェントワークツリーは、CLI の起動時に保守的なフェイルクローズドルールで回収されます。

ガード動作
スラッグが agent-<7hex> パターンに一致あなたが作成した名前付きワークツリーには触れません。
ディレクトリ mtime が 30 日を超える新しいエントリはスキップされます。
追跡対象の未コミット変更があるそのエントリをスキップ(削除しません)。
リモートから到達可能でないコミットがあるそのエントリをスキップ(削除しません)。
git 状態の読み取り中にエラーが発生そのエントリをスキップ(削除しません)。

名前付きのユーザー作成ワークツリー(enter_worktree スラッグ)は 自動的には決してクリーンアップされません — 削除を明示的に要求するまで保持されます。

exit_worktree action="remove" の安全ガード

ディレクトリとブランチが削除される前に、3つの独立したガードがトリガーされます。

  1. セッション所有権 — 各ワークツリーには、それを作成したセッションIDを示すサイドカーマーカーが付いています。別のセッションがそれを削除しようとすると、手動での脱出手段として git worktree remove を指し示す明確なエラーで拒否されます。
  2. ダーティな作業ツリー — 未コミットの追跡対象ファイルまたは追跡されていないファイルがあると、削除がブロックされます。上書きするには discard_changes: true を渡します。(バイパスには明示的なユーザー確認が必要です — action: "remove" は AUTO_EDIT モードでも自動承認されません。)
  3. マージされていないコミット — 他のローカルブランチやリモート参照が指していない worktree-<slug> 上のコミットは、無条件に削除をブロックします。「コミットを破棄する」フラグはありません。なぜなら、コミットされた作業を失うことはユーザーが意図することはほとんどないからです。最初にマージ、プッシュ、またはブランチを他の場所にリネームしてください。

これら3つのガードは、WorktreeExitDialog → Remove ボタンにも適用されます。

設定

汎用ワークツリー体験を形成する2つの設定:

キータイプデフォルト効果
ui.hideBuiltinWorktreeIndicatorbooleanfalse組み込みの ⎇ worktree-… (…) フッター行を非表示にします。worktree フィールドはカスタムステータス行スクリプトに引き続き配信されます。ステータス行ですでにワークツリーを表示している場合のみ true に設定してください。そうしないと、すべての UI アフォーダンスを失います。
worktree.symlinkDirectoriesstring[]undefined作成時にメインリポジトリから汎用ワークツリーにシンボリックリンクするディレクトリ。パスはリポジトリルートからの相対パスです。絶対パスや .. を含むエントリは拒否されます。存在しないソースや既存の宛先は黙ってスキップされます(上書きはしません)。

例:

// ~/.qwen/settings.json または <repo>/.qwen/settings.json { "worktree": { "symlinkDirectories": ["node_modules", ".turbo", "dist"], }, }

すべてのワークツリー作成パスに適用されます: --worktree フラグ、enter_worktree ツール、agent isolation: "worktree"

汎用ワークツリーとは無関係ですが、知っておく価値のある設定:

  • agents.arena.worktreeBaseDirAgent Arena のワークツリー配置を制御します(デフォルト ~/.qwen/arena)。汎用ワークツリーには影響しません。汎用ワークツリーは常に <repoRoot>/.qwen/worktrees/ の下に置かれます。

worktree.sparsePaths のスキーマはまだありません — これはロードマップ項目です(制限事項 を参照)。

ツールリファレンス

enter_worktree

{ "name": "experiment-a" }
フィールドタイプ必須備考
namestringnoスラッグ。英字、数字、ドット、アンダースコア、ハイフン。最大64文字。省略時は自動生成。

以下の場合に実行を拒否:

  • CLI が Git リポジトリ内にない場合。
  • カレントワーキングディレクトリがすでに .qwen/worktrees/ 内にある場合(入れ子のワークツリーは不可)。

exit_worktree

{ "name": "experiment-a", "action": "remove", "discard_changes": false }
フィールドタイプ必須備考
namestringyesenter_worktree で使用したスラッグと一致する必要があります。
action"keep" | "remove"yeskeep はディレクトリとブランチを保持、remove は両方を削除。
discard_changesbooleanaction="remove" かつダーティな場合のみダーティツリーガードを上書きします。action="keep" では効果なし。

action: "remove"AUTO_EDIT 承認モードでも常に確認を求められます — これは破壊的なシェル操作として扱われ、情報のみのツールではありません。

agentisolation パラメーター

{ "subagent_type": "my-agent", "description": "…", "prompt": "…", "isolation": "worktree" }
フィールドタイプ必須備考
isolation"worktree"noエージェントを新しい agent-<7hex> ワークツリーで実行します。subagent_type の設定が必要です(フォーク不可)。

エージェントツールリファレンスの残りの部分については サブエージェント を参照してください。

CLI リファレンス

--worktree [name | #N | url]

qwen --worktree # スラッグ自動生成 qwen --worktree my-feature # 明示的なスラッグ qwen --worktree=my-feature # = 形式 qwen --worktree=#123 # PR 参照 qwen --worktree https://github.com/owner/repo/pull/123 # PR URL
入力結果
ベアフラグ(値なし)自動スラッグ <形容詞>-<名詞>-<6桁16進数>、ブランチ worktree-<slug>、ベース = 現在のブランチ
プレーンスラッグブランチ worktree-<slug>、ベース = 現在のブランチ。スラッグの検証: 英字/数字/ドット/アンダースコア/ハイフン、最大64文字
#N または <github-url>/pull/Nスラッグ pr-<N>、ブランチ worktree-pr-<N>、ベース = git fetch origin pull/<N>/head 後の FETCH_HEAD(30秒タイムアウト)

--worktree--acp / --experimental-acp と組み合わせることはできません。

--worktree--resume <session-id> と組み合わせた場合、ワークツリーが優先されます: 再開されたセッションの保存済みワークツリー(存在する場合)は上書きされ、stderr 行と最初のプロンプトリマインダーが上書きを報告します。

インタラクティブ(TUI)およびヘッドレス(-p)モードでは、ワークツリーが自動的に作成され、最初のターンの前にセッションがその中に chdir されます。

PR フェッチの失敗モード(終了コード != 0、ワークツリーは作成されない):

原因メッセージ抜粋
origin リモートが存在しないrequires an "origin" remote that points at GitHub
PR が origin に存在しないFailed to fetch PR #<N>: the PR does not exist on origin
30秒のネットワークタイムアウトFailed to fetch PR #<N>: timed out after 30s
PR 番号が範囲外 / ゼロInvalid PR number

制限事項

以下の項目は現在のフェーズでは意図的に実装されていません。

  • スパースチェックアウトなし。 大規模なモノレポではツリー全体がチェックアウトされます。(worktree.sparsePaths はロードマップ項目です。)
  • tmux 統合なし。 CLI は新しい tmux ウィンドウでワークツリーセッションを起動しません。
  • ワークツリーはセッションストレージにおいて独立した「プロジェクト」です。 --worktree foo で開始されたセッションは、そのワークツリーのチャットディレクトリの下に保存されます。後で再開するには、再度 --worktree foo を渡す必要があります。--worktree なしで開始されたセッションはメインチェックアウトの下に保存され、ワークツリーの再開ピッカーには表示されません。
  • スラッグをまたいだセッションのオーバーライドはありません。 qwen --resume <sid> --worktree second で、<sid>--worktree first で作成された場合、セッションを見つけることができません。セッションとワークツリーは projectHash(cwd) によって強く結合されています。既存のセッションでワークツリーを切り替えるには、終了してから新しい --worktree と新しいプロンプトで再起動する必要があります。将来のアーキテクチャ変更(ストレージのアンカーを cwd ではなくリポジトリルートにする)により、この制約は解消される可能性があります。
  • セッション中の enter_worktreeprocess.cwd()Config.targetDir を切り替えません。 そのツールはモデルコンテキストのみの規則を使用します(サブエージェント を参照)。起動時の --worktree フラグのみがプロセスの作業ディレクトリを実際に切り替えます。
  • 他の引数フィールドの相対パスは、ワークツリーの chdir の前に解決されます。 パスを受け取るフラグ(--mcp-config--openai-logging-dir--json-file--input-file--telemetry-outfile--include-directories)は、--worktree が設定されている場合、起動時の cwd を基準に絶対パスに正規化されます。このリストにない他のパス形状の argv フィールドは、ワークツリーの cwd に対して解決されます — 安全のために絶対パスを使用してください。
`docs/design/worktree.md` のロードマップを参照してください。 ## トラブルシューティング **フッターにワークツリーインジケーターが表示されない(ワークツリーを作成したばかりなのに)** `ui.hideBuiltinWorktreeIndicator` が `true` に設定されていないか確認してください。また、ツールの成功メッセージでスラッグが空でないことを確認してください。 **`--resume` でワークツリーが復元されない** `<chatsDir>/<sessionId>.worktree.json` が存在するか確認してください。ワークツリーディレクトリが削除されると、CLI はサイドカーを自動的に削除します。そのため、サイドカーとディレクトリの両方が存在しない場合は、「復元するワークツリーがない」という正常な状態であり、バグではありません。`--debug` フラグを付けて実行し、`restoreWorktreeContext` を grep して理由を確認してください。 **`exit_worktree` が「別のセッションによって作成されました」と表示する** これはセッション所有権ガードです。元のセッションを再開してそこから終了するか、提案された `git worktree remove …` コマンドを手動で実行してください。 **古い `agent-<hex>` ワークツリーがどんどん蓄積される** 30 日間の期限は控えめに設定されています。`git worktree list && git worktree remove <path>` で手動で掃除するか、待つだけでも構いません。30 日経過後の次の CLI 起動時に、ワークツリーがクリーンでプッシュ済みであれば自動的に削除されます。
Last updated on