Isolated git worktrees for Claude Code sessions. Prevents multiple Claude instances from stepping on each other's git state.
When running multiple Claude agents or sessions on the same repo, they can conflict:
- Competing for staging area
- Conflicting uncommitted changes
- One agent's commit including another's work
Each Claude session runs in its own git worktree - a separate working directory with its own branch. Work is isolated, and auto-committed on exit so nothing is lost.
./install.sh
source ~/.zshrcThis adds the cc alias to your shell.
cc [description words]Examples:
cc # → worktree/session-20260113-1400
cc fix auth bug # → worktree/fix-auth-bug-20260113-1400
cc refactor email agent # → worktree/refactor-email-agent-20260113-1401cc fix auth bug- Creates branch
worktree/fix-auth-bug-20260113-1400 - Creates directory
<repo>-wt-fix-auth-bug-<pid> - Rsyncs
.envand other dotfiles (excludes.venv,node_modules) - Launches Claude in the worktree
- Work happens in isolated branch
- Main repo is untouched
- Claude sees a SessionStart hook message about being in a worktree (if configured)
On quit, Ctrl+C, or crash:
- If uncommitted changes exist:
- Stages all changes (
git add -A) - Uses Claude haiku to summarize the diff
- Commits as
WIP (fix-auth-bug): <summary>
- Stages all changes (
- Worktree directory is deleted
- Branch is preserved
# List all worktree branches with age and summary
git for-each-ref --sort=-committerdate \
--format='%(refname:short) %(committerdate:relative) %(subject)' \
refs/heads/worktree/
# Example output:
# worktree/fix-auth-bug-20260113-1400 2 hours ago WIP (fix-auth-bug): Add validation for sender field
# worktree/refactor-20260112-0930 1 day ago WIP (refactor): Extract email parser to separate module
# Merge useful work
git merge worktree/fix-auth-bug-20260113-1400
# Delete stale branches
git branch -D worktree/fix-auth-bug-20260113-1400
# Bulk delete old worktree branches
git branch | grep 'worktree/' | xargs git branch -DThe script rsyncs dotfiles from the main repo, excluding heavy directories:
Included:
.env,.envrc, and other dotfiles
Excluded:
.venv(runuv syncto recreate)node_modules(runnpm installto recreate).git__pycache__,*.pyc.mypy_cache,.pytest_cache
To inform Claude it's in a worktree, add this hook to your repo's .claude/settings.json:
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/worktree-info.sh"
}
]
}
]
}
}And create .claude/hooks/worktree-info.sh:
#!/bin/bash
WORKTREE_INFO=$(git worktree list --porcelain 2>/dev/null | head -1)
MAIN_WORKTREE=$(echo "$WORKTREE_INFO" | sed 's/worktree //')
CURRENT_DIR=$(pwd)
if [ "$CURRENT_DIR" != "$MAIN_WORKTREE" ] && [ -n "$MAIN_WORKTREE" ]; then
BRANCH=$(git branch --show-current)
echo "You are working in a git worktree (isolated workspace)."
echo "Path: $CURRENT_DIR"
echo "Branch: $BRANCH"
echo "Main repo: $MAIN_WORKTREE"
echo ""
echo "Note: .venv may not exist - run 'uv sync' if needed for Python modules."
fi- Work is never lost - auto-commit + branch preserved
- Main repo stays clean - no stray uncommitted changes
- Multiple agents can work in parallel - each in their own worktree
- Meaningful commit messages - LLM-generated summaries of changes
- Easy cleanup - directory deleted, just branches to manage