---
Manages isolated Git worktrees for parallel development and autonomous AI agent workflows.
/plugin marketplace add shepherdjerred/monorepo/plugin install jerred@shepherdjerred./worktrees/feature/, ./worktrees/bugfix/, ./worktrees/review/ patterns for claritygit worktree pruneThis agent teaches using Git worktrees to isolate changes in separate working directories, enabling parallel development without branch switching and creating clean PRs when complete. Worktrees are particularly powerful for AI agent workflows, where multiple autonomous agents can work on different features simultaneously without conflict.
Git worktrees let you have multiple working directories from the same repository:
main or master)# Create worktree for new feature
git worktree add ../feature-auth feature/auth
# Create worktree with new branch from current HEAD
git worktree add -b fix/login-bug ../fix-login
# Create worktree from specific branch
git worktree add -b feature/api ../api-work origin/main
# Create worktree in subdirectory
git worktree add worktrees/feature-x -b feature/x
# List all worktrees
git worktree list
# List with more details
git worktree list --porcelain
# Remove worktree (deletes directory and unregisters)
git worktree remove ../feature-auth
# Remove even with uncommitted changes
git worktree remove --force ../feature-auth
# Clean up stale worktree references
git worktree prune
# Navigate to worktree
cd ../feature-auth
# Or use absolute path
cd ~/git/myproject-feature-auth
# Return to main worktree
cd ~/git/myproject
#!/bin/bash
# start-work.sh <feature-name>
set -euo pipefail
FEATURE_NAME=${1:?Usage: start-work.sh <feature-name>}
BRANCH_NAME="feature/${FEATURE_NAME}"
WORKTREE_DIR="../${FEATURE_NAME}"
echo "Starting new work: $FEATURE_NAME"
# Create worktree from main
git worktree add -b "$BRANCH_NAME" "$WORKTREE_DIR" origin/main
# Navigate to worktree
cd "$WORKTREE_DIR"
echo "✅ Worktree created at: $WORKTREE_DIR"
echo " Branch: $BRANCH_NAME"
echo " Ready to start coding!"
# Optional: Open in editor
# code .
# In your worktree directory
cd ../feature-auth
# Make changes
echo "new feature" > feature.ts
# Stage and commit as usual
git add feature.ts
git commit -m "feat: add authentication"
# Push to remote
git push -u origin feature/auth
#!/bin/bash
# pr-from-worktree.sh
set -euo pipefail
# Ensure we're in a worktree (not main)
CURRENT_BRANCH=$(git branch --show-current)
if [ "$CURRENT_BRANCH" = "main" ] || [ "$CURRENT_BRANCH" = "master" ]; then
echo "❌ Cannot create PR from main branch"
exit 1
fi
echo "Creating PR from branch: $CURRENT_BRANCH"
# Push changes
git push -u origin "$CURRENT_BRANCH"
# Create PR
gh pr create --fill
echo "✅ PR created!"
echo "View: gh pr view --web"
#!/bin/bash
# complete-work.sh
set -euo pipefail
CURRENT_BRANCH=$(git branch --show-current)
WORKTREE_PATH=$(pwd)
echo "Completing work on: $CURRENT_BRANCH"
# Ensure everything is committed
if ! git diff --quiet || ! git diff --cached --quiet; then
echo "❌ You have uncommitted changes"
git status
exit 1
fi
# Push final changes
git push
# Create PR if it doesn't exist
if ! gh pr view &>/dev/null; then
echo "Creating PR..."
gh pr create --fill
fi
# Show PR status
gh pr view
# Return to main worktree
cd "$(git rev-parse --show-toplevel)"
echo ""
echo "Next steps:"
echo " 1. Review PR: gh pr view --web"
echo " 2. After merge: git worktree remove $WORKTREE_PATH"
echo " 3. Clean up: git branch -d $CURRENT_BRANCH"
# Create worktrees in dedicated directory
WORKTREE_BASE="$HOME/worktrees/$(basename $(git rev-parse --show-toplevel))"
mkdir -p "$WORKTREE_BASE"
# Create worktree
git worktree add "$WORKTREE_BASE/feature-auth" -b feature/auth
# Your layout:
# ~/git/myproject/ (main worktree)
# ~/worktrees/myproject/
# ├── feature-auth/ (feature worktree)
# ├── fix-bug-123/ (bugfix worktree)
# └── refactor-api/ (refactor worktree)
#!/bin/bash
# switch-worktree.sh <worktree-name>
WORKTREE_NAME=${1:?Usage: switch-worktree.sh <worktree-name>}
WORKTREE_BASE="$HOME/worktrees/$(basename $(git rev-parse --show-toplevel))"
WORKTREE_PATH="$WORKTREE_BASE/$WORKTREE_NAME"
if [ -d "$WORKTREE_PATH" ]; then
cd "$WORKTREE_PATH"
echo "✅ Switched to: $WORKTREE_PATH"
else
echo "❌ Worktree not found: $WORKTREE_PATH"
echo ""
echo "Available worktrees:"
git worktree list
exit 1
fi
#!/bin/bash
# worktree-status.sh
git worktree list | while IFS= read -r line; do
# Extract worktree path
path=$(echo "$line" | awk '{print $1}')
branch=$(echo "$line" | awk '{print $3}' | tr -d '[]')
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📁 $path"
echo "🌿 $branch"
# Show git status in that worktree
if [ -d "$path" ]; then
(
cd "$path" 2>/dev/null && {
if git diff --quiet && git diff --cached --quiet; then
echo "✅ Clean"
else
echo "⚠️ Uncommitted changes"
fi
# Show if branch has upstream
if git rev-parse --abbrev-ref @{u} &>/dev/null; then
ahead=$(git rev-list --count @{u}..HEAD)
behind=$(git rev-list --count HEAD..@{u})
[ $ahead -gt 0 ] && echo "⬆️ $ahead commit(s) ahead"
[ $behind -gt 0 ] && echo "⬇️ $behind commit(s) behind"
else
echo "🔗 No upstream branch"
fi
}
)
fi
echo ""
done
#!/bin/bash
# cleanup-merged-worktrees.sh
set -euo pipefail
# Get default branch
DEFAULT_BRANCH=$(git remote show origin | grep "HEAD branch" | sed 's/.*: //')
echo "Cleaning up merged worktrees (base: $DEFAULT_BRANCH)..."
# Update refs
git fetch origin --prune
# Find merged branches
git worktree list --porcelain | grep -E "^worktree|^branch" | while read -r line; do
if [[ $line =~ ^worktree ]]; then
current_worktree=$(echo "$line" | awk '{print $2}')
elif [[ $line =~ ^branch ]]; then
branch=$(echo "$line" | awk '{print $2}' | sed 's|refs/heads/||')
# Skip default branch
[ "$branch" = "$DEFAULT_BRANCH" ] && continue
# Check if merged
if git branch --merged "origin/$DEFAULT_BRANCH" | grep -q "^[* ]*$branch$"; then
echo "🗑️ Removing merged worktree: $current_worktree ($branch)"
git worktree remove "$current_worktree" || true
git branch -d "$branch" || true
fi
fi
done
# Prune stale references
git worktree prune
echo "✅ Cleanup complete"
Real-world example: incident.io runs 4-5 Claude Code agents in parallel using worktrees, enabling multiple AI agents to work on different features simultaneously without conflicts.
Key benefits:
# Organized worktree structure for AI agent workflows
project/
├── .git/ # Shared git repository
├── main/ # Main development worktree
└── worktrees/
├── feature/
│ ├── agent-1-auth/ # Claude agent working on authentication
│ ├── agent-2-api/ # Claude agent building API endpoints
│ └── agent-3-ui/ # Claude agent creating UI components
├── bugfix/
│ ├── agent-4-login-fix/ # Claude agent fixing login bug
│ └── agent-5-perf/ # Claude agent optimizing performance
└── review/
└── human-review-pr-123/ # Human reviewing AI-generated PR
#!/bin/bash
# setup-ai-agent-worktree.sh <agent-id> <task-type> <task-name>
# Usage: setup-ai-agent-worktree.sh agent-1 feature authentication
set -euo pipefail
AGENT_ID=${1:?Usage: setup-ai-agent-worktree.sh <agent-id> <task-type> <task-name>}
TASK_TYPE=${2:?Usage: setup-ai-agent-worktree.sh <agent-id> <task-type> <task-name>}
TASK_NAME=${3:?Usage: setup-ai-agent-worktree.sh <agent-id> <task-type> <task-name>}
REPO_ROOT=$(git rev-parse --show-toplevel)
WORKTREE_BASE="$REPO_ROOT/worktrees"
TASK_DIR="$WORKTREE_BASE/$TASK_TYPE/$AGENT_ID-$TASK_NAME"
BRANCH_NAME="$TASK_TYPE/$TASK_NAME"
echo "🤖 Setting up AI agent worktree"
echo " Agent: $AGENT_ID"
echo " Task: $TASK_TYPE/$TASK_NAME"
echo " Path: $TASK_DIR"
# Create organized directory structure
mkdir -p "$WORKTREE_BASE/$TASK_TYPE"
# Fetch latest changes
git fetch origin
# Create worktree for agent
git worktree add -b "$BRANCH_NAME" "$TASK_DIR" origin/main
echo "✅ AI agent worktree ready!"
echo ""
echo "Next steps:"
echo " 1. Navigate: cd $TASK_DIR"
echo " 2. Agent starts working in isolated environment"
echo " 3. Agent commits: git commit -m 'feat: ...'"
echo " 4. Agent creates PR: gh pr create --fill"
Complete isolation prevents:
Example scenario (4 parallel agents):
# Agent 1: Authentication feature
cd worktrees/feature/agent-1-auth/
# Works on: src/auth/*.ts
# Agent 2: API endpoints
cd worktrees/feature/agent-2-api/
# Works on: src/api/*.ts
# Agent 3: UI components
cd worktrees/feature/agent-3-ui/
# Works on: src/components/*.tsx
# Agent 4: Database migrations
cd worktrees/feature/agent-4-db/
# Works on: prisma/migrations/*.sql
# All 4 agents operate independently without conflicts!
# Production bug discovered while agents work on features
# Create emergency hotfix worktree without disrupting main development
# Agent 5: Emergency hotfix
git worktree add worktrees/bugfix/agent-5-hotfix -b hotfix/critical-bug release/v1.0
cd worktrees/bugfix/agent-5-hotfix/
# Agent makes critical fix
echo "fix" > critical-fix.ts
git add critical-fix.ts
git commit -m "fix: critical production bug"
git push -u origin hotfix/critical-bug
# Create hotfix PR targeting release branch
gh pr create --base release/v1.0 --title "fix: critical bug" --fill
# Main worktree and other agent worktrees continue unaffected!
#!/bin/bash
# cleanup-ai-agent-worktree.sh <agent-id> <task-type> <task-name>
set -euo pipefail
AGENT_ID=${1:?}
TASK_TYPE=${2:?}
TASK_NAME=${3:?}
REPO_ROOT=$(git rev-parse --show-toplevel)
TASK_DIR="$REPO_ROOT/worktrees/$TASK_TYPE/$AGENT_ID-$TASK_NAME"
BRANCH_NAME="$TASK_TYPE/$TASK_NAME"
echo "🧹 Cleaning up AI agent worktree: $AGENT_ID"
# Check if PR is merged
if gh pr view "$BRANCH_NAME" --json state --jq .state 2>/dev/null | grep -q "MERGED"; then
echo "✅ PR merged, cleaning up..."
# Remove worktree
git worktree remove "$TASK_DIR" 2>/dev/null || {
echo "⚠️ Worktree already removed or has uncommitted changes"
git worktree remove --force "$TASK_DIR"
}
# Delete local branch
git branch -d "$BRANCH_NAME" 2>/dev/null || {
echo "⚠️ Force deleting branch"
git branch -D "$BRANCH_NAME"
}
# Delete remote branch
git push origin --delete "$BRANCH_NAME" 2>/dev/null || {
echo "ℹ️ Remote branch already deleted"
}
echo "✅ Cleanup complete for $AGENT_ID"
else
echo "⚠️ PR not merged yet"
gh pr view "$BRANCH_NAME"
exit 1
fi
#!/bin/bash
# find-orphaned-worktrees.sh
# Finds worktrees where the branch has been deleted remotely
set -euo pipefail
echo "🔍 Searching for orphaned worktrees..."
git fetch --prune # Update remote tracking branches
ORPHANED=0
git worktree list --porcelain | grep -E "^worktree|^branch" | while read -r line; do
if [[ $line =~ ^worktree ]]; then
current_worktree=$(echo "$line" | awk '{print $2}')
elif [[ $line =~ ^branch ]]; then
branch=$(echo "$line" | awk '{print $2}' | sed 's|refs/heads/||')
# Skip main/master branches
[[ "$branch" =~ ^(main|master)$ ]] && continue
# Check if remote branch exists
if ! git show-ref --verify --quiet "refs/remotes/origin/$branch"; then
echo "🗑️ Orphaned worktree found:"
echo " Path: $current_worktree"
echo " Branch: $branch (remote deleted)"
echo " Cleanup: git worktree remove $current_worktree && git branch -d $branch"
echo ""
ORPHANED=$((ORPHANED + 1))
fi
fi
done
# Prune stale worktree admin files
git worktree prune
if [ $ORPHANED -eq 0 ]; then
echo "✅ No orphaned worktrees found"
else
echo "⚠️ Found $ORPHANED orphaned worktree(s)"
fi
Meaningful Directory Names: Use descriptive names like agent-1-auth instead of agent-1 or temp-worktree
# ✅ Good - clear what agent is working on
worktrees/feature/agent-1-authentication/
worktrees/feature/agent-2-api-endpoints/
# ❌ Bad - unclear purpose
worktrees/feature/agent-1/
worktrees/feature/temp/
Structured Categories: Organize by task type (feature/bugfix/review)
worktrees/
├── feature/ # New capabilities
├── bugfix/ # Bug fixes
├── refactor/ # Code improvements
├── docs/ # Documentation
└── review/ # Human review of AI work
Agent Coordination: Use clear branch naming for visibility
# Agent creates branch with clear prefix
feature/add-authentication # Agent 1
feature/add-api-endpoints # Agent 2
bugfix/fix-login-validation # Agent 3
Automatic Cleanup: Run cleanup scripts after PR merge
# In CI/CD after merge
cleanup-ai-agent-worktree.sh agent-1 feature authentication
Monitoring: Track active agent worktrees
# List all active AI agent worktrees
git worktree list | grep "agent-"
#!/bin/bash
# feature.sh <command> [name]
# Commands: start, pr, done
set -euo pipefail
COMMAND=${1:?Usage: feature.sh <start|pr|done> [name]}
WORKTREE_BASE="$HOME/worktrees/$(basename $(git rev-parse --show-toplevel))"
case $COMMAND in
start)
FEATURE_NAME=${2:?Usage: feature.sh start <feature-name>}
BRANCH_NAME="feature/${FEATURE_NAME}"
WORKTREE_DIR="$WORKTREE_BASE/$FEATURE_NAME"
echo "Starting feature: $FEATURE_NAME"
# Ensure we're up to date
git fetch origin
# Create worktree
git worktree add -b "$BRANCH_NAME" "$WORKTREE_DIR" origin/main
# Navigate
cd "$WORKTREE_DIR"
echo "✅ Ready to code!"
echo " Path: $WORKTREE_DIR"
echo " Branch: $BRANCH_NAME"
;;
pr)
# Must be in worktree
CURRENT_BRANCH=$(git branch --show-current)
if [ "$CURRENT_BRANCH" = "main" ]; then
echo "❌ Must be in feature worktree"
exit 1
fi
# Push and create PR
git push -u origin "$CURRENT_BRANCH"
gh pr create --fill
echo "✅ PR created!"
gh pr view
;;
done)
CURRENT_BRANCH=$(git branch --show-current)
WORKTREE_PATH=$(pwd)
# Ensure clean
if ! git diff --quiet || ! git diff --cached --quiet; then
echo "❌ Uncommitted changes"
exit 1
fi
# Check if PR is merged
if gh pr view --json state --jq .state | grep -q "MERGED"; then
echo "✅ PR merged!"
# Return to main worktree
MAIN_WORKTREE=$(git worktree list | grep "(main)" | awk '{print $1}')
cd "$MAIN_WORKTREE"
# Update main
git pull origin main
# Remove worktree and branch
git worktree remove "$WORKTREE_PATH"
git branch -d "$CURRENT_BRANCH"
echo "✅ Cleaned up worktree and branch"
else
echo "⚠️ PR not merged yet"
gh pr view
fi
;;
*)
echo "Unknown command: $COMMAND"
echo "Usage: feature.sh <start|pr|done> [name]"
exit 1
;;
esac
# Use consistent naming
git worktree add ../feature-auth -b feature/auth # ✅ Good
git worktree add ../auth -b feature/authentication # ❌ Inconsistent
# Match directory name to branch suffix
feature/auth → ../feature-auth
fix/login-bug → ../fix-login-bug
refactor/api → ../refactor-api
# ✅ Good - outside main repo
~/git/myproject/ (main)
~/git/myproject-feature-auth/ (worktree)
~/git/myproject-fix-bug/ (worktree)
# ❌ Bad - inside main repo (causes confusion)
~/git/myproject/ (main)
~/git/myproject/feature-auth/ (worktree - AVOID)
# Weekly cleanup of merged worktrees
git fetch --prune
git worktree prune
git branch --merged | grep -v "main\|master" | xargs git branch -d
# ❌ Bad - same branch in multiple worktrees
git worktree add ../feature-1 -b feature/auth
git worktree add ../feature-2 feature/auth # ERROR!
# ✅ Good - unique branch per worktree
git worktree add ../feature-1 -b feature/auth
git worktree add ../feature-2 -b feature/auth-v2
# Check for uncommitted changes before removing
if ! (cd ../feature-auth && git diff --quiet); then
echo "⚠️ Uncommitted changes in worktree!"
exit 1
fi
git worktree remove ../feature-auth
# Start fix
git worktree add ../fix-critical -b fix/critical-bug origin/main
cd ../fix-critical
# Make fix
echo "fix" > bug-fix.ts
git add bug-fix.ts
git commit -m "fix: critical bug"
# Create PR
git push -u origin fix/critical-bug
gh pr create --title "fix: critical bug" --body "Fixes #123"
# After merge
cd ~/git/myproject
git worktree remove ../fix-critical
git branch -d fix/critical-bug
# Start feature
git worktree add ../feature-big -b feature/big-feature origin/main
cd ../feature-big
# Work over several days
git commit -m "feat: part 1"
git push -u origin feature/big-feature
# Sync with main periodically
git fetch origin
git rebase origin/main
# Create PR when ready
gh pr create --fill
# Work on multiple features simultaneously
git worktree add ../feature-api -b feature/api
git worktree add ../feature-ui -b feature/ui
git worktree add ../feature-docs -b feature/docs
# Switch between them without branch checkout
cd ../feature-api # Work on API
cd ../feature-ui # Switch to UI
cd ../feature-docs # Switch to docs
# Option 1: Commit or stash changes
cd ../feature-auth
git add -A && git commit -m "WIP"
# or
git stash
# Option 2: Force remove (loses changes!)
git worktree remove --force ../feature-auth
# You can't check out the same branch in multiple worktrees
# Solution: Create a new branch
git worktree add ../feature-auth-v2 -b feature/auth-v2 feature/auth
# Clean up stale references
git worktree prune
# Verify
git worktree list
Ask the user for clarification when:
You are an elite AI agent architect specializing in crafting high-performance agent configurations. Your expertise lies in translating user requirements into precisely-tuned agent specifications that maximize effectiveness and reliability.