Why does Git refuse to check out the same branch in two worktrees, and what do you do instead?
answer
- One ref, two checkouts
- HEAD is per-worktree, branches are not
- Whoever commits moves the pointer under the other
- -b for a new branch
- --detach when you only need the commit
basics
~20 sAll worktrees share one set of refs, so a branch is a single pointer. Two checkouts advancing it independently would silently clobber each other, so Git allows a branch in only one worktree. Use a new branch or a detached checkout instead.
solid answer
~50 sBranches live in the shared `refs/heads` namespace, so `main` is one ref no matter how many worktrees exist. If two worktrees had it checked out, a commit in one would move the ref under the other, leaving that checkout's index and files describing a commit that is no longer the branch tip. Git prevents this: `git worktree add ../x main` fails with `'main' is already checked out at <path>`, and `git switch main` in a second worktree fails the same way. It also refuses to delete a branch that some worktree has checked out. The fix is to say what you actually want — `git worktree add -b fix ../x main` for a new branch from that point, or `git worktree add --detach ../x main` when you only need to build or inspect the code. `--force` overrides the check and is almost never the right answer.
code
console · 8 lines$ git worktree add ../build main
fatal: 'main' is already checked out at '/home/dev/project'
$ git worktree add --detach ../build main
Preparing worktree (detached HEAD 4a1c9e2)
$ git worktree add -b hotfix ../hotfix main
Preparing worktree (new branch 'hotfix')go deeper
Recall the rule and the two clean workarounds: create a new branch with -b, or check the commit out detached with --detach.
Explain the mechanism — one shared refs/heads entry versus per-worktree HEAD and index — and describe the corruption-shaped confusion two checkouts of one branch would produce.
Show the diagnostic path: read the path named in the error, confirm with git worktree list, recognise that a deleted-by-hand worktree can hold a branch until it is pruned, and explain why --force is the wrong reflex.
Own the conventions that keep branch ownership unambiguous across a team's automation — scripts and build agents that create worktrees should use detached checkouts or generated branch names rather than competing for shared branches.
## The rule A branch may be checked out in at most one worktree at a time. Attempting otherwise gives an error naming the offending directory: `fatal: 'main' is already checked out at '/home/dev/project'` The same applies from the other direction: `git switch` or `git checkout` of a branch that another worktree holds fails, and `git branch -d`/`-D` refuses to delete a branch that is checked out somewhere. ## Why it exists Worktrees share the repository's refs. `refs/heads/main` is one file (or one packed-refs entry) for the whole repository — there is no per-worktree copy. What *is* per-worktree is `HEAD`, the index, and the working files. Now suppose both worktrees had `main` checked out. You commit in worktree A. `refs/heads/main` advances. Worktree B's `HEAD` still says "on branch main", but B's index and files describe the *old* tip. From B's point of view every file in the new commit now looks modified in reverse; a `git status` there is misleading and a `git commit` would build on A's commit while treating B's stale content as the change. Nothing warns you, and the damage looks like a mysterious mass revert. Git therefore enforces exclusivity at the moment of checkout rather than letting you find out later. ## What to do instead Ask what you actually need: - **A place to work from that point** — `git worktree add -b hotfix ../hotfix main`. You get a new branch `hotfix` starting at `main`, checked out in the new directory. `main` stays where it is. - **Just to build, test, bisect or read the code** — `git worktree add --detach ../build main`. HEAD is detached at that commit, no branch is occupied, and nothing prevents another worktree from holding `main`. This is the right choice for build-and-test tasks and for inspecting a tag: `git worktree add --detach ../v2 v2.1.0`. - **To follow a remote branch without owning the local one** — check out the remote-tracking commit detached, or create a distinctly named local branch from it. A convenient shorthand: `git worktree add ../thing` with no commit-ish creates a new branch named after the directory's last path component, based on HEAD — so you rarely have to think about naming at all. ## The escape hatch, and why to avoid it `git worktree add --force` (and `git switch --ignore-other-worktrees`) will override the check. They exist for edge cases, and they hand you exactly the failure mode described above: two checkouts racing one ref. If you find yourself reaching for them, the honest question is why two directories need to *be* the same branch rather than share the same commit — and the answer is almost always `--detach`. ## Related consequences of the shared namespace - **You cannot delete a checked-out branch.** Remove or switch the worktree holding it first, then delete. - **`git worktree list` is the diagnostic.** It prints each worktree's path, current commit, and branch (or `detached`), which immediately shows who is holding the branch you want. The error message also names the path directly. - **Rebase and merge across worktrees work fine.** Because refs and objects are shared, worktree B can rebase onto `main` while worktree A has `main` checked out — reading a branch is unrestricted; only *occupying* it is exclusive. - **A stale worktree can hold a branch hostage.** If a worktree's directory was deleted by hand, Git may still believe the branch is checked out there; `git worktree prune` clears that bookkeeping. ## The short answer "Because branches are shared refs and only HEAD and the index are per-worktree, two checkouts of one branch would fight over the same pointer. Create a new branch with `-b`, or use `--detach` if you only need the commit."
- Can a worktree rebase onto a branch that another worktree has checked out?Yes. The restriction is only on checking a branch out — occupying it as this worktree's HEAD. Reading it is unrestricted, so you can rebase onto `main`, merge it, diff against it or log it from any worktree while another directory has it checked out. Only the branch pointer's owner is exclusive.
- Why does git branch -d fail for a branch checked out in another worktree?For the same reason: deleting the ref would leave that worktree's HEAD pointing at a branch that no longer exists, with an index and files describing it. Git refuses and names the worktree holding it. Remove that worktree, or switch it to something else, and the deletion then succeeds.
- When is git worktree add --force actually reasonable?Rarely. It exists for situations where you knowingly accept two checkouts of one branch, typically short-lived and read-only in one of them. If the goal is only to build or inspect the code at that point, `--detach` gives you the same content with none of the hazard, so treat reaching for `--force` as a sign the requirement was misstated.
saying these in an interview costs you the question
- Thinks each worktree gets its own copy of the branch pointer
- Recommends --force as the normal way around the error
- Believes you cannot even rebase onto a branch another worktree holds
- Assumes the error means the repository is corrupted
- Says deleting the worktree directory by hand releases the branch