Willow CLI — Worktree Management for AI Agents
Willow gives every task its own isolated directory via git worktrees. Instead of stashing and switching branches, each branch gets a full working copy. This is especially powerful for AI agents that run in parallel — each agent gets its own worktree with no conflicts.
When to use willow vs raw git
Use willow (ww) commands instead of git checkout, git branch, or git worktree directly. Willow handles worktree creation, tmux session management, agent status tracking, and stacked PR relationships automatically. Raw git commands bypass all of this.
Quick decision guide
| Situation | Command |
|---|---|
| Set up a new repo for willow (one-time) | ww clone <url> |
| Work on a branch (don't know if worktree exists) | ww checkout <branch> |
| Create a new feature branch | ww new <branch> |
| Check out someone's PR | ww checkout --pr <number> |
| Hand a task to a fresh Claude agent | ww dispatch "<prompt>" |
| Stack a branch on another | ww new <child> -b <parent> |
| Rebase a stack after upstream changes | ww sync |
| Turn the current branch or stack into PRs | ww pr create [--stack] |
| Check CI/review for the whole stack | ww stack status |
| Switch to an existing worktree | ww sw <name> |
| See all worktrees and their status | ww ls |
| Remove a worktree you're done with | ww rm <branch> |
| Clean up merged branches | ww gc --prune |
Core commands
ww clone <url> [name]
Required first step for any repo. Willow only manages repos that live under ~/.willow/repos/, so a plain git clone elsewhere won't work with the rest of these commands. If ww ls doesn't list the repo, run ww clone first.
ww clone git@github.com:org/repo.git # default name from URL
ww clone git@github.com:org/repo.git myrepo # custom name
ww checkout <branch> (alias: co)
The go-to command. Figures out the right action automatically:
- Worktree already exists for that branch? Switches to it.
- Branch exists on remote but no worktree? Creates a worktree for it.
- Branch doesn't exist anywhere? Creates a new branch + worktree.
ww checkout feature-auth # switch or create
ww checkout --pr 123 # check out PR by number
ww checkout --pr https://github.com/org/repo/pull/123 # by URL
wwc feature-auth # checkout + cd into it (shell alias)
Flags: -r/--repo, -b/--base, --pr, --no-fetch, --cd
ww new <branch> (alias: n)
Creates a new worktree explicitly. Use this when you specifically want a new branch (not switching to an existing one).
ww new feature-auth # new branch from default base
ww new feature-auth -b develop # fork from specific branch
ww new -e existing-branch # worktree for existing remote branch
ww new -e # pick from remote branches (fzf)
ww new --pr 123 # worktree for a PR
ww new child-feature -b parent-feature # stacked PR (records dependency)
wwn feature-auth # new + cd into it (shell alias)
When -b points to a local branch (another worktree's branch), willow forks from it directly and records the parent relationship for ww sync.
ww sync [branch]
Rebases stacked worktrees onto their parents in topological order — parents are rebased before children, so the whole chain stays consistent.
ww sync # sync all stacks in current repo
ww sync feature-b # sync only feature-b and its descendants
ww sync --abort # abort any in-progress rebases
The algorithm: fetches origin once, then for each branch in dependency order, rebases it onto its parent. If a conflict occurs, it stops descendants of that branch but continues other independent stacks.
ww stack status (alias: ww stack s)
Shows CI, review, and merge status for every PR in a stack in one gh pr list call. Use this before running ww sync to spot which layers still need attention, or to answer "is the whole stack green?" without opening GitHub.
ww stack status
ww stack status --json
Requires the GitHub CLI (gh).
ww pr create
Create a GitHub PR for the current branch. The base branch is inferred automatically:
- stacked branch: uses its recorded parent
- unstacked branch: uses the repo's default base branch
ww pr create # current branch only
ww pr create --draft # open as draft
ww pr create --stack # create missing PRs from root → current branch
Use this when the user says "open a PR", "publish this branch", or "create PRs for this stack". It must be run from inside a willow-managed worktree with no uncommitted changes.
ww dispatch <prompt>
Create a worktree and launch Claude Code with a prompt in one step. The branch name is auto-slugified from the prompt. Use this when the user says "spin up an agent to do X" or when you'd otherwise create a worktree and immediately start Claude yourself.
ww dispatch "Fix the login validation bug"
ww dispatch "Add retry logic" --name add-retries
ww dispatch "Write tests for auth" -b feature/auth # stacked on a branch
From a terminal, Claude runs in the foreground. From the tmux picker (Ctrl-G), it launches in a background session so the user can keep working.
ww sw [name]
Switch between existing worktrees via fzf picker. Shows Claude Code agent status per worktree (BUSY/DONE/WAIT/IDLE). If a name is given, switches directly without the picker.
ww rm [branch]
Remove a worktree and its branch. Opens multi-select fzf picker if no branch specified.
ww rm feature-auth # remove specific worktree
ww rm # pick from fzf
ww rm feature-auth --force # skip safety checks
ww rm feature-auth --keep-branch # keep the git branch
If the branch has stacked children, warns and requires --force. Children are re-parented to the removed branch's parent.
ww ls [repo]
List worktrees with status. Shows tree structure for stacked branches and [merged] indicators for branches that have been merged into the base.
ww status
Rich view of Claude Code agent activity. Shows per-session status when multiple agents run in the same worktree.
ww gc [--prune] [--dry-run]
Garbage collection. Without flags, just empties ~/.willow/trash/. With --prune, interactively removes worktrees whose branches have been merged into the base. Pair with --dry-run to preview before committing — useful when the user wants to see what would go before running the real thing.
ww gc # empty trash only
ww gc --prune # interactively remove merged worktrees
ww gc --prune --dry-run # preview the prune without removing anything
Stacked PR workflow
Stacked PRs let you build features incrementally — each PR builds on the previous one. Willow tracks the dependency chain and can rebase the entire stack in one command.
# Create the stack
ww new feature-a -b main # first layer (based on main)
ww new feature-b -b feature-a # second layer (based on feature-a)
ww new feature-c -b feature-b # third layer
# After main is updated or feature-a changes:
ww sync # rebases a→b→c in correct order
# Or sync just part of the stack:
ww sync feature-b # only feature-b and its descendants
# See the stack visually:
ww ls
# BRANCH STATUS PATH AGE
# ├─ feature-a BUSY ~/.willow/.../feature-a 2h
# │ └─ feature-b DONE ~/.willow/.../feature-b 1h
# │ └─ feature-c -- ~/.willow/.../feature-c 30m
# standalone -- ~/.willow/.../standalone 1d
Important rules
Use
ww checkoutinstead ofgit checkout— it manages worktrees, tmux sessions, and status tracking automatically.Navigate with
wwcorww sw, not rawcd— these ensure tmux sessions are created and status is tracked. Manually cd-ing to a worktree path bypasses session management.Always use
-bfor stacked branches —ww new child -b parentrecords the parent relationship. Without-b, the branch won't be part of the stack andww syncwon't know about it.Run
ww syncafter upstream changes — when main moves forward or a parent PR is updated,ww syncrebases the entire chain in the right order.Check
ww lsfor[merged]tags — these indicate branches that have been merged and can be cleaned up withww rmorww gc --prune.
Directory layout
~/.willow/
├── repos/<name>.git/ # bare git clones
│ ├── willow.json # per-repo config
│ └── branches.json # stack parent relationships
├── worktrees/<name>/<branch>/ # checked-out worktrees
├── status/<name>/<branch>/ # agent status files
└── trash/ # soft-deleted worktrees
Shell aliases
These are available after running eval "$(willow shell-init)":
| Alias | Expands to |
|---|---|
ww <cmd> |
willow <cmd> (with tmux-aware sw/checkout/rm) |
wwn <branch> |
ww new <branch> --cd then cd into result |
wwc <branch> |
ww checkout <branch> --cd then cd into result |
www |
cd ~/.willow/worktrees/ |
Source: iamrajjoshi/willow — distributed by TomeVault.