Git

git worktree as a daily driver

The git feature that finally cured me of having five clones of the same repo in different directories.

· 3 min read

I spent years with a folder structure like this:

~/code/
  myproject/
  myproject-hotfix/
  myproject-review/
  myproject-experiment/

Four clones of the same repo. Four copies of node_modules. Four separate sets of editor windows. All because I needed to work on the main branch, review a PR, and fix a production bug at the same time, and git stash is not a real answer for anything that takes more than five minutes.

I eventually learned git worktree and it fixed all of this. I use it every day now. If you haven’t tried it, here’s the pitch.

What it is

A worktree is a second (or third, or tenth) working directory attached to the same repository. One .git directory, one set of refs, one history — but multiple checked-out branches sitting in different folders, each with its own files. You can edit them independently, run them independently, even have different commits going in each one. Fetches and pushes are shared because it’s all one repo.

The commands

# Add a new worktree for an existing branch
git worktree add ../myproject-hotfix hotfix/urgent-bug

# Add a new worktree on a brand new branch
git worktree add -b feature/redesign ../myproject-redesign

# List all worktrees
git worktree list

# Remove a worktree when you're done
git worktree remove ../myproject-hotfix

That’s basically the whole interface. There’s a little more for edge cases (locked worktrees, pruning stale entries) but I almost never need it.

The workflow that actually works for me

I keep a tree like this:

~/code/myproject/           # the main clone, sits on main
~/code/myproject.wt/        # a directory of worktrees
  feature-a/
  feature-b/
  review-pr-1234/

Every new branch is a worktree. I never switch branches in the main clone anymore. When a branch gets merged or abandoned, I delete its worktree. feature-a/ and feature-b/ each have their own node_modules, their own build artifacts, their own dev server on a different port, and they don’t fight each other.

The concrete wins:

  • No more stashing to switch tasks. Production alert at 3 PM? Open the hotfix worktree, fix it, push, go back to the feature worktree. No context save, no context restore.
  • PR reviews are actual checkouts. I can review a PR in its own worktree, run it, poke at it, without disturbing whatever I was doing.
  • Long-running experiments don’t block the main flow. That branch where I’m trying a new state-management library lives in its own worktree for a month, and I don’t have to context-switch into it when I don’t want to.
  • node_modules stops being a hostage. Four feature branches can each have their own, and installing the right one for the branch I just switched to isn’t a thing anymore.

The gotchas

  • You can’t check out the same branch in two worktrees at once. Git enforces this. If you need to, make a second branch pointed at the same commit.
  • Build artifacts are per-worktree. That’s usually what you want, but it means disk usage grows.
  • Editor integration varies. Most editors handle a directory that happens to be a worktree fine; some extensions (especially git UIs) occasionally get confused.
  • git worktree prune is what you run if you deleted a worktree directory with rm -rf instead of git worktree remove, and now git thinks it still exists.

If you’ve been cloning the same repo multiple times, or if you’ve been living in git stash, try worktrees for a week. I don’t miss the old way at all.

#Git #Worktree