230 lines
5.9 KiB
Markdown
230 lines
5.9 KiB
Markdown
---
|
|
name: worktrees
|
|
description: >
|
|
Git worktree patterns for parallel development workflows. Use when managing
|
|
multiple concurrent branches, implementing issues in parallel, or isolating
|
|
work contexts.
|
|
user-invocable: 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
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
~/.claude/skills/worktrees/scripts/list-worktrees.sh
|
|
```
|
|
|
|
Shows all active worktrees with their branches.
|
|
|
|
### Cleanup Worktrees
|
|
|
|
```bash
|
|
# 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:**
|
|
```bash
|
|
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:**
|
|
```bash
|
|
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:**
|
|
```bash
|
|
~/.claude/skills/worktrees/scripts/cleanup-worktrees.sh "${WORKTREES_DIR}"
|
|
```
|
|
|
|
### Pattern: Review in Isolation
|
|
|
|
**Create review worktree:**
|
|
```bash
|
|
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:**
|
|
```bash
|
|
~/.claude/skills/worktrees/scripts/list-worktrees.sh
|
|
```
|
|
|
|
**Force cleanup:**
|
|
```bash
|
|
~/.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:**
|
|
```bash
|
|
# 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:**
|
|
```bash
|
|
# 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:**
|
|
```bash
|
|
# 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:**
|
|
```bash
|
|
# 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 list` if unsure about state
|