If you've ever stashed half-finished work to review a PR, or lost a train of thought switching branches, you should know about git worktrees. They've been in git since 2015, but most developers I talk to have never heard of them.
The problem with branches
The standard git workflow is linear. You're on a branch, you need to context-switch, so you stash your changes (or worse, make a throwaway commit), switch branches, do your thing, switch back, and pop the stash. If you're lucky, nothing conflicts.
This gets worse when you're juggling multiple things at once. Reviewing a colleague's PR while your feature branch is mid-refactor. Running tests on one branch while coding on another. Hotfixing production while your main work sits frozen.
A git repository has one working directory. One branch checked out at a time. Everything else has to wait.
Worktrees
Git worktrees let you check out multiple branches simultaneously, each in its own directory. They share the same .git history and objects, so you're not cloning the entire repo, but each one has its own working directory and index.
git worktree add ../feat-login feat/login
Now feat/login is checked out in ../feat-login. You can open it in a separate editor window, run tests there, or just let it sit while you work on something else.
When you're done:
git worktree remove ../feat-login
Why nobody uses them
If worktrees are so useful, why aren't they more popular? I think it comes down to two things.
First, the directory problem. Every time you create a worktree, you have to pick a path. There's no convention for where they go. After a week you end up with directories scattered across your filesystem: ../feat-login, ~/tmp/hotfix-auth, ../../pr-review. Good luck remembering where anything is.
Second, there are no ergonomics. You can't easily list your worktrees with status info, cd into one quickly, or run something like npm install in the new directory after checkout. The raw git commands work, but they don't make worktrees feel like a real workflow.
These aren't fundamental problems with worktrees. They're tooling gaps. That's why I built arbor.
A better workflow with arbor
Arbor is a CLI that manages git worktrees. It keeps them organized in a central directory (~/.arbor/worktrees/) and handles the stuff that plain git doesn't.
# Clone a repo (sets up a bare repo + default branch worktree)
arbor clone user/my-app
# Create a worktree for a new feature
arbor add feat/login
# Shell integration auto-cds you into the worktree
# You're now in ~/.arbor/worktrees/my-app/feat-login
# Need to review a PR? Open another worktree
arbor add fix/auth-bug
# See all your worktrees with dirty/clean status
arbor status
Every worktree for my-app lives under ~/.arbor/worktrees/my-app/. Branch slashes become dashes in directory names, so the filesystem stays tidy. When you're done with a branch:
arbor rm -d feat/login
That removes the worktree and the local branch in one step.
What makes it stick
I've been using worktrees for a while, but I kept falling off because of the friction. A few things in arbor made the difference for me.
Shell integration. arbor init sets up a wrapper so that arbor add and arbor switch automatically cd you into the worktree directory. Without it you create the worktree and then have to cd into it yourself every single time, which gets old fast.
Post-create hooks. You can add an .arbor.toml to your repo:
[hooks]
post_create = "npm install"
Every new worktree gets its dependencies installed automatically. You can chain commands too:
[hooks]
post_create = ["npm install", "cp .env.example .env"]
And arbor status --all shows the state of every worktree across all your repos, which is nice for a quick scan before you call it a day.
Where I use them most
PR reviews. arbor add the branch, review it in a separate editor window, remove it when done. My own work is untouched.
Long test suites. Tests running on one branch, coding on another. No waiting around.
Hotfixes. arbor add hotfix/critical, fix it, push it, remove it. Back to what I was doing.
Comparing behavior. Two worktrees open side by side, one on main and one on my feature branch. Way easier than switching back and forth.
Big migrations. Upgrading a framework to a new major version in a worktree while the rest of the team keeps shipping from main. No half-broken build blocking anyone.
Try it
Arbor is open source, written in Rust. Install with Homebrew:
brew install morellodev/tap/arbor
Or grab a binary from the releases page.
Run arbor init after installing to set up shell integration. Takes about 30 seconds.
If you've never tried worktrees, give them a shot. And if you have but gave up because of the directory mess, this might be worth another look.
morellodev
/
arbor
A friendly CLI for managing git worktrees
π³ arbor
A CLI for managing git worktrees. It keeps all your worktrees under ~/.arbor/worktrees so you can switch between branches without stashing or losing context.
Why arbor?
Git worktrees are great: multiple branches checked out at once, no stashing, no half-finished commits. The problem is that git worktree add makes you pick a directory every time, and you end up with worktrees scattered everywhere.
Arbor puts them all in one place. arbor add feat/login creates the worktree, and with shell integration it cds you into it too. arbor rm feat/login cleans it up.
Who is this for?
If you review PRs while working on your own feature, juggle hotfixes alongside long-running branches, or run tests in one worktree while coding in another β arbor keeps everything organized.
Install
Homebrew (macOS and Linux)
brew install morellodev/tap/arbor
Pre-built binaries (macOS, Linux, Windows)
Download the latest binary for your platform fromβ¦

Top comments (0)