All articles

September 24, 2026

You Should Use Git Worktrees

Juggle multiple git branches without getting a headache.

Has this happened to you: You’re developing a new feature with tens, possibly hundreds of working changes in git.

Then your boss messages you,

hey @bryan could you quickly take a look at issue #42069 it should be a quick fix thanks

Well crap, now you’ve got to save all of your changes, make new branch to work on the issue, then switch back and remember where you left off, yadayada…

Screenshot of VS Code source control showing the git status with 14 untracked file changes.

If your workflow looks anything like mine, your context switch probably looks something like this:

git stash -u                    # Stash changes
git checkout main               # Make new branch for bugfix
git checkout -b bryan/fix-bug
...                             # Fix bug bang head against wall etc
git add -A                      # Commit changes and push, make PR
git commit -m "fix: blah blah"
git push
git checkout bryan/cool-feat    # Switch back to where you left off like 20 min ago
git stash pop

The whole acrobatics of stashing your changes and switching between branches is rather annoying and can be error-prone. God forbid you have to juggle 3 or more branches, or have to do the bugfix while in the middle of a complex git rebase (unrelated: if you’ve never used git rebase -i you are missing out).

Wouldn’t it be nice if you could just have separate folders for each of your git branches? Then switching branches would be as simple as switching folders in your text editor.

Luckily, the git team heard your cries back in 2015 when they released the git worktree feature.

The concept is simple: A git repository is a folder with a .git directory (which stores git’s internal files), along with presumably a bunch of source code for whatever language you use. Git calls these files in your filesystem the “working tree”.

my-project/
├─ .git/        # git internals -- do not touch
├─ src/
│  └─ main.rs
├─ .gitignore
├─ Cargo.toml
└─ Cargo.lock

What the git worktrees feature lets you do is to checkout an entirely new working tree, which will be associated with another branch in your git repository. That working tree will share the same .git folder as your original working tree (known as the “main worktree”), they will all share the same git commit history, remotes, stashes, etc.

Theoretically, you can put your worktrees anywhere in your filesystem. Personally, I like to put them in .worktrees/<branch_name> within the project folder (make sure to add .worktrees to the main worktree .gitignore).

The command to create a new git worktree is git worktree add <folder> [branch_name]. For example, running the following commands on the example project above will cause the folders .worktrees/feature-1 and .worktrees/feature-2 to contain worktrees with newly created branches (omit -b to checkout an existing branch instead).

git worktree add .worktrees/feature-1 -b bryan/feature-1
git worktree add .worktrees/feature-2 -b bryan/feature-2
my-project/
├─ .git/            # git internals -- do not touch
├─ .worktrees/
│  ├─ feature-1/
│  │  ├─ .git       # pointer file to main .git/ folder
│  │  ├─ src/
│  │  │  └─ main.rs
│  │  ├─ .gitignore
│  │  ├─ Cargo.toml
│  │  └─ Cargo.lock
│  └─ feature-2/
│     ├─ .git       # pointer file to main .git/ folder
│     ├─ src/
│     │  └─ main.rs
│     ├─ .gitignore
│     ├─ Cargo.toml
│     └─ Cargo.lock
├─ src/
│  └─ main.rs
├─ .gitignore
├─ Cargo.toml
└─ Cargo.lock

Within each worktree, you can edit your files, stage and commit changes, switch branches, etc as normal. Each worktree will have its own staging area, so you can commit files to multiple branches independently.

There is one caveat however—it is not possible for two worktrees to checkout the same branch. I typically will use the main worktree to checkout main and make any small changes, and make a new worktree for any branches with significant feature work.

You can see which worktrees exist for your git repo with git worktree list, and remove them with git worktree remove <worktree>.


Lots of you reading probably are already aware of this feature from this checkbox in Claude Code.

By the way, Claude stores its worktrees in .claude/worktrees/<branch_name>.

A screenshot of Claude Code, showing the worktree checkbox.

I still decided to write this article since:

  1. I’m relatively late to adopting all these AI coding tools and so I still prefer to do these things by hand.
  2. You’ll learn how git worktrees work under the hood and how to use the commands directly.