{"record":{"id":"ec08fd6b9d62f114","repo":"gastownhall/beads","slug":"not-a-git-repository","errorCode":null,"errorMessage":"not a git repository","messagePattern":"not a git repository","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/doctor/fix/hooks.go","lineNumber":606,"sourceCode":"\t}\n\treturn strings.Join(names, \", \")\n}\n\n// GitHooks fixes missing or broken git hooks by calling bd hooks install.\n// If external hook managers are detected (lefthook, husky, etc.), it uses\n// --chain to preserve existing hooks instead of overwriting them.\nfunc GitHooks(path string) error {\n\t// Validate workspace\n\tif err := validateBeadsWorkspace(path); err != nil {\n\t\treturn err\n\t}\n\n\t// Check if we're in a git repository using git rev-parse\n\t// This handles worktrees where .git is a file, not a directory\n\tcheckCmd := exec.Command(\"git\", \"rev-parse\", \"--git-dir\")\n\tcheckCmd.Dir = path\n\tif err := checkCmd.Run(); err != nil {\n\t\treturn fmt.Errorf(\"not a git repository\")\n\t}\n\n\t// Detect external hook managers\n\texternalManagers := DetectExternalHookManagers(path)\n\n\t// Get bd binary path\n\tbdBinary, err := getBdBinary()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Build command arguments\n\t// Use --force to cleanly replace outdated hooks without creating backups (GH#1466)\n\targs := []string{\"hooks\", \"install\", \"--force\"}\n\n\t// If external hook managers detected, use --chain to preserve them\n\tif len(externalManagers) > 0 {\n\t\targs = append(args, \"--chain\")","sourceCodeStart":588,"sourceCodeEnd":624,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/doctor/fix/hooks.go#L588-L624","documentation":"GitHooks installs bd's git hooks via the `bd hooks install` subprocess, but first verifies the target path is a git repository by running `git rev-parse --git-dir` with cmd.Dir set to path. If that command fails (non-zero exit / git not resolvable), the plain error \"not a git repository\" is returned and no hooks are installed.","triggerScenarios":"Calling GitHooks (via bd doctor hook fixes) on a directory that is not inside a git work tree: a plain folder, a bare repo without a work tree at that path, a deleted/invalid .git, or git not on PATH so exec fails.","commonSituations":"Running `bd doctor` in a subdirectory outside any repo; CI checkouts using shallow/submodule setups with broken .git; worktrees whose .git file points at a missing branch dir; PATH missing git in containers.","solutions":["Run the command from inside a valid git repository (cd to the repo root or a tracked subdirectory)","Verify with `git rev-parse --git-dir` yourself in the target path","If it's a worktree, repair the .git file link (git worktree repair); ensure git is installed and on PATH"],"exampleFix":"// before\nerr := fix.G-hooks(path) // not a git repository\n// after: guard before calling\nif err := exec.Command(\"git\", \"-C\", path, \"rev-parse\", \"--git-dir\").Run(); err != nil {\n\treturn fmt.Errorf(\"skipping hooks: %s is not a git repo\", path)\n}","handlingStrategy":"validation","validationCode":"cmd := exec.Command(\"git\", \"-C\", path, \"rev-parse\", \"--git-dir\")\nif err := cmd.Run(); err != nil {\n\treturn fmt.Errorf(\"%s is not a git repository, skipping hooks install\", path)\n}","typeGuard":null,"tryCatchPattern":"if err := fix.GitHooks(path, bdBinary); err != nil {\n\tif err.Error() == \"not a git repository\" {\n\t\tlog.Printf(\"skipping hooks: %s has no git work tree\", path)\n\t\treturn nil // non-fatal for doctor runs outside repos\n\t}\n\treturn err\n}","preventionTips":["Always run doctor/hook fixes from inside a git work tree","Verify `git rev-parse --git-dir` succeeds in the target path first","Ensure git is installed and on PATH in containers/CI images","Repair broken worktrees with `git worktree repair`"],"tags":["git","hooks","doctor","environment"],"backgroundTag":"not-a-git-repository","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}