Worktrees let you check out multiple branches at once — perfect for hopping between a feature, a hotfix review, and an agent's branch without stashing or cloning. The native CLI is just a bit clunky for everyday use:
git worktree add ../somewhere-else feature-x
cd ../somewhere-else
# ...later...
cd /path/to/main
git worktree remove ../somewhere-else
git branch -d feature-xgw collapses that to:
gw -b feature-x # create + cd in
gw -d feature-x # remove + delete branchAll worktrees live under <repo>/.worktrees/<branch>, gitignored locally. You spend less time managing paths and more time writing code.
Clone once into ~/.claude/skills/gw/ and you get both the zsh helper and the Claude Code skill in one go:
git clone https://github.com/ohwhen/gw.git ~/.claude/skills/gw
echo 'source ~/.claude/skills/gw/gw.zsh' >> ~/.zshrc
source ~/.zshrcIf you don't use Claude Code, clone anywhere and source gw.zsh from there — only the path changes.
cd ~/.claude/skills/gw && git pullThen source ~/.zshrc (or open a new shell) to load the new version.
| Command | What it does |
|---|---|
gw |
List all worktrees |
gw <branch> |
Check out an existing branch in a worktree, cd into it |
gw -b <branch> |
Create a new branch + worktree, cd into it |
gw -d <branch> |
Remove worktree and delete branch (refuses if dirty or unmerged) |
gw -D <branch> |
Force-remove worktree and force-delete branch |
gw -r |
cd to the main worktree from anywhere in the repo |
gw -h, --help |
Show help |
Slashes in branch names get sanitized into the directory: owen/foo → .worktrees/owen-foo.
- On first use in a repo,
gwadds.worktrees/to.git/info/exclude(local-only — no committed change to the repo) and creates the directory. gw <branch>is idempotent. If the worktree already exists, it justcds in.-dmirrorsgit branch -dsemantics: refuses to delete unmerged branches or dirty worktrees.-Dis the force variant.- All operations run against the main repo via
git -C, so it works correctly from inside any linked worktree too.
Tab completion is included and is context-aware:
gw <Tab>— branches that already have worktrees first, then all other local branchesgw -d <Tab>/gw -D <Tab>— only branches that have a worktree (so you don't accidentally delete a random branch)gw -b <Tab>— all local branches as a reference (so you can avoid name collisions and follow your existing prefix conventions)
Requires compinit to be active (it is by default in oh-my-zsh, prezto, and most modern setups).
A typical day: you're working on a feature, a teammate's PR review comes in, then you go back and finish.
1. Start a new feature.
$ cd ~/code/myproject
$ gw -b owen/login-redesign
added .worktrees/ to /Users/me/code/myproject/.git/info/exclude
Preparing worktree (new branch 'owen/login-redesign')
HEAD is now at a1b2c3d main: bump version
$ pwd
/Users/me/code/myproject/.worktrees/owen-login-redesignYou're already in the new worktree. First time in this repo, gw set up .worktrees/ in your local exclude.
2. Teammate pings you for a PR review. You don't want to lose your in-progress edits — just spin up another worktree.
$ gw -b sara/payments-fix origin/sara/payments-fix
Preparing worktree (new branch 'sara/payments-fix')
HEAD is now at d4e5f6a Add retry on Stripe 5xx
$ # ...read the diff, leave comments, run the tests...
$ gw # see everything you've got going
/Users/me/code/myproject a1b2c3d [main]
/Users/me/code/myproject/.worktrees/owen-login-redesign b9c0d1e [owen/login-redesign]
/Users/me/code/myproject/.worktrees/sara-payments-fix d4e5f6a [sara/payments-fix]3. Hop back to your feature. Tab completion knows which branches have worktrees and ranks them first.
$ gw owen/<Tab>
owen/login-redesign -- worktree
owen/old-experiment -- branch
$ gw owen/login-redesign
$ pwd
/Users/me/code/myproject/.worktrees/owen-login-redesign4. Push, open the PR, get it merged. Time to clean up. You're still inside the worktree — gw -d handles that.
$ git push -u origin owen/login-redesign
$ # ...PR merged on GitHub...
$ git fetch --prune
$ pwd
/Users/me/code/myproject/.worktrees/owen-login-redesign
$ gw -d owen/login-redesign
Deleted branch owen/login-redesign (was b9c0d1e).
$ pwd # gw cd'd you back to root before deleting
/Users/me/code/myproject5. Drop the review worktree the same way.
$ gw -d sara/payments-fix
Deleted branch sara/payments-fix (was d4e5f6a).
$ gw
/Users/me/code/myproject a1b2c3d [main]Back to a clean slate. No cds memorized, no orphaned branches.
- zsh
- git 2.5 or newer
This repo doubles as a Claude Code skill — see SKILL.md. When you clone into ~/.claude/skills/gw/ (the Install step above), Claude Code automatically picks up the skill. It teaches an agent the .worktrees/ isolation pattern — when to use a worktree instead of stashing, the path conventions, and the raw git worktree commands to use in non-interactive contexts.
