{"record":{"id":"4957c687d5a64f1c","repo":"gastownhall/beads","slug":"target-common-git-directory-q-does-not-match-repo","errorCode":null,"errorMessage":"target common git directory %q does not match repository %q","messagePattern":"target common git directory %q does not match repository %q","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/worktree_cmd.go","lineNumber":1304,"sourceCode":"\tstatus := worktreeremove.Clean\n\tif target.status != \"\" {\n\t\tstatus = worktreeremove.Dirty\n\t}\n\tplan.prepareFacts = worktreeremove.PrepareFacts{\n\t\tRegistration:   worktreeremove.Present,\n\t\tTarget:         worktreeremove.RegisteredTarget,\n\t\tRegisteredPath: target.path,\n\t\tTargetDir:      worktreeremove.Present,\n\t\tGitAdminDir:    worktreeremove.Present,\n\t\tGitMarker:      worktreeremove.Present,\n\t\tCommonDir:      worktreeremove.Matched,\n\t\tHead:           worktreeremove.Present,\n\t\tStatus:         status,\n\t\tManagedIgnore:  worktreeremove.IgnoreAbsent,\n\t}\n\tif !sameWorktreePath(target.commonDir, mainCommonDir) {\n\t\tplan.prepareFacts.CommonDir = worktreeremove.Unmatched\n\t\tplan.prepareErr = fmt.Errorf(\n\t\t\t\"target common git directory %q does not match repository %q\",\n\t\t\ttarget.commonDir,\n\t\t\tmainCommonDir,\n\t\t)\n\t\treturn plan, nil\n\t}\n\tif relative, inside := relativeWorktreePath(plan.mainWorktree, target.path); inside {\n\t\tplan.gitignoreCleanup, err = prepareGitignoreCleanup(plan.mainWorktree, relative)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"cannot safely prepare .gitignore cleanup: %w\", err)\n\t\t}\n\t\tif plan.gitignoreCleanup != nil {\n\t\t\tplan.prepareFacts.ManagedIgnore = worktreeremove.IgnoreManaged\n\t\t\tplan.prepareFacts.ManagedIgnoreEntry = plan.gitignoreCleanup.entry\n\t\t}\n\t}\n\n\tif options.force.value {","sourceCodeStart":1286,"sourceCodeEnd":1322,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/worktree_cmd.go#L1286-L1322","documentation":"During removal planning, bd compares the target worktree's common git directory with the primary worktree's common dir. A mismatch means the 'worktree' being removed does not actually belong to the same repository (its common dir resolves elsewhere), so removal would corrupt an unrelated repo. bd records the mismatch in plan facts (CommonDir = Unmatched) and returns the plan with this prepare error instead of proceeding.","triggerScenarios":"`bd worktree remove <name>` where `inspectWorktreeTarget` on the target yields a commonDir that does not path-match the main worktree's common dir — e.g. the registered path now hosts a worktree of a different repository, or GIT_COMMON_DIR/git dir files point across repos.","commonSituations":"A directory reused for another clone after the original worktree was deleted; manually copied worktree folders retaining a .git file pointing to the old repo; nested repos confusing resolution.","solutions":["Verify the target is the intended repo: run `git -C <target> rev-parse --git-common-dir` and compare with the main repo","Re-register/remove the stale worktree entry: `git worktree prune`, then `git worktree add` a fresh worktree of the correct repo and retry","Remove the foreign worktree with plain `git worktree remove` inside the repo it actually belongs to","Do not delete directories by hand; let git manage worktree metadata to keep common dirs consistent"],"exampleFix":"// before: /wt/feature is a worktree of a different clone\n$ bd worktree remove feature\n// error: target common git directory \"/other/clone/.git\" does not match repository \"/main/.git\"\n// after\n$ git worktree prune && git worktree add /wt/feature feature-branch\n$ bd worktree remove feature","handlingStrategy":"validation","validationCode":"main=$(git rev-parse --path-format=absolute --git-common-dir)\ntgt=$(git -C /wt/feature rev-parse --path-format=absolute --git-common-dir)\n[ \"$main\" = \"$tgt\" ] || { echo 'target belongs to a different repository'; exit 1; }","typeGuard":"func sameRepository(mainCommonDir string, target worktreeTarget) bool {\n\treturn filepath.Clean(target.commonDir) == filepath.Clean(mainCommonDir)\n}","tryCatchPattern":"plan, err := buildWorktreeRemovalPlan(ctx, git, name, nil)\nif plan != nil && plan.prepareErr != nil && strings.Contains(plan.prepareErr.Error(), \"does not match repository\") {\n\treturn fmt.Errorf(\"re-add the worktree with `git worktree add` from the correct repo first\")\n}","preventionTips":["Create worktrees only via `git worktree add` from the primary repo","Never copy worktree directories between clones","Prune stale registrations with `git worktree prune` after manual deletions","Check `git worktree list` paths match expectations before scripted removals"],"tags":["git","worktree","repository-mismatch"],"backgroundTag":"worktree-repository-mismatch","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}