Worktree Isolation
Objective
Execute agent work in isolated git worktrees so that parallel tasks, subagent operations, and background work never modify the operator's working tree. Each worktree gets its own branch, its own filesystem snapshot, and a deterministic lifecycle from creation through merge or discard.
Scope
In-scope:
- Creating and configuring git worktrees for agent use
- Branch naming and worktree directory placement
- Running agents (main or sub) inside a worktree
- Committing, merging, pushing, and creating PRs from worktree branches
- Worktree cleanup and orphan prevention
- Parallel execution patterns for
/fleetand multi-agent workflows - Operator-concurrent workflows (agent works while human edits the main tree)
Out-of-scope:
- Git worktree internals or low-level plumbing commands
- Non-git version control systems
- Container-based or VM-based isolation
- CI/CD pipeline design
When to Use This Skill
Activate this skill when any of the following apply:
- The
/fleetcommand is dispatching parallel subagents that may touch overlapping files - A subagent needs to perform work without risk of corrupting the operator's staging area or uncommitted changes
- The operator wants to continue editing the working tree while an agent works in the background
- A task involves exploratory or speculative changes that should be easy to discard
- Multiple agents must each produce independent changesets for later review or merge
Do NOT use this skill when:
- The task modifies only a single file with no risk of conflict
- The operator explicitly requests in-place changes
- The repository is not a git repository
Worktree Directory Placement
Place worktrees in a persistent, user-invisible location that is not subject to OS-level temporary-file cleanup. The base directory depends on the platform.
Base Directory
All platforms use the same path under the user's home directory:
~/.local/share/copilot/worktrees/
If XDG_DATA_HOME is set, replace ~/.local/share with its value.
Create the base directory on first use if it does not exist.
Worktree Path Format
<base-directory>/<repo-name>--<branch-suffix>/
Example (Windows):
C:\Users\Mike\.local\share\copilot\worktrees\my-project--agent-alpha\
Example (Linux/macOS):
/home/user/.local/share/copilot/worktrees/my-project--agent-alpha/
The <repo-name> component is the basename of the git repository root directory. The <branch-suffix> matches the final segment of the branch name (see below).
Branch Naming
All worktree branches use a consistent prefix to distinguish them from human-created branches.
Convention
worktree/<purpose>-<unique>
Rules:
<purpose>is a lowercase, hyphen-separated slug describing the task<unique>is a 6-character random hex suffix to prevent collisions (e.g.,a3f1b2). Generate with:$(git rev-parse --short=6 HEAD)$(date +%s | tail -c 3)(Bash) or(-join ((48..57)+(97..102) | Get-Random -Count 6 | ForEach-Object {[char]$_}))(PowerShell)- For parallel agents, incorporate the agent identity before the suffix:
worktree/fleet-alpha-a3f1b2 - For single-agent isolation, describe the task:
worktree/refactor-auth-d8e4c1 - Maximum total branch name length: 100 characters
- The suffix is mandatory. Even sequential single-agent worktrees risk collision with leftover branches from previous runs.
Examples:
| Scenario | Branch name |
|---|---|
| Fleet agent "Alpha" | worktree/fleet-alpha-a3f1b2 |
| Fleet agent "Beta" | worktree/fleet-beta-7c9e01 |
| Isolated refactor task | worktree/refactor-auth-module-d8e4c1 |
| Background test generation | worktree/generate-api-tests-f0b3a9 |
Lifecycle
Every worktree follows a five-phase lifecycle: Create → Execute → Commit → Apply → Clean up.
Phase 1: Create
Create the worktree from the current HEAD of the active branch. Always create a new branch — never check out an existing branch into a worktree.
PowerShell (Windows)
$RepoRoot = git rev-parse --show-toplevel
$RepoName = Split-Path $RepoRoot -Leaf
$BranchName = "worktree/fleet-alpha-$(-join ((48..57)+(97..102) | Get-Random -Count 6 | ForEach-Object {[char]$_}))"
$Suffix = ($BranchName -split '/')[-1]
$WtBase = Join-Path $HOME ".local/share/copilot/worktrees"
$WtPath = Join-Path $WtBase "$RepoName--$Suffix"
if (-not (Test-Path $WtBase)) { New-Item -Path $WtBase -ItemType Directory -Force | Out-Null }
git worktree add $WtPath -b $BranchName
Bash (macOS/Linux)
repo_root=$(git rev-parse --show-toplevel)
repo_name=$(basename "$repo_root")
branch_name="worktree/fleet-alpha-$(head -c3 /dev/urandom | xxd -p | cut -c1-6)"
suffix="${branch_name##*/}"
wt_base="${XDG_DATA_HOME:-$HOME/.local/share}/copilot/worktrees"
wt_path="$wt_base/${repo_name}--${suffix}"
mkdir -p "$wt_base"
git worktree add "$wt_path" -b "$branch_name"
Verification
After creation, confirm the worktree exists:
git worktree list
Expected output includes a line for the new worktree with the correct branch.
Phase 2: Execute
Run the agent (or subagent) with its working directory set to the worktree path. The agent operates exclusively within that directory.
Rules for agents executing in a worktree:
- All file operations MUST use the worktree path, never the main repository path.
- The agent MUST NOT
cdto or modify files in the main working tree. - If the agent needs to run build/test commands, run them from the worktree directory.
- The agent SHOULD treat the worktree as its entire world — it has full read/write access within it.
Dispatching a subagent to a worktree:
When dispatching a subagent via the task tool, include these instructions in the prompt:
- State the worktree path explicitly: "Your working directory is
<wt_path>. All file operations use this path." - State the boundary: "Do NOT read or write files under
<main_repo_path>." - Include the branch name so the agent can verify it is on the correct branch.
Phase 3: Commit
After the agent completes its work, commit all changes on the worktree branch.
cd <wt_path>
git add -A
git commit -m "<conventional-commit-message>"
Commit message rules:
- Follow the repository's commit message conventions
- Include a clear description of what the agent accomplished
- For fleet agents, prefix the scope with the agent identity:
feat(alpha): add test.txt to all skills
If the agent is a subagent, it SHOULD commit its own work before reporting completion. The orchestrator MUST verify the commit exists.
Phase 4: Apply
After all worktree branches are committed, determine the appropriate strategy for integrating the work. Evaluate the criteria below in order — use the first matching strategy.
Decision Criteria
| Condition | Strategy | Action |
|---|---|---|
| Operator requested a PR | Push + PR | Push the branch to the remote and create a pull request |
| Changes need human review before integration | Push + share | Push the branch and report the branch name to the operator |
| Multiple worktree branches modify overlapping files | Sequential merge with conflict check | Merge branches one at a time, stopping on conflict for operator resolution |
| Changes are independent and low-risk | Direct merge | Merge the worktree branch into the active branch |
| Changes are speculative or experimental | Share only | Report the branch name to the operator without merging or pushing |
Push + PR
git push origin <branch-name>
# Then use the GitHub MCP server or gh CLI to create a PR
Direct Merge (from the main working tree)
cd <main_repo_path>
git merge --no-ff <branch-name> -m "merge: <description>"
Sequential Merge (multiple branches)
When merging multiple worktree branches that may overlap:
- Merge the first branch. If clean, continue.
- Merge the next branch. If conflicts arise, STOP.
- Report the conflict to the operator with the conflicting file list and branch names.
- Do NOT auto-resolve conflicts. The operator decides the resolution.
- After resolution, continue with remaining branches.
Post-Merge Verification
After any merge, verify the working tree is clean:
git status --short
If additional isolated work (tests, linting, validation) should run on the merged result before it is considered final, create a new worktree for that verification step rather than running it in the main tree.
Phase 5: Clean Up
Remove the worktree directory and optionally delete the branch.
Who Cleans Up
| Context | Responsible party | Rationale |
|---|---|---|
| Subagent completed and merged | Orchestrator | Orchestrator owns the lifecycle and has merge context |
| Single-agent isolation (no orchestrator) | Main agent | Same agent that created the worktree |
| Branch was pushed/shared for review | Operator | Human decides when the branch is no longer needed |
| Fleet execution with orchestrator | Orchestrator after all merges | Batch cleanup after all agents finish |
Cleanup Commands
# Remove the worktree
git worktree remove <wt_path> --force
# Delete the branch (only if merged or no longer needed)
git branch -d <branch-name>
# Use -D if the branch was never merged and should be discarded
git branch -D <branch-name>
# Prune stale worktree metadata (in case of unclean removal)
git worktree prune
Cleanup Rules
- MUST NOT delete a branch that has been pushed to a remote and has an open PR.
- MUST NOT delete a branch whose changes have not been merged or explicitly discarded by the operator.
- SHOULD delete the worktree directory even if the branch is kept (the branch persists in the git object store independent of the worktree).
- SHOULD run
git worktree pruneafter removing worktrees to keep metadata clean.
Fleet Parallel Execution Pattern
This is the standard pattern for /fleet or multi-agent parallel work.
Orchestrator Workflow
- Plan: Decompose the task into independent subtasks. Assign each subtask a unique agent name.
- Create: For each agent, create a worktree (Phase 1) with a unique branch name.
- Dispatch: Launch all agents in parallel. Each agent prompt includes its worktree path and branch name.
- Wait: Monitor agent completion.
- Verify: Check that each agent committed its work. Inspect commit logs on each branch.
- Merge: Apply changes using the decision criteria from Phase 4. Merge sequentially if branches may overlap.
- Clean up: Remove all worktrees and delete merged branches.
Example: Three Parallel Agents
Orchestrator creates (each branch gets a unique suffix):
worktree/fleet-alpha-a3f1b2 → <base>/my-project--fleet-alpha-a3f1b2/
worktree/fleet-beta-7c9e01 → <base>/my-project--fleet-beta-7c9e01/
worktree/fleet-gamma-d8e4c1 → <base>/my-project--fleet-gamma-d8e4c1/
Orchestrator dispatches agents in parallel:
Agent Alpha → works in fleet-alpha-a3f1b2 worktree
Agent Beta → works in fleet-beta-7c9e01 worktree
Agent Gamma → works in fleet-gamma-d8e4c1 worktree
Orchestrator merges (sequentially):
merge worktree/fleet-alpha-a3f1b2 → clean
merge worktree/fleet-beta-7c9e01 → conflict detected → report to operator
(operator resolves)
merge worktree/fleet-gamma-d8e4c1 → clean
Orchestrator cleans up:
remove all 3 worktrees
delete all 3 branches
Operator-Concurrent Workflow
When the operator wants to keep working while an agent runs in the background:
- Create a worktree for the agent task.
- Dispatch the agent to the worktree.
- The operator continues editing the main working tree freely.
- When the agent completes, the orchestrator reports the branch name.
- The operator decides when and how to integrate (merge, cherry-pick, or discard).
This pattern is useful for long-running tasks like test generation, documentation updates, or exploratory refactors.
Validation
Pass conditions:
- Worktree created in the correct base directory, not adjacent to the repository
- Branch name follows the
worktree/<purpose>convention - Agent operated exclusively within its worktree directory
- Main working tree was not modified during agent execution
- All changes committed on the worktree branch before cleanup
- Merge strategy matches the decision criteria
- Worktree directory removed after merge or discard
- Branch deleted only when safe (merged or explicitly discarded)
- No orphaned worktree metadata remains after cleanup