Your parallel agentic coding workflow follows a simple lifecycle:
cd into the right
directory.
Open a terminal. We'll simulate the complete lifecycle: create โ work โ
merge โ cleanup. Use a real repo โ the pocock-skills repo
you're in right now works perfectly.
# Create a directory for your worktrees (do this once, ever):
mkdir -p ~/dev/worktrees
# Agent 1: building dark mode feature
git worktree add ~/dev/worktrees/dark-mode -b feat/dark-mode
# Agent 2: fixing a login timeout bug
git worktree add ~/dev/worktrees/fix-login -b fix/login-timeout
# Agent 3: reviewing PR #42
git fetch origin pull/42/head:pr-42
git worktree add ~/dev/worktrees/review-pr-42 pr-42
# Verify your setup:
git worktree list
Three worktrees created in under 3 seconds. No clones, no network, no waiting.
In a real workflow, each AI agent would work in its own directory.
Let's simulate that manually โ imagine each cd block is a
different agent process:
# === AGENT 1: Dark Mode (Terminal 1) ===
cd ~/dev/worktrees/dark-mode
echo ".dark { background: #111; }" >> dark-mode.css
git add dark-mode.css
git commit -m "feat: add dark mode stylesheet"
# === AGENT 2: Login Fix (Terminal 2) ===
cd ~/dev/worktrees/fix-login
echo "// increase timeout to 30s" >> auth.ts
git add auth.ts
git commit -m "fix: extend login timeout to 30s"
# === AGENT 3: PR Review (Terminal 3) ===
cd ~/dev/worktrees/review-pr-42
# Just reading code, making notes...
echo "LGTM on the refactor, one nit about error handling" > review-notes.md
All three worktrees are operating independently. No stashing, no context switching. Each agent stays in its own directory with its own branch, its own staged changes, its own untracked files.
# In the main worktree โ see all commits from all agents:
cd ~/dev/my-project
git log --all --oneline --graph -10
# The commits from Agent 1 and Agent 2 are visible because
# they share the same object database. No fetch needed.
# But their working trees are isolated:
ls dark-mode.css auth.ts review-notes.md
# None of these files exist here โ they're in the other worktrees.
# Merge Agent 1's work (dark mode):
git merge feat/dark-mode
# Merge Agent 2's work (login fix):
git merge fix/login-timeout
# Agent 3's review notes stay in the review worktree โ
# no merge needed since it wasn't a code change.
# Remove the worktrees (branches persist unless you delete them):
git worktree remove ~/dev/worktrees/dark-mode
git worktree remove ~/dev/worktrees/fix-login
git worktree remove ~/dev/worktrees/review-pr-42
# Optionally delete merged branches:
git branch -d feat/dark-mode
git branch -d fix/login-timeout
git branch -D pr-42 # -D because it's a fetched PR branch
# Verify clean state:
git worktree list
# Should only show the main worktree.
A consistent location for worktrees prevents chaos. Choose a convention and stick to it:
| Strategy | Path pattern | Best for |
|---|---|---|
| Sibling directories | ../my-project-<feature> |
Quick one-offs, small number of worktrees |
| Dedicated dir | ~/dev/worktrees/<feature> |
Daily driver โ keeps repo root clean |
| Per-project dir | ~/dev/worktrees/<project>/<feature> |
Multiple projects, many worktrees each |
~/dev/worktrees/fix-login is
self-documenting; ~/dev/worktrees/wt-3 requires a
git worktree list to decode.
Once you've internalized the pattern, wrap it in a shell function. Add
this to your ~/.zshrc:
# Create a new worktree for agent work
wt-new() {
local branch="$1"
local name="${2:-$(echo "$branch" | tr '/' '-')}"
local base="${WT_BASE:-$HOME/dev/worktrees}"
mkdir -p "$base"
git worktree add "$base/$name" ${3:+-b} "$branch" && cd "$base/$name"
}
# List all worktrees for the current repo
wt-list() {
git worktree list
}
# Remove a worktree by its directory name
wt-rm() {
local base="${WT_BASE:-$HOME/dev/worktrees}"
git worktree remove "$base/$1"
}
# Usage:
# wt-new feat/dark-mode # creates worktree at ~/dev/worktrees/feat-dark-mode
# wt-new fix/login-timeout # creates at ~/dev/worktrees/fix-login-timeout
# wt-list # shows all worktrees
# wt-rm feat-dark-mode # removes worktree
This gives you a single-command workflow:
wt-new feat/dark-mode spins up a worktree, creates the
branch, and cds you into it โ ready to hand off to an agent.
Worktrees give you parallel workspaces, but they come with guardrails that protect you from yourself:
| Constraint | Why it exists |
|---|---|
| One branch cannot be checked out in two worktrees | Prevents conflicting working-tree states. If two worktrees had the same branch, which one's HEAD is authoritative? |
| Worktrees must be on different filesystems from the main worktree | Prevents confusion โ linked worktrees should be clearly separate directories. (You can't create a worktree inside the main worktree.) |
git worktree remove refuses if the worktree is dirty
|
Prevents accidental data loss. Use --force if you're
sure.
|
| A worktree cannot be removed if its branch is checked out nowhere else | Prevents orphaning commits. Git warns you to merge or delete the branch first. |
feat/dark-mode in its worktree, and you
rebase feat/dark-mode from the main worktree, Agent 1's
worktree now has a diverged history. Git won't prevent this โ it's a
coordination problem you need to manage. We'll cover this in
Lesson 0003.
~/dev/worktrees/
is a good default) and stick to it.
wt-new,
wt-list, wt-rm) for single-command
operation.
Primary source: Git Worktrees: A Practical Guide โ The GitHub Blog. The parallel workflow section is directly applicable.
Ask questions: "How do I handle merge conflicts between worktrees?" or "What's the best way to organize worktrees when I have 10+ active branches?" โ your agent-teacher can help you think through your specific setup.