5.9 KiB
name, description, user-invocable
| name | description | user-invocable |
|---|---|---|
| worktrees | Git worktree patterns for parallel development workflows. Use when managing multiple concurrent branches, implementing issues in parallel, or isolating work contexts. | false |
Git Worktrees
Patterns and scripts for managing git worktrees in parallel development workflows.
What are Worktrees?
Git worktrees allow multiple working directories from a single repository. Each worktree can have a different branch checked out, enabling true parallel development.
Use cases:
- Implementing multiple issues simultaneously
- Isolated review environments for PRs
- Switching contexts without stashing
Naming Conventions
Directory structure:
project/
├── .git/ # Main repo
├── src/ # Main working tree
└── ../worktrees/ # Sibling worktrees directory
├── project-issue-42/ # Issue implementation
├── project-issue-43/ # Another issue
└── project-review-55/ # PR review
Naming patterns:
- Issue work:
${REPO_NAME}-issue-${ISSUE_NUMBER} - PR review:
${REPO_NAME}-review-${PR_NUMBER} - Feature work:
${REPO_NAME}-feature-${FEATURE_NAME}
Why sibling directory:
- Keeps main repo clean
- Easy to identify worktrees
- Simple bulk operations
- Works with tooling that scans parent directories
Creating Worktrees
For Issue Implementation
REPO_PATH=$(pwd)
REPO_NAME=$(basename "$REPO_PATH")
WORKTREES_DIR="${REPO_PATH}/../worktrees"
ISSUE_NUMBER=42
# Create worktrees directory
mkdir -p "$WORKTREES_DIR"
# Fetch latest
git fetch origin
# Get issue title for branch name
ISSUE_TITLE=$(tea issues $ISSUE_NUMBER | grep -i "title" | head -1 | cut -d: -f2- | xargs)
BRANCH_NAME="issue-${ISSUE_NUMBER}-$(echo "$ISSUE_TITLE" | tr '[:upper:]' '[:lower:]' | tr ' ' '-' | tr -cd '[:alnum:]-' | cut -c1-50)"
# Create worktree with new branch from main
git worktree add "${WORKTREES_DIR}/${REPO_NAME}-issue-${ISSUE_NUMBER}" \
-b "$BRANCH_NAME" origin/main
For PR Review
# For reviewing existing PR branch
PR_NUMBER=55
BRANCH_NAME="issue-42-feature-name" # Get from PR details
git fetch origin
git worktree add "${WORKTREES_DIR}/${REPO_NAME}-review-${PR_NUMBER}" \
"origin/${BRANCH_NAME}"
Bundled Scripts
Use bundled scripts for error-prone operations. Scripts are located in ~/.claude/skills/worktrees/scripts/:
Create Worktree
# Usage: ~/.claude/skills/worktrees/scripts/create-worktree.sh issue <issue-number>
# Usage: ~/.claude/skills/worktrees/scripts/create-worktree.sh review <pr-number> <branch-name>
~/.claude/skills/worktrees/scripts/create-worktree.sh issue 42
~/.claude/skills/worktrees/scripts/create-worktree.sh review 55 issue-42-feature-name
Returns worktree path on success.
List Worktrees
~/.claude/skills/worktrees/scripts/list-worktrees.sh
Shows all active worktrees with their branches.
Cleanup Worktrees
# Remove specific worktree
~/.claude/skills/worktrees/scripts/cleanup-worktrees.sh "${WORKTREES_DIR}/${REPO_NAME}-issue-42"
# Remove all worktrees in directory
~/.claude/skills/worktrees/scripts/cleanup-worktrees.sh "${WORKTREES_DIR}"
# Force remove even if dirty
~/.claude/skills/worktrees/scripts/cleanup-worktrees.sh --force "${WORKTREES_DIR}"
Patterns
Pattern: Parallel Issue Implementation
Orchestrator creates all worktrees upfront:
for issue in 42 43 44; do
worktree_path=$(~/.claude/skills/worktrees/scripts/create-worktree.sh issue $issue)
# Spawn worker with worktree_path
done
Worker uses provided worktree:
cd "$WORKTREE_PATH" # Provided by orchestrator
# Do work
git add -A && git commit -m "..."
git push -u origin $(git branch --show-current)
Orchestrator cleans up after all complete:
~/.claude/skills/worktrees/scripts/cleanup-worktrees.sh "${WORKTREES_DIR}"
Pattern: Review in Isolation
Create review worktree:
worktree_path=$(~/.claude/skills/worktrees/scripts/create-worktree.sh review $PR_NUMBER $BRANCH_NAME)
cd "$worktree_path"
git diff origin/main...HEAD # Review changes
Pattern: Error Recovery
List stale worktrees:
~/.claude/skills/worktrees/scripts/list-worktrees.sh
Force cleanup:
~/.claude/skills/worktrees/scripts/cleanup-worktrees.sh --force "${WORKTREES_DIR}"
Best Practices
Always provide worktree paths to agents:
- Orchestrator creates worktrees
- Agents receive path as parameter
- Agents work in provided path
- Orchestrator handles cleanup
Never nest cleanup:
- Only orchestrator cleans up
- Agents never remove their own worktree
- Cleanup happens after all work complete
Track worktree paths:
# In orchestrator
declare -A worktrees
worktrees[42]=$(~/.claude/skills/worktrees/scripts/create-worktree.sh issue 42)
worktrees[43]=$(~/.claude/skills/worktrees/scripts/create-worktree.sh issue 43)
# Pass to agents
spawn_agent --worktree="${worktrees[42]}"
Handle errors gracefully:
- Use scripts (they handle errors)
- Always cleanup, even on failure
- Force-remove if necessary
Common Issues
Worktree already exists:
# Remove old worktree first
~/.claude/skills/worktrees/scripts/cleanup-worktrees.sh "${WORKTREES_DIR}/${REPO_NAME}-issue-42"
# Then create new one
~/.claude/skills/worktrees/scripts/create-worktree.sh issue 42
Branch already exists:
# Delete branch if safe
git branch -d issue-42-old-name
# Or force delete
git branch -D issue-42-old-name
Stale worktrees after crash:
# List and force remove
~/.claude/skills/worktrees/scripts/list-worktrees.sh
~/.claude/skills/worktrees/scripts/cleanup-worktrees.sh --force "${WORKTREES_DIR}"
Tips
- Keep worktrees short-lived (hours, not days)
- Clean up regularly to avoid clutter
- Use scripts for reliability
- Let orchestrator manage lifecycle
- Check
git worktree listif unsure about state