.agents/worktree/<name> dedicated worktree placed at Procedure . The policy of "when a worktree is mandatory" and "what the exceptions are"
is held by rules/git-workflow.md , so it is not repeated here.
This skill is used with both Claude Code and Codex. In Claude Code, --worktree or at isolation startup,
kit's WorktreeCreate hook handles creation on your behalf, so in that case start from "Procedure after creation". Deletion at exit is also
handled by the WorktreeRemove hook, but worktrees containing uncommitted changes, locks, or initialized submodules,
worktrees committed without creating a branch (unreachable from any branch), and worktrees with ignore targets other than caches
(such as .env) are left behind, so clean them up in Phase 6.
When to Use
- When starting Issue resolution, feature development, or multi-file implementation (immediately after Plan approval, before the first Edit)
- When you try to edit in the shared checkout and are stopped by a hook saying "please start from a worktree"
- When assigning a work location to each worker in parallel implementation
- When a PR is merged and you clean up the worktree
- When told "cut a worktree", "create a worktree", "list worktrees", or "clean up worktrees"
Layout and Naming
| Item | Value |
|---|---|
| Location | <project_root>/.agents/worktree/<name> (do not create in upstream or sibling directories) |
<name> |
Branch name with / を - . Example: fix/issue-123 → fix-issue-123 |
| branch | fix/issue-<n>, feat/issue-<n>, refactor/issue-<n> (naming from git-workflow.md) |
| Starting point | origin/<default branch> immediately after fetching |
.agents/ is the same parent as the skills entity (.agents/skills/). Agents use a fixed relative path, and people use VS Code's
Source Control; either way, looking here is sufficient.
Phase 0: One-time Setup (per repository)
First time only. Skip if already done.
-
.gitignore: prevent the contents of the worktree from appearing in the shared checkout'sgit status.grep -qxF '.agents/worktree/' .gitignore 2>/dev/null || printf '.agents/worktree/\n' >> .gitignore -
VS Code detection setting (recommended): the default folder scan depth is 1 level, so
.agents/worktree/<name>is not covered by the scan. Worktree detection (git.detectWorktrees, enabled by default since 1.103) picks it up, but just in case place the following in.vscode/settings.json. Do not overwrite existing keys.{ "git.repositoryScanMaxDepth": 2, "git.detectWorktrees": true }Worktrees are listed in the Source Control Repositories view, and in multi-repo mode diffs are also displayed across repositories.
-
Permanent shared venv (Python/uv):
.claude/settings.jsonのenvにUV_PROJECT_ENVIRONMENT=<project_root>/.venvis included. If not, add it using the procedure in the destination's parallel-execution.md. Without this, a bareuv runinside the worktree will create a separate venv.
Phase 1: Start a Worktree
cd "$(git rev-parse --show-toplevel)" # 共有 checkout へ
git fetch origin
DEFAULT="$(git symbolic-ref --short refs/remotes/origin/HEAD | sed 's#^origin/##')"
BRANCH="fix/issue-123"
NAME="${BRANCH//\//-}"
git worktree add ".agents/worktree/$NAME" -b "$BRANCH" "origin/$DEFAULT"
cd ".agents/worktree/$NAME"
-
If a worktree with the same name already exists, reuse it (check with
git worktree list). Do not recreate it. -
Worktree created by the hook (Claude Code の
--worktree/ isolation) is handed over in detached HEAD. Create a branch first inside it:git switch -c "$BRANCH" -
In repositories with submodules, initialize only source (do not touch the execution environment):
git submodule update --init --recursive
Immediately after creation, git status と git branch --show-current confirm "correct worktree, correct branch" before
starting to edit.
Phase 2: Work Inside the Worktree
-
Pin cwd to the worktree. Every Bash call points inside the worktree by absolute path. Do not go back to the shared checkout to make edits (the hook denies edits to protected directories).
-
Shared venv: per worktree
uv sync/uv venvdo not.UV_PROJECT_ENVIRONMENTis always present, plainuv run pytestis fine. In a shell where it is not in effect, specify it explicitly:UV_PROJECT_ENVIRONMENT="$(git rev-parse --path-format=absolute --git-common-dir | xargs dirname)/.venv" uv run pytest tests/test_x.py -
Operations that rewrite the lockfile / venv (
uv sync,uv lock,uv add) are performed serially in the shared checkout, and are not run from the worktree. For details, see parallel-execution.md. -
Verify starting from the smallest unit: run only the tests for the modules you touched, and run the full suite once before the PR (problem-solving.md).
-
commit / push are done inside this worktree.
git push -u origin "$BRANCH"。
Phase 3: Recover From a Hook Block
If you are stopped by the PreToolUse hook while trying to edit src/tests in the shared checkout (the same applies to any of Claude Code's Edit / Write / NotebookEdit or Codex's apply_patch):
-
The blocked edit has not yet been applied. Nothing has been lost.
-
If there are uncommitted local changes in the shared checkout, stash them:
git stash push -u -m "move to worktree" -
Create the worktree in Phase 1.
-
Restore the stashed changes on the worktree side:
cd .agents/worktree/$NAME && git stash pop -
Continue subsequent edits in the worktree. Check with
git statusthat the shared checkout's working tree has returned to clean.
Phase 4: Parallel Workers
- A separate worktree and a separate branch per worker. Include the scope of responsibility in the name, like
<type>-issue-<n>-<scope>. - Specify the write scope (files/modules in charge) at assignment time, and consolidate overlapping scopes into one worker.
- Either the lead creates it and passes the absolute path, or isolation startup lets the hook create it. Either way, the location is the same.
- All workers use the same shared venv, so a worker that needs to add dependencies asks the lead, and the lead does it serially in the shared checkout.
Phase 5: Hand Off to PR
Once implementation and verification are done inside the worktree:
git push -u origin "$BRANCH"
gh pr create --fill --base "$DEFAULT"
Once the PR is ready, pr-maintainer (policy) and pr-autoloop (self-driving). Continue in the same worktree and the same session. CI monitoring, fixes, and merge decisions from here on are outside the scope of this skill.
Phase 6: Clean Up After Merge
Do this immediately after merge. Do not leave it unattended.
cd "$(git rev-parse --path-format=absolute --git-common-dir | xargs dirname)" # 共有 checkout へ戻る
git worktree remove ".agents/worktree/$NAME"
git branch -d "$BRANCH"
git fetch --prune
git worktree prune
- When cwd is the deletion target, move to the shared checkout first (the first line above).
- If uncommitted changes remain and
removeis rejected, check the contents before deciding. Onlygit worktree remove --forceif you have confirmed it is safe to discard. If you cannot confirm, stop and report. - When cleaning up in bulk, the targets are those under
.agents/worktree/that have no uncommitted changes and whose branch is already merged (git branch --merged "origin/$DEFAULT"). If the destination has a cleanup Makefile target, use it (see the project-specific section in git-workflow.md).
List check:
git worktree list --porcelain
Troubleshooting
| Symptom | Action |
|---|---|
fatal: '<branch>' is already checked out at ... |
A worktree for that branch already exists.git worktree list to find the location and reuse it |
git worktree add later .agents/worktree/x が git status appears in |
Phase 0 の .gitignore is not set |
in the worktree uv run が .venv started creating a new one |
UV_PROJECT_ENVIRONMENT is not taking effect. Run with the explicit form of Phase 2 and fix the env in settings |
| The worktree does not appear in VS Code | Check the Phase 0 settings.git.detectWorktreesLimit (default 50) exceeded is also suspected |
remove が contains modified or untracked files failed with |
Check the contents. If necessary, commit/stash; if it is fine to discard, --force |
| Deleted the worktree directory by hand | git worktree prune to remove the registration, and the branch is git branch -d |
| The hook fails to create the worktree and the session does not start | stderr の git worktree add 失敗 Read. In many cases it is leftover debris from a directory with the same name.prune Re-run after |
WorktreeRemove hook failed; kept worktree |
hook は --force is not used, so worktrees containing changes, locks, or submodules remain. It also remains when HEAD is not reachable from any branch (if necessary, preserve with git branch <name> ) and when there are ignore targets other than the cache. Check the contents and delete using the Phase 6 procedure |
Related
- rules/git-workflow.md: Conditions under which a worktree is required, exceptions, and the definition of completion
- rules/parallel-execution.md: Details of the shared venv and parallel execution
- pr-maintainer / pr-autoloop: maintenance after PR creation
- kit hooks:
hook_worktree_create.py(proxy for creation),hook_worktree_remove.py(proxy for deletion),hook_pre_edit_worktree.py(edit gate for the shared checkout)