Skip to content

feat: Add generic git worktree support (EnterWorktree/ExitWorktree tools + Agent isolation) #4056

@LaZzyMan

Description

@LaZzyMan

What would you like to be added?

Add first-class git worktree support as a general-purpose capability in qwen-code. This includes two user-facing tools (EnterWorktree and ExitWorktree) and an isolation: 'worktree' parameter for the Agent tool, allowing both users and agents to work in isolated git worktrees without affecting the main working directory.

The implementation is planned in four phases:

Phase A — Core tools (user session-level worktree)

  • EnterWorktree tool: creates a worktree at .qwen/worktrees/<slug>, switches the session's working directory into it, and persists the worktree state in SessionService (including --resume support)
  • ExitWorktree tool: exits with keep (preserves the worktree branch) or remove (deletes the worktree and branch); refuses removal when uncommitted changes exist unless discard_changes: true is set
  • Tool prompts that guide the model to call these tools only when the user explicitly mentions "worktree"

Phase B — Agent isolation + prompt updates

  • isolation: 'worktree' parameter on the Agent tool: spins up a temporary worktree (agent-<7hex>) for the subagent, auto-cleans it on exit if no changes were made, and returns the worktree path and branch if changes exist
  • Periodic stale worktree cleanup: scans .qwen/worktrees/ for ephemeral agent-<7hex> slugs older than 30 days with no unpushed commits and removes them (fail-closed)
  • Update AgentTool description to document the isolation: 'worktree' parameter
  • Add buildWorktreeNotice(): inject context into fork subagents running in worktree isolation, telling them they are in an isolated worktree, that paths are inherited from the parent agent, and that files should be re-read before editing

Phase C — Quality-of-life

  • Post-creation setup: configure core.hooksPath to point at the main repo (qwen-code has no settings.local.json equivalent, so only hooks setup applies)
  • StatusLine display of the current worktree name and branch
  • WorktreeExitDialog: prompt the user to keep or remove the worktree when the session exits while a worktree is still active
  • worktree.symlinkDirectories config: symlink directories like node_modules to avoid disk duplication

Phase D — Advanced

  • --worktree [name] CLI flag: launch the entire session inside a new worktree from the start
  • worktree.sparsePaths config for git sparse-checkout (large monorepo optimization)
  • .worktreeinclude file support: copy gitignored files into the worktree
  • --worktree=#<PR> shorthand: auto-fetch a PR and create a worktree from it
  • tmux integration: --worktree --tmux

Why is this needed?

qwen-code already has an internal worktree implementation used exclusively by Arena (multi-model comparison). However, there is no way for a user or an agent to isolate work in a worktree during a normal session. This means any experimental change risks polluting the main working directory, and agents cannot be given a safe sandbox to operate in independently.

Worktree isolation is especially valuable when:

  • Trying out a risky refactor without touching the current branch
  • Running multiple agents on independent tasks in parallel without conflicts
  • Reviewing or testing a PR in an isolated environment

Additional context

Design constraints:

  • The existing Arena worktree logic (GitWorktreeService, ArenaManager, agents.arena.worktreeBaseDir config) must remain completely unchanged — Arena and general-purpose worktrees are independent
  • The existing /review skill manages its own worktrees at .qwen/tmp/review-pr-<n> via dedicated CLI commands; it does not overlap with the general-purpose worktree system and requires no changes
  • Worktree state for user sessions is stored in the existing SessionService, not as a new global
  • General-purpose worktrees always live under {repo root}/.qwen/worktrees/; Arena worktrees remain under ~/.qwen/arena (configurable)

Full design doc: docs/design/worktree.md

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions