main

name: using-git-worktrees description: Use when starting feature work that needs isolation from current workspace or before executing implementation plans - ensures an isolated workspace exists under the single global worktree root

Using Git Worktrees

Overview

Ensure work happens in an isolated workspace.

Core principle: Detect existing isolation first. Then use a native tool. Then fall back to raw git. Never fight the harness.

Every worktree lives under ~/.local/share/worktrees/. There is exactly one worktree root on this machine. Never create a worktree in /tmp, directly in $HOME, or next to the repository.

Announce at start: “I’m using the using-git-worktrees skill to set up an isolated workspace.”

Step 0: Detect Existing Isolation

Before creating anything, check if you are already in an isolated workspace.

GIT_DIR=$(cd "$(git rev-parse --git-dir)" 2>/dev/null && pwd -P)
GIT_COMMON=$(cd "$(git rev-parse --git-common-dir)" 2>/dev/null && pwd -P)
BRANCH=$(git branch --show-current)

Submodule guard: GIT_DIR != GIT_COMMON is also true inside git submodules. Before concluding “already in a worktree,” verify you are not in a submodule:

# If this returns a path, you're in a submodule, not a worktree — treat as normal repo
git rev-parse --show-superproject-working-tree 2>/dev/null

If GIT_DIR != GIT_COMMON (and not a submodule): You are already in a linked worktree. Skip to Step 2 (Project Setup). Do NOT create another worktree.

Report with branch state:

  • On a branch: “Already in isolated workspace at <path> on branch <name>.”
  • Detached HEAD: “Already in isolated workspace at <path> (detached HEAD, externally managed). Branch creation needed at finish time.”

If GIT_DIR == GIT_COMMON (or in a submodule): You are in a normal repo checkout.

Ask for consent before creating a worktree, unless the user already asked for one:

“Would you like me to set up an isolated worktree? It protects your current branch from changes.”

If the user declines, work in place and skip to Step 2.

Step 1: Create the Worktree

Use the first mechanism that is available.

1a. lazyworktree / the git_worktree tool (preferred)

Both place worktrees under ~/.local/share/worktrees/ automatically and handle branch creation and cleanup. If you have the git_worktree tool, use it and skip to Step 2.

1b. herdr worktree create

Use this when the worktree should come with its own herdr workspace and agent pane. It requires an explicit --path — without it herdr falls back to its own ~/.herdr/worktrees root:

herdr worktree create --cwd "$REPO" --branch "$BRANCH" --base main \
  --path ~/.local/share/worktrees/<owner>/<repo>/"$BRANCH"

Note: the herdr MCP tool’s worktree-create action exposes no path parameter. If you only have the MCP tool, either accept its default root or shell out to the CLI above.

1c. Raw git (last resort)

owner=<github-owner>   # fork owner for fork workflows, else the org
repo=$(basename "$(git rev-parse --show-toplevel)")
path=~/.local/share/worktrees/$owner/$repo/$BRANCH_NAME

git worktree add "$path" -b "$BRANCH_NAME"
cd "$path"

The global root needs no gitignore verification — it is outside every repository.

Sandbox fallback: If git worktree add fails with a permission error, tell the user the sandbox blocked worktree creation and you’re working in the current directory instead. Then run setup and baseline tests in place.

Step 2: Project Setup

Auto-detect and run appropriate setup:

if [ -f package.json ]; then npm install; fi        # Node.js
if [ -f Cargo.toml ]; then cargo build; fi          # Rust
if [ -f pyproject.toml ]; then uv sync; fi          # Python (uv, not pip)
if [ -f go.mod ]; then go mod download; fi          # Go
if [ -f flake.nix ]; then direnv allow 2>/dev/null || true; fi

Step 3: Verify Clean Baseline

Run tests to ensure the workspace starts clean, using the project-appropriate command (make test, go test ./..., cargo test, npm test, pytest).

If tests fail: Report failures, ask whether to proceed or investigate. If tests pass: Report ready.

Report

Worktree ready at <full-path>
Tests passing (<N> tests, 0 failures)
Ready to implement <feature-name>

Quick Reference

Situation Action
Already in linked worktree Skip creation (Step 0)
In a submodule Treat as normal repo (Step 0 guard)
git_worktree tool / lwt available Use it (Step 1a)
Need a herdr workspace too herdr worktree create --path ... (Step 1b)
Nothing else available Raw git with explicit path (Step 1c)
Tempted by /tmp, $HOME, .worktrees/ Never — use the global root
Permission error on create Sandbox fallback, work in place
Tests fail during baseline Report failures + ask

Common Mistakes

Fighting the harness

  • Problem: Using git worktree add when a native tool is available
  • Fix: Step 0 detects existing isolation; Step 1a defers to native tools

Forgetting --path with herdr

  • Problem: Worktree silently lands in ~/.herdr/worktrees, invisible to lwt
  • Fix: Always pass --path under the global root

Skipping detection

  • Problem: Creating a nested worktree inside an existing one
  • Fix: Always run Step 0 before creating anything

Proceeding with failing tests

  • Problem: Can’t distinguish new bugs from pre-existing issues
  • Fix: Report failures, get explicit permission to proceed

Red Flags

Never:

  • Create a worktree when Step 0 detects existing isolation
  • Create a worktree outside ~/.local/share/worktrees/
  • Use raw git worktree add when git_worktree / lwt is available
  • Skip baseline test verification
  • Proceed with failing tests without asking

Always:

  • Run Step 0 detection first
  • Prefer native tools over the git fallback
  • Pass --path to herdr worktree create
  • Verify a clean test baseline