using-git-worktrees · diff

git:20260629.d3d308c to git:20260629.a7208eb

20 added, 184 removed. Audit A to A.

---
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 via native tools or git worktree fallback
---
# Using Git Worktrees
- ## Overview
-
- Ensure work happens in an isolated workspace. Prefer your platform's native worktree tools. Fall back to manual git worktrees only when no native tool is available.
-
- **Core principle:** Detect existing isolation first. Then use native tools. Then fall back to git. Never fight the harness.
+ Ensure work runs in an isolated workspace. Detect existing isolation first, then prefer the harness's native worktree tool, then fall back to `git worktree`. Never fight the harness.
- **Announce at start:** "I'm using the using-git-worktrees skill to set up an isolated workspace."
+ Pairs with `[[main-only-branch]]` — `main` always committed, worktrees for isolation. The harness ships native worktree tools (`EnterWorktree`/`ExitWorktree`); use them over raw git.
- ## Step 0: Detect Existing Isolation
+ Announce: "Using the using-git-worktrees skill to set up an isolated workspace."
- **Before creating anything, check if you are already in an isolated workspace.**
+ ## Step 0 — detect existing isolation
```bash
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:
-
- ```bash
- # 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.
-
- Has the user already indicated their worktree preference in your instructions? If not, ask for consent before creating a worktree:
-
- > "Would you like me to set up an isolated worktree? It protects your current branch from changes."
-
- Honor any existing declared preference without asking. If the user declines consent, work in place and skip to Step 2.
-
- ## Step 1: Create Isolated Workspace
-
- **You have two mechanisms. Try them in this order.**
-
- ### 1a. Native Worktree Tools (preferred)
-
- The user has asked for an isolated workspace (Step 0 consent). Do you already have a way to create a worktree? It might be a tool with a name like `EnterWorktree`, `WorktreeCreate`, a `/worktree` command, or a `--worktree` flag. If you do, use it and skip to Step 2.
-
- Native tools handle directory placement, branch creation, and cleanup automatically. Using `git worktree add` when you have a native tool creates phantom state your harness can't see or manage.
-
- Only proceed to Step 1b if you have no native worktree tool available.
-
- ### 1b. Git Worktree Fallback
-
- **Only use this if Step 1a does not apply** — you have no native worktree tool available. Create a worktree manually using git.
-
- #### Directory Selection
-
- Follow this priority order. Explicit user preference always beats observed filesystem state.
-
- 1. **Check your instructions for a declared worktree directory preference.** If the user has already specified one, use it without asking.
-
- 2. **Check for an existing project-local worktree directory:**
-
- ```bash
- ls -d .worktrees 2>/dev/null # Preferred (hidden)
- ls -d worktrees 2>/dev/null # Alternative
- ```
-
- If found, use it. If both exist, `.worktrees` wins.
-
- 3. **If there is no other guidance available**, default to `.worktrees/` at the project root.
-
- #### Safety Verification (project-local directories only)
-
- **MUST verify directory is ignored before creating worktree:**
-
- ```bash
- git check-ignore -q .worktrees 2>/dev/null || git check-ignore -q worktrees 2>/dev/null
- ```
-
- **If NOT ignored:** Add to .gitignore, commit the change, then proceed.
-
- **Why critical:** Prevents accidentally committing worktree contents to repository.
-
- #### Create the Worktree
-
- ```bash
- # Determine path based on chosen location
- path="$LOCATION/$BRANCH_NAME"
-
- git worktree add "$path" -b "$BRANCH_NAME"
- cd "$path"
- ```
-
- **Sandbox fallback:** If `git worktree add` fails with a permission error (sandbox denial), 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:
-
- ```bash
- # Node.js
- if [ -f package.json ]; then npm install; fi
-
- # Rust
- if [ -f Cargo.toml ]; then cargo build; fi
-
- # Python
- if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- if [ -f pyproject.toml ]; then poetry install; fi
-
- # Go
- if [ -f go.mod ]; then go mod download; fi
- ```
-
- ## Step 3: Verify Clean Baseline
-
- Run tests to ensure workspace starts clean:
-
- ```bash
- # Use project-appropriate command
- npm test / cargo test / pytest / go test ./...
- ```
-
- **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) |
- | Native worktree tool available | Use it (Step 1a) |
- | No native tool | Git worktree fallback (Step 1b) |
- | `.worktrees/` exists | Use it (verify ignored) |
- | `worktrees/` exists | Use it (verify ignored) |
- | Both exist | Use `.worktrees/` |
- | Neither exists | Check instruction file, then default `.worktrees/` |
- | Directory not ignored | Add to .gitignore + commit |
- | Permission error on create | Sandbox fallback, work in place |
- | Tests fail during baseline | Report failures + ask |
- | No package.json/Cargo.toml | Skip dependency install |
-
- ## Common Mistakes
-
- ### Fighting the harness
-
- - **Problem:** Using `git worktree add` when the platform already provides isolation
- - **Fix:** Step 0 detects existing isolation. Step 1a defers to native tools.
-
- ### Skipping detection
-
- - **Problem:** Creating a nested worktree inside an existing one
- - **Fix:** Always run Step 0 before creating anything
-
- ### Skipping ignore verification
-
- - **Problem:** Worktree contents get tracked, pollute git status
- - **Fix:** Always use `git check-ignore` before creating project-local worktree
-
- ### Assuming directory location
-
- - **Problem:** Creates inconsistency, violates project conventions
- - **Fix:** Follow priority: explicit instructions > existing project-local directory > default
-
- ### Proceeding with failing tests
+ - `GIT_DIR != GIT_COMMON` is ALSO true in a submodule. Guard: `git rev-parse --show-superproject-working-tree` returns a path → you're in a submodule, treat as a normal repo.
+ - `GIT_DIR != GIT_COMMON` (not submodule) → already in a linked worktree. Skip to Step 2; do NOT nest another. Report the path + branch (note if detached HEAD — branch creation deferred to finish time).
+ - `GIT_DIR == GIT_COMMON` → normal checkout. If no worktree preference is declared in instructions, ask consent before creating one; honor a declared preference silently; if declined, work in place → Step 2.
- - **Problem:** Can't distinguish new bugs from pre-existing issues
- - **Fix:** Report failures, get explicit permission to proceed
+ ## Step 1 — create the workspace
- ## Red Flags
+ 1. **Native tool (preferred)** — if a worktree tool/command/flag exists (`EnterWorktree`, `/worktree`, `--worktree`), use it and skip to Step 2. It owns placement, branch, and cleanup; `git worktree add` alongside it creates phantom state the harness can't see.
+ 2. **Git fallback (only if no native tool):**
+ - Directory priority: declared instruction preference > existing `.worktrees/` (wins over `worktrees/`) > default `.worktrees/`.
+ - Verify ignored before creating: `git check-ignore -q .worktrees`. If not ignored, add to `.gitignore` + commit first — else worktree contents get tracked.
+ - `git worktree add "$LOCATION/$BRANCH_NAME" -b "$BRANCH_NAME" && cd "$_"`.
+ - Permission/sandbox denial on add → tell the user, work in place, run setup + baseline there.
- **Never:**
+ ## Step 2 — setup + baseline
- - Create a worktree when Step 0 detects existing isolation
- - Use `git worktree add` when you have a native worktree tool (e.g., `EnterWorktree`). This is the #1 mistake — if you have it, use it.
- - Skip Step 1a by jumping straight to Step 1b's git commands
- - Create worktree without verifying it's ignored (project-local)
- - Skip baseline test verification
- - Proceed with failing tests without asking
+ - Auto-detect and install: `package.json`→`npm install`, `Cargo.toml`→`cargo build`, `requirements.txt`→`pip install -r`, `pyproject.toml`→`poetry install`, `go.mod`→`go mod download`.
+ - Run the project test suite to confirm a clean baseline. Tests fail → report + ask before proceeding (can't tell new bugs from pre-existing). Tests pass → report ready: path, test count, feature.
- **Always:**
+ ## See
- - Run Step 0 detection first
- - Prefer native tools over git fallback
- - Follow directory priority: explicit instructions > existing project-local directory > default
- - Verify directory is ignored for project-local
- - Auto-detect and run project setup
- - Verify clean test baseline
+ - `[[main-only-branch]]` — worktrees for isolation, main always committed
+ - `finishing-a-development-branch` — merge/PR/cleanup when work is done