Git worktrees

Work on multiple branches without switching

January 13, 2026

If you’ve ever worked on multiple branches in a single Git repo, you know the pain of switching back and forth. You have to stash unfinished changes or commit early, just to check out another branch. On top of that, when branches use different dependencies, like Python venvs or node_modules, you often end up reinstalling or adjusting things every time you switch.

That friction shouldn’t be part of your daily workflow. Thankfully, Git has a feature that solves exactly this problem: worktrees.

What are Git worktrees

A Git worktree is an additional working directory attached to the same repository. Unlike cloning the repo multiple times, worktrees share the same Git database, history, and configuration. Each worktree can have its own branch checked out and its own working directory state. This means:

  • - You can work on multiple branches simultaneously
  • - Your dependency folders stay isolated
  • - You don’t waste disk space duplicating Git history.

Think of a worktree as multiple checkouts of the same repository sharing a single .git directory.

Important limitation

A branch can only be checked out in one worktree at a time. Git will prevent you from accidentally using the same branch twice.

Why not just git clone?

Cloning the same repository multiple times works, but it introduces unnecessary overhead:

  • - Git history is duplicated for every clone
  • - Fetching and staging happens per clone
  • - Configuration, hooks, and cleanup must be managed repeatedly

Worktrees avoid these issues, offering a lighter, more manageable workflow.

Getting started

Creating a worktree is straightforward. You can either create a new branch or use an existing one:

# Create a new branch and worktree
git worktree add -b feat/123-new-button ../feat-123-new-button

# Use an existing branch in a new worktree
git worktree add ../feat-123-new-button feat/123-new-button

Here is what my workspace usually looks like:

 ../
├─ ui-monorepo # original project, always on the development branch
├─ feat-ad-1234-node-deps-in-playground # worktree for a specific feature
├─ fix-ad-1235-stale-state # worktree for a specific bug fix
├─ fix-ad-1236-another-bug-state # worktree for another bug fix

The original repo stays on development, while each feature or fix gets its own worktree directory. This makes it easy to open a specific branch in your editor and continue where you left off, without context switching or dependency headaches.

Some other useful worktree commands:

git worktree list  # list all active worktrees
git worktree delete <directory>  # delete a worktree
git worktree move <worktree> <new-path>  # move a worktree to a new location
git worktree prune  # remove stale worktree references when directories were deleted manually

Now, when a pull request needs rebasing or a quick fix, I can simply open the corresponding directory and make the changes immediately.

Tip

To make it even faster, you can use the project specific aliases from my previous post to create a initialization command:

alias init-env="uv sync --all-groups \
  && cp --update=none .env.dist .env \
  && (cd frontend && npm install)"
Share

Comments (0)