| name | git-worktree |
| description | Git worktree management for isolated parallel development. Use when reviewing PRs in isolation, working on multiple features simultaneously, or when workflows offer worktree option. |
| argument-hint | [create|list|switch|cleanup] <name> |
| user-invokable | true |
Git Worktree Manager
Manage git worktrees for isolated parallel development with a simple, safe
interface.
What It Does
Creates and manages git worktrees — separate working directories from the same
repository that allow you to:
- Work on multiple branches simultaneously without stashing
- Review PRs in complete isolation from your current work
- Test features without switching branches in your main working directory
- Keep separate .env configurations per worktree
Critical Rule
ALWAYS use the manager script. NEVER use raw git worktree add directly.
The manager script provides:
- Automatic .env file copying
- .gitignore management
- Safety validations
- Consistent directory structure
- Color-coded output
Manager Script Location
${CLAUDE_PLUGIN_ROOT}/skills/git-worktree/scripts/worktree-manager.sh
Replace ${CLAUDE_PLUGIN_ROOT} with the actual plugin installation path.
Usage
create
Create a new worktree:
worktree-manager.sh create <branch-name> [from-branch]
Behavior:
- Creates worktree in
.worktrees/<branch-name>/
- Branches from
main by default (or specify from-branch)
- Copies all
.env* files from main repo
- Adds
.worktrees/ to .gitignore if missing
- Symlinks the main repo's
.ruvector/ into the worktree if it exists
(see ruvector DB Sharing below)
- Fails safely if worktree already exists
Examples:
worktree-manager.sh create feature-auth
worktree-manager.sh create hotfix-security develop
list / ls
List all worktrees:
worktree-manager.sh list
worktree-manager.sh ls
Output:
Worktrees:
main /home/user/repo (clean)
feature-auth /home/user/repo/.worktrees/feature-auth (modified)
pr-review-123 /home/user/repo/.worktrees/pr-review-123 (clean)
switch / go
Switch to a worktree directory:
worktree-manager.sh switch <name>
worktree-manager.sh go <name>
Note: Prints cd command for shell evaluation:
eval "$(worktree-manager.sh switch feature-auth)"
wtgo() { eval "$(worktree-manager.sh go "$1")"; }
copy-env
Copy .env files to a worktree:
worktree-manager.sh copy-env <name>
Copies all .env* files from main repo to specified worktree. Useful if you've
updated environment configuration and need to sync. Also repairs a missing
.ruvector/ symlink for worktrees created before that feature existed (see
below).
ruvector DB Sharing
When a Claude Code session runs inside a worktree, the ruvector MCP server
resolves ${PWD}/.ruvector/ against the worktree path. Because .ruvector/
is gitignored (**/.ruvector/), it is not present in a fresh worktree, so
the MCP server and hook scripts would silently no-op (no recall, no
session-start context, no post-edit indexing).
worktree-manager.sh create injects an absolute symlink
${worktree}/.ruvector -> ${main_repo}/.ruvector after the .env copy step,
so MCP and hooks reach the project's shared DB. worktree-manager.sh copy-env
applies the same fix retroactively.
Behavior:
- Skipped silently (with
info) if the symlink already exists — idempotent.
- Skipped (with
warning) if a real .ruvector/ directory already exists in
the worktree — preserves the user's intentional isolated DB if they bypassed
the manager script.
- Skipped (with
warning) if the main repo has no .ruvector/ yet — no
dangling symlinks.
- Removed safely on
cleanup: [ -L ] check, then rm -- (no -r, no -f,
no trailing slash). Cannot follow into the main repo's DB.
MCP-spawn-time qualifier: RUVECTOR_STORAGE_PATH is evaluated when
Claude Code spawns the MCP server process for a session. The symlink only
helps when Claude Code is launched (or re-launched) from inside the
worktree directory. A pre-existing session started in main that later
cds into a worktree continues to write to the main repo's DB directly.
Concurrent-write caveat: When two Claude Code sessions run simultaneously
(one in main, one in a worktree, or two worktrees), both MCP server processes
write to the same shared DB without cross-process locking. Avoid running
simultaneous sessions with active hooks_remember / /ruvector:index
operations on the same project. See plugins/yellow-ruvector/CLAUDE.md
Known Limitations.
cleanup / clean
Remove inactive worktrees:
worktree-manager.sh cleanup
worktree-manager.sh clean
Behavior:
- Lists all worktrees
- Prompts for confirmation
- Removes worktrees one by one
- Skips currently active worktree
- Removes empty
.worktrees/ directory if all cleaned up
When to Use
Code Review (/workflows:review)
When reviewing a PR and you're not on the target branch:
/workflows:review
Parallel Feature Development (/workflows:work)
When working on multiple features:
/workflows:work
cd .worktrees/feature-2
/workflows:work
Manual Worktree Management
When you need direct control:
worktree-manager.sh create experimental-refactor
eval "$(worktree-manager.sh go experimental-refactor)"
worktree-manager.sh list
worktree-manager.sh cleanup
Workflow Examples
Example 1: Code Review with Worktree
$ git branch --show-current
feature-auth
$ /workflows:review pr-123
$ worktree-manager.sh cleanup
Example 2: Parallel Feature Development
$ pwd
/home/user/myproject
$ worktree-manager.sh create feature-b
Created worktree: .worktrees/feature-b
$ eval "$(worktree-manager.sh go feature-b)"
$ pwd
/home/user/myproject/.worktrees/feature-b
$ nvim src/feature-b.ts
$ git commit -m "feat: prototype feature B"
$ cd /home/user/myproject
Integration with Workflows
/workflows:review Integration
When /workflows:review detects you're not on the target branch:
- Offers worktree option
- Calls this skill:
/git-worktree create pr-review-<number>
- Switches to worktree
- Proceeds with review in isolation
/workflows:work Integration
When starting feature work:
- Asks if you want isolated environment
- Calls:
/git-worktree create <branch-name>
- Copies .env files automatically
- Starts feature work in worktree
Auto-Trust mise/direnv After Worktree Creation
If your project uses mise (.mise.toml,
.tool-versions) or direnv (.envrc), the new
worktree directory starts untrusted — the tool refuses to load
configs until the user explicitly opts in. This breaks the principle of
least surprise: you create a worktree, cd in, and tooling silently
fails to load.
The fix is to auto-trust the new worktree directory at creation time.
The manager script handles common cases; the patterns below show how to
do it explicitly when needed (e.g., a CI runner creating a throwaway
worktree).
mise:
cd .worktrees/feature-auth
mise trust 2>/dev/null || true
mise --cwd .worktrees/feature-auth trust 2>/dev/null || true
direnv:
cd .worktrees/feature-auth
direnv allow 2>/dev/null || true
direnv allow .worktrees/feature-auth 2>/dev/null || true
Suppress on absent tools: 2>/dev/null || true keeps the trust step
quiet when neither mise nor direnv is installed. Do not drop the
redirect — without it, missing-binary stderr leaks into worktree
creation logs.
Why this is per-worktree: mise and direnv key trust on the absolute
path of the directory containing the config. A worktree at
.worktrees/feature-auth/ is a different absolute path from the main
repo, even when the .mise.toml content is identical.
.git-Is-a-File Detection (Submodule and Worktree Cases)
In a normal repo, .git is a directory. But in two important cases it
is a plain file containing a gitdir: <path> pointer:
- Inside a submodule: the submodule's
.git is a file pointing at
<superproject>/.git/modules/<submodule-name>.
- Inside an existing worktree: the worktree's
.git is a file
pointing at <main-repo>/.git/worktrees/<worktree-name>.
Naive scripts that do [ -d .git ] to detect a git repo will misclassify
both cases as "not a git repo" and fail in confusing ways.
Detection pattern:
is_git_repo() {
[ -e .git ] && git rev-parse --git-dir >/dev/null 2>&1
}
git_dir_kind() {
if [ -d .git ]; then
echo "directory"
elif [ -f .git ]; then
case "$(head -n 1 .git)" in
"gitdir: "*/.git/worktrees/*) echo "worktree" ;;
"gitdir: "*/.git/modules/*) echo "submodule" ;;
"gitdir: "*) echo "linked" ;;
*) echo "unknown" ;;
esac
else
echo "none"
fi
}
Worktree creation inside a submodule: Avoid creating a worktree
inside a directory whose .git is the submodule pointer file —
git worktree add from a submodule treats the submodule's gitdir as
the parent, which lands the new worktree under
<superproject>/.git/modules/<sub>/worktrees/, far from where users
expect. Always run worktree commands from the superproject root, or
explicitly pass -C <superproject-root> to git worktree add.
Why this matters for the manager script: the helper resolves
get_repo_root via git rev-parse --show-toplevel, which already
returns the correct top-level whether .git is a file or directory.
But any caller that pre-checks [ -d .git ] before invoking the helper
will short-circuit incorrectly. Use git rev-parse --git-dir (which
handles both forms) instead.
Troubleshooting
See troubleshooting.md for common issues and solutions.
Design Principles
KISS (Keep It Simple, Stupid)
- One script does everything
- Clear command names
- No complex configuration
- Fails fast with clear errors
Opinionated Defaults
- Worktrees always in
.worktrees/ directory
- Always branch from
main (unless specified)
- Always copy .env files
- Branch name = worktree name (1:1 mapping)
Safety First
- Never overwrites existing worktrees
- Requires confirmation for cleanup
- Adds .gitignore automatically
- Color-coded warnings and errors
Reference
Git worktree documentation:
man git-worktree
Common git worktree commands:
git worktree list
git worktree remove <path>
git worktree prune
But use the manager script instead for consistent, safe operations.