← All articles
GIT Git Worktrees: Work on Multiple Branches Simultaneously 2026-02-14 · 6 min read · git · worktree · branching

Git Worktrees: Work on Multiple Branches Simultaneously

Git 2026-02-14 · 6 min read git worktree branching workflow productivity code-review version-control

Git Worktrees: Work on Multiple Branches Simultaneously

Git logo

Every developer has been in this situation: you are deep in a feature branch, you have uncommitted changes across several files, and someone asks you to review a pull request or fix an urgent bug on main. Your options are bad. You can stash your work (and hope the stash applies cleanly later), commit half-finished work with a "WIP" message, or just say "give me 20 minutes" while you save and switch context.

Git worktrees eliminate this problem. A worktree is a separate working directory linked to the same repository. You can have your feature branch checked out in one directory and main in another, simultaneously. Each directory has its own working tree and index, but they share the same .git objects, refs, and history. No cloning. No stashing. No context switching.

How Worktrees Work

A standard Git repository has one working directory associated with it. When you run git checkout main, your entire working directory changes to reflect the main branch. Worktrees let you check out additional branches in separate directories, all linked to the same repository.

The key insight is that the .git directory (the object store, refs, hooks, and config) is shared. Each worktree gets its own HEAD, index, and working tree, but they all reference the same underlying data. This means:

Creating Worktrees

Check out an existing branch

# From your main project directory
git worktree add ../project-feature feature-branch

This creates a new directory ../project-feature with feature-branch checked out. The original directory remains on whatever branch it was on.

Create a new branch in a worktree

# Create a new branch and check it out in a worktree
git worktree add -b hotfix/login-bug ../project-hotfix main

This creates a new branch hotfix/login-bug based on main and checks it out in ../project-hotfix.

Check out a detached HEAD

# Useful for reviewing a specific commit or tag
git worktree add --detach ../project-review v2.1.0

Managing Worktrees

List active worktrees

git worktree list

Output:

/home/dev/project          abc1234 [main]
/home/dev/project-feature  def5678 [feature-branch]
/home/dev/project-hotfix   ghi9012 [hotfix/login-bug]

Remove a worktree

# Remove the worktree (the branch remains intact)
git worktree remove ../project-hotfix

# Force removal if there are untracked or modified files
git worktree remove --force ../project-hotfix

Clean up stale references

If you manually delete a worktree directory instead of using git worktree remove, the reference remains. Clean it up with:

git worktree prune

Lock a worktree

Prevent a worktree from being pruned (useful for worktrees on removable media):

git worktree lock ../project-feature --reason "Active development"
git worktree unlock ../project-feature

Practical Workflows

Workflow 1: PR Review Without Context Switching

You are working on a feature. A teammate asks you to review their PR.

# You're in ~/project on feature/new-dashboard

# Create a worktree for the PR branch
git fetch origin
git worktree add ../project-review origin/fix/user-auth

# Open the review worktree in your editor
code ../project-review

# Run tests in the review worktree
cd ../project-review && npm test

# After the review, clean up
git worktree remove ../project-review

Your feature branch work is completely untouched. No stashing, no WIP commits.

Workflow 2: Hotfix While Developing

Production is broken. You need to ship a fix from main, but your feature branch has hours of uncommitted work.

# Create a worktree for the hotfix off main
git worktree add -b hotfix/fix-payment ../project-hotfix main

# Work on the fix
cd ../project-hotfix
# ... make changes ...
git add -A && git commit -m "fix: resolve payment processing timeout"
git push origin hotfix/fix-payment

# Clean up after the hotfix is merged
cd ~/project
git worktree remove ../project-hotfix

Workflow 3: Comparing Implementations

You want to try two different approaches to the same problem:

# Approach A
git worktree add -b experiment/approach-a ../project-a main

# Approach B
git worktree add -b experiment/approach-b ../project-b main

# Work on both, benchmark, compare
# Keep the winner, remove the loser
git worktree remove ../project-a
git worktree remove ../project-b

Workflow 4: Running Tests on a Different Branch

You want to run the test suite against main while continuing to develop:

git worktree add ../project-main main

# In a separate terminal
cd ../project-main && npm test

# Your development continues uninterrupted in ./project

Directory Layout Conventions

A consistent naming convention makes worktrees easier to manage. Here are two common approaches:

Sibling directories

~/code/
  project/              # main worktree (main branch)
  project-feature/      # feature branch worktree
  project-hotfix/       # hotfix worktree

Bare repository with worktree subdirectories

# Clone as bare repo
git clone --bare [email protected]:user/project.git project.git

# Create worktrees inside a containing directory
cd project.git
git worktree add ../project/main main
git worktree add ../project/feature feature-branch

This layout:

~/code/
  project.git/          # bare repo (no working tree)
  project/
    main/               # main branch worktree
    feature/            # feature branch worktree

The bare repository approach is cleaner when you use worktrees as your primary workflow rather than an occasional tool.

Editor Integration

VS Code

VS Code works well with worktrees. Open each worktree as a separate window:

# Open worktrees in separate VS Code windows
code ~/project
code ~/project-feature

Each window has its own Git state, terminal, and file tree. VS Code detects the branch automatically.

For a smoother workflow, use the Git Worktrees extension, which adds commands to create, switch, and remove worktrees from within VS Code.

Neovim

If you use telescope.nvim, the telescope-git-worktree plugin provides fuzzy finding across worktrees:

-- Install via lazy.nvim or your plugin manager
{ "ThePrimeagen/git-worktree.nvim" }

-- Keybindings
vim.keymap.set("n", "<leader>gw", function()
  require("telescope").extensions.git_worktree.git_worktrees()
end)
vim.keymap.set("n", "<leader>gW", function()
  require("telescope").extensions.git_worktree.create_git_worktree()
end)

JetBrains IDEs

IntelliJ, WebStorm, and other JetBrains IDEs support worktrees natively. Go to Git > Manage Worktrees to create and switch between them. Each worktree opens as a separate project with its own run configurations.

Shell Aliases

Add these aliases to your shell configuration to streamline worktree management:

# ~/.bashrc or ~/.zshrc
alias gwl="git worktree list"
alias gwa="git worktree add"
alias gwr="git worktree remove"
alias gwp="git worktree prune"

# Quick worktree for PR review
gw-review() {
  local branch="$1"
  local dir="../$(basename $(pwd))-review"
  git fetch origin
  git worktree add "$dir" "origin/$branch"
  echo "Worktree created at $dir"
}

# Quick cleanup of all non-main worktrees
gw-clean() {
  git worktree list --porcelain | grep "^worktree" | tail -n +2 | \
    awk '{print $2}' | while read wt; do
      echo "Removing $wt"
      git worktree remove "$wt"
    done
}

Gotchas and Limitations

Cannot check out the same branch twice: Git prevents this to avoid conflicting changes. If you need the same branch content in two places, use --detach for the second worktree.

Submodules require extra steps: If your repository uses submodules, you need to run git submodule update --init in each new worktree.

Node modules and build artifacts: Each worktree has its own node_modules directory. You need to run npm install (or your package manager of choice) in each worktree independently. The same applies to build artifacts, virtual environments, and other generated files.

Hooks are shared: Git hooks live in .git/hooks, which is shared across all worktrees. A pre-commit hook runs the same way in every worktree.

Branch deletion: You cannot delete a branch that is checked out in any worktree. Remove the worktree first, then delete the branch.

When to Use Worktrees

Worktrees are most valuable when you frequently switch contexts. If you only work on one branch at a time and rarely need to interrupt your work, stashing or WIP commits are fine. But if any of these apply to you, worktrees will save time:

The cost is minimal -- a few extra megabytes of disk space and one extra command to set up. The benefit is never losing your working context again.