---
title: Git Worktrees: Multiple Branches Without the Stash Shuffle
description: A guide to git worktree: check out several branches into separate folders at once, skip the stash-switch-unstash cycle, and dodge the cloud-sync pitfall.
date: 2026-07-27T00:00:00.000Z
category: dev-tools
tags: git, workflow, cli
---

Every developer knows the interruption: you're mid-feature, half your files are edited, and a teammate needs an urgent fix on `main`. The usual move is `git stash`, switch branches, fix the bug, switch back, `git stash pop`, and hope nothing conflicts. It works, but it's friction you pay every single time context-switching happens, and on a bad day it happens five times before lunch.

`git worktree` removes the friction entirely. Instead of one working directory that can only ever point at one branch, a worktree lets you check out several branches into separate folders at the same time, all sharing the same underlying repository.

## Quick Answer

`git worktree add ../myproject-hotfix main` checks out another branch into its own folder while your current one stays exactly as you left it, sharing one `.git` history across both. Reach for it when an interruption is long enough that losing your place would cost real time; a plain `git stash` is still less typing for a thirty-second fix.

## What a worktree actually is

A normal clone has one working directory and one `.git` folder. [`git worktree add`](https://git-scm.com/docs/git-worktree) creates an additional working directory linked to that same `.git`: same commit history, same remotes, same config, but checked out to a different branch. Nothing is duplicated except the files themselves.

```bash
# from inside your existing repo
git worktree add ../myproject-hotfix main
```

That command creates a sibling folder, `../myproject-hotfix`, already checked out to `main`, ready to work in immediately: no stash, no losing your place in the feature branch sitting untouched in the original folder.

## The core commands

```bash title="worktree basics"
# add a new worktree for an existing branch
git worktree add ../myproject-hotfix main

# add a new worktree AND create a new branch at the same time
git worktree add -b feature/new-nav ../myproject-nav

# see every worktree attached to this repo
git worktree list

# remove one once you're done with it
git worktree remove ../myproject-hotfix

# clean up references to worktrees whose folders were deleted manually
git worktree prune
```

<Callout type="tip" title="Skip the manual folder delete">
  Always remove a worktree with `git worktree remove`, not by deleting the
  folder yourself. If you do delete it manually, Git still thinks it exists
  until you run `git worktree prune`, and until then, commands like `git branch
  -d` on that branch will refuse, claiming it's checked out somewhere.
</Callout>

## What's shared, and what isn't

{/* prettier-ignore */}
<CodeTabs labels={["Without worktrees", "With worktrees"]}>
  <Fragment slot="tab-0">
    ```bash
    git stash
    git checkout main
    # fix the bug
    git checkout feature/new-nav
    git stash pop
    # hope nothing conflicted
    ```
  </Fragment>
  <Fragment slot="tab-1">
    ```bash
    cd ../myproject-hotfix
    # fix the bug, already on main, feature branch untouched
    cd ../myproject-nav
    # still exactly where you left off
    ```
  </Fragment>
</CodeTabs>

Commit history, branches, tags, and remotes are shared instantly across every worktree: a commit made in one is visible to `git log` in all the others right away. What's **not** shared is anything outside Git's own tracking: `node_modules`, build output, `.env` files. Each worktree needs its own `npm install` and its own build. That's the most common surprise for people trying worktrees for the first time, the code appears instantly, but the project isn't actually runnable until dependencies are installed in that specific folder.

<Callout type="warning" title="Cloud-synced folders and stale locks">
  If your repository lives inside a cloud-synced folder (OneDrive, Dropbox,
  iCloud Drive), be aware that every worktree still writes to the one shared
  `.git` directory. A sync client racing a git command mid-write can leave a
  stale `index.lock` or `HEAD.lock` file behind. If a worktree command fails
  with a `File exists` error on a `.lock` file, confirm nothing else is actually
  mid-operation before removing it by hand, and consider keeping active repos
  outside the synced folder, or excluding `.git` from sync, if this happens
  often.
</Callout>

## When it's not worth it

Worktrees shine for genuinely parallel work: a long-running feature branch plus an urgent hotfix, or reviewing a colleague's PR without disturbing your own uncommitted changes. For a thirty-second fix you were going to make anyway, a plain `git stash` is still less typing. Reach for worktrees when the interruption is long enough that losing your place would actually cost you something.

Browse more posts like this in the [Dev Tools](/dev-tools) archive.
