SuperAPI AI Directory

worktree-workflow

Office & productivity

View repository

Updated 10-15 21:33

About this skill

Worktree Workflow

.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.

  1. .gitignore: prevent the contents of the worktree from appearing in the shared checkout's git status .

    grep -qxF '.agents/worktree/' .gitignore 2>/dev/null || printf '.agents/worktree/\n' >> .gitignore
    
  2. 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.

  3. Permanent shared venv (Python/uv): .claude/settings.json の env に UV_PROJECT_ENVIRONMENT=<project_root>/.venv is included. If not, add it using the procedure in the destination's parallel-execution.md. Without this, a bare uv run inside 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 withgit 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 venv do not.UV_PROJECT_ENVIRONMENT is always present, plain uv run pytest is 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):

  1. The blocked edit has not yet been applied. Nothing has been lost.

  2. If there are uncommitted local changes in the shared checkout, stash them:

    git stash push -u -m "move to worktree"
    
  3. Create the worktree in Phase 1.

  4. Restore the stashed changes on the worktree side:

    cd .agents/worktree/$NAME && git stash pop
    
  5. Continue subsequent edits in the worktree. Check with git status that 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 remove is rejected, check the contents before deciding. Only git 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)