worktree
Create an isolated git worktree for code changes. Use when starting work on a new feature, bug fix, or any changes that should be on a separate branch. Keeps the main working directory clean.
When & Why to Use This Skill
This Claude skill automates the creation and management of isolated Git worktrees, enabling seamless parallel development without the friction of context switching. It solves the problem of workspace clutter and the 'stash-and-switch' overhead by allowing developers to maintain multiple active branches in separate directories, complete with automatic environment initialization and permission inheritance.
Use Cases
- Parallel Feature Development: Work on a new feature in an isolated directory while keeping your main workspace stable for other tasks.
- Urgent Bug Fixes: Quickly switch to a hotfix branch without the need to stash or commit incomplete work in your current development branch.
- Code Reviews: Checkout a colleague's pull request into a separate worktree to test and review code without disrupting your own local environment.
- Multi-Version Testing: Run and compare different versions or branches of a project side-by-side in independent environments for integration testing.
- Clean Environment Setup: Automatically initialize dependencies (npm, pip, go mod, etc.) and copy local settings when spinning up a new branch workspace.
| name | worktree |
|---|---|
| description | Create an isolated git worktree for code changes. Use when starting work on a new feature, bug fix, or any changes that should be on a separate branch. Keeps the main working directory clean. |
| allowed-tools | Bash, Read, Write, Glob |
Git Worktree Workflow
Create and manage isolated git worktrees for parallel development with automatic permission inheritance.
Permission Handling
Claude Code permissions work as follows in worktrees:
| Settings File | Location | Behavior in Worktrees |
|---|---|---|
.claude/settings.json |
Project (committed) | Automatically inherited - shared via git |
.claude/settings.local.json |
Project (gitignored) | Not inherited - must be copied manually |
~/.claude/settings.json |
User global | Always available in all worktrees |
Key insight: If your team's permissions are in .claude/settings.json (committed), all worktrees automatically get them with zero additional setup.
Creating a Worktree
Step 1: Gather Information
If not already clear, ask:
- Feature name: What are you working on? (will be used for branch/directory name)
- Base branch: Create from main/master or another branch?
Step 2: Verify Prerequisites
# Ensure we're in a git repository
git rev-parse --show-toplevel || { echo "Not a git repository"; exit 1; }
# Check for uncommitted changes that might cause issues
git status --porcelain
Step 3: Create the Worktree
# Set up variables
REPO_ROOT=$(git rev-parse --show-toplevel)
REPO_NAME=$(basename "$REPO_ROOT")
PARENT_DIR=$(dirname "$REPO_ROOT")
FEATURE_NAME="<kebab-case-feature-name>" # e.g., add-auth, fix-pagination
BASE_BRANCH="${BASE_BRANCH:-main}" # or master, develop, etc.
# Create worktree with new branch
WORKTREE_PATH="$PARENT_DIR/$REPO_NAME-$FEATURE_NAME"
git worktree add "$WORKTREE_PATH" -b "$FEATURE_NAME" "$BASE_BRANCH"
Step 4: Copy Local Settings (if they exist)
# Copy local settings if present (these are gitignored so not shared automatically)
if [ -f "$REPO_ROOT/.claude/settings.local.json" ]; then
mkdir -p "$WORKTREE_PATH/.claude"
cp "$REPO_ROOT/.claude/settings.local.json" "$WORKTREE_PATH/.claude/"
echo "Copied .claude/settings.local.json to worktree"
fi
Step 5: Initialize Environment
Detect and run appropriate setup commands:
cd "$WORKTREE_PATH"
# Node.js projects
if [ -f "package-lock.json" ]; then
npm ci # or npm install
elif [ -f "yarn.lock" ]; then
yarn install --frozen-lockfile
elif [ -f "pnpm-lock.yaml" ]; then
pnpm install --frozen-lockfile
elif [ -f "bun.lockb" ]; then
bun install
# Python projects
elif [ -f "requirements.txt" ]; then
# Suggest virtual environment
echo "Python project detected. Consider:"
echo " python -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt"
elif [ -f "pyproject.toml" ]; then
# Poetry or other Python build system
if command -v poetry &> /dev/null && grep -q "\[tool.poetry\]" pyproject.toml; then
poetry install
elif command -v uv &> /dev/null; then
uv sync
fi
# Go projects
elif [ -f "go.mod" ]; then
go mod download
# Rust projects
elif [ -f "Cargo.toml" ]; then
cargo fetch
fi
Step 6: Confirm Setup
echo ""
echo "Worktree created successfully!"
echo " Directory: $WORKTREE_PATH"
echo " Branch: $FEATURE_NAME"
echo " Based on: $BASE_BRANCH"
echo ""
echo "To start working:"
echo " cd $WORKTREE_PATH"
echo " claude"
Managing Worktrees
List All Worktrees
git worktree list
Switch to an Existing Worktree
# Just cd to the worktree directory
cd "$PARENT_DIR/$REPO_NAME-<feature-name>"
Check Worktree Status
# From any worktree, list all with status
git worktree list --porcelain
Completing Work
After Making Changes
Commit your changes:
git add -A git commit -m "feat: description of changes"Push the branch:
git push -u origin "$FEATURE_NAME"Create a PR (optional):
gh pr create --fill
Cleanup
# Return to main repository
cd "$PARENT_DIR/$REPO_NAME"
# Remove the worktree (use -f if there are uncommitted changes)
git worktree remove "$WORKTREE_PATH"
# If branch was merged, delete it
git branch -d "$FEATURE_NAME"
Bulk Cleanup (remove stale worktrees)
# Preview what would be pruned
git worktree prune --dry-run
# Actually prune stale worktree entries
git worktree prune
Error Handling
Worktree Already Exists
# Check if worktree exists
if git worktree list | grep -q "$FEATURE_NAME"; then
echo "Worktree for '$FEATURE_NAME' already exists."
# Offer: reuse existing, create with suffix, or abort
fi
Branch Already Exists
# If branch exists but no worktree, use it
git worktree add "$WORKTREE_PATH" "$FEATURE_NAME"
# Or create with a unique suffix
git worktree add "$WORKTREE_PATH-2" -b "$FEATURE_NAME-2" "$BASE_BRANCH"
Dirty Worktree During Removal
# Force remove (discards uncommitted changes!)
git worktree remove --force "$WORKTREE_PATH"
Best Practices
Permission Setup: Put common tool permissions in
.claude/settings.json(committed) so all worktrees inherit them automaticallyNaming Convention: Use descriptive names like
repo-feature-auth,repo-fix-login-bugEnvironment Variables: Keep
.envfiles consistent or copy them to new worktreesSession Isolation: Each worktree gets its own Claude Code session context - use
/resumeto see sessions from all worktrees in the same repoCleanup Regularly: Remove worktrees after PRs are merged to avoid confusion
Quick Reference
| Task | Command |
|---|---|
| Create worktree | git worktree add ../repo-feature -b feature main |
| List worktrees | git worktree list |
| Remove worktree | git worktree remove ../repo-feature |
| Prune stale | git worktree prune |
| Lock worktree | git worktree lock ../repo-feature |
| Unlock worktree | git worktree unlock ../repo-feature |