Version Control

Parallel Development with git worktree: Multiple Branches at Once

For devs juggling several branches who fear stash chaos while switching, here is how to keep one clean worktree per task and never stash-swap again.

By LaoHand Team·6 min read·Updated 2026-09-06

Why Stash-and-Checkout Churn Drives You Mad

With a single working dir, you stash to switch branches and stash-pop to come back; after a few rounds it blurs — pop conflicts, the "which branch does this belong to" mystery, and a forgotten stash losing half a day.

git worktree lets one repository host several physically separate working directories at once, each bound to its own branch. Edit feature-A in dir A and bugfix-B in dir B, no interference, no stash.

The precondition: branches must not share local files that collide at runtime (node_modules, .env). Install dependencies once and share or externalize them, so you are not reinstalling in every worktree.

# 在仓库根目录下新建一个绑定分支的额外工作树
git worktree add ../feature-a -b feature-a

# 再建一个跟踪已有分支的 worktree
git worktree add ../hotfix -b hotfix origin/main

git worktree list
# /repo                12ab main
# /repo/../feature-a  34cd feature-a
# /repo/../hotfix     56ef hotfix

Create a Worktree per Task: One Clean Dir, One Clear History

The core habit: one in-flight task (feature, bug, experiment) maps to one worktree and one dedicated branch. Name the dir after the ticket, e.g. ../feat/pricing-table, ../fix/timezone.

This model frees you from remembering which branch you are on — wherever you stand tells you. It also lets you spin up several branches off the same base for comparison: open A and B from origin/main in own dirs, commit and test each, never overlapping.

Committing, testing, and linting happen independently in each worktree, so parallelizing with CI is natural: each dir runs its own server and tests, no port or file-lock fights.

base="origin/main"

git worktree add ../feat/pricing-table -b feat/pricing-table "$base"
git worktree add ../fix/timezone    -b fix/timezone    "$base"

# 各自独立开发
# (cd ../feat/pricing-table && pnpm install && pnpm dev)
# (cd ../fix/timezone && pnpm install && pnpm test)

git worktree list

Mistake: Forgetting a Branch Can Only Have One Worktree

A branch usually has exactly one worktree. Trying to check out main in a second directory fails with "already checked out at". That is a guard, not a bug; the message tells you which directory holds it.

If you really need it, check out detached in the second one with git checkout --detach, but not for normal work.

To clean up, git worktree remove <path> (older Git may need git worktree prune to clear stale registrations) removes it from both Git and disk at once.

# 错误示范:同一分支开两个目录
git worktree add ../dup main
# fatal: 'main' is already checked out at '<other-dir>'

# 正确清理
git worktree remove ../dup

# 或只移除注册信息(目录你手动删过)
git worktree prune

git worktree list

Verify the Worktrees Are Clean and Point Around Correctly

Before removing, confirm the worktree holds no uncommitted changes. git worktree list --porcelain gives scriptable path and branch for reading.

When running in parallel, never guess the branch: explicitly cd into the target directory so scripts act on the right worktree.

Wrap-up habit: delete the worktree after its branch is merged and pushed, keep list lean, and do not let merged branches hoard disk in stray directories.

# 脚本化查看所有 worktree(--porcelain 输出易解析)
git worktree list --porcelain
# worktree /repo
# branch refs/heads/main
# worktree /repo/../feat/a
# branch refs/heads/feat/a

# 回收完的分支对应目录
git worktree remove ../feat/a

git worktree prune

git worktree list

Official References

Each command links to its official documentation below, so you can verify the latest usage and read deeper.