gastownhall/beads · error

not in a git repository

Error message

not in a git repository

What it means

configureSharedHooksPath sets core.hooksPath to <repoRoot>/.beads-hooks and needs a repository root to anchor it (git resolves relative hooks paths against the work tree root, hence the absolute path). It tries git.GetMainRepoRoot() then git.GetRepoRoot(); when both are empty it fails with `not in a git repository`.

Source

Thrown at cmd/bd/hooks.go:1288

	// v9: `. "$(dirname "$0")/h"`  (or with `--` / single quotes).
	// Require both `dirname` and a trailing `/h"` or `/h'` to avoid matching
	// unrelated sourcing of files that happen to end in "h".
	if strings.Contains(line, "dirname") && (strings.HasSuffix(line, `/h"`) || strings.HasSuffix(line, `/h'`) || strings.HasSuffix(line, "/h")) {
		return true
	}
	return false
}

func configureSharedHooksPath() error {
	// Set git config core.hooksPath to an absolute path pointing to .beads-hooks.
	// Using an absolute path is critical for git worktrees (GH#2414):
	// git resolves relative core.hooksPath relative to the working tree root.
	repoRoot, _ := git.GetMainRepoRoot()
	if repoRoot == "" {
		repoRoot = git.GetRepoRoot()
	}
	if repoRoot == "" {
		return fmt.Errorf("not in a git repository")
	}
	absHooksPath := filepath.Join(repoRoot, ".beads-hooks")
	cmd := exec.Command("git", "config", "core.hooksPath", absHooksPath)
	cmd.Dir = repoRoot
	if output, err := cmd.CombinedOutput(); err != nil {
		return fmt.Errorf("git config failed: %w (output: %s)", err, string(output))
	}
	return nil
}

func configureBeadsHooksPath() error {
	// Set git config core.hooksPath to an absolute path pointing to .beads/hooks.
	// Using an absolute path is critical for git worktrees (GH#2414):
	// git resolves relative core.hooksPath relative to the working tree root,
	// so in a worktree ".beads/hooks" would resolve to <worktree>/.beads/hooks/
	// which doesn't exist — the hooks live in the main repo's .beads/hooks/.
	repoRoot, _ := git.GetMainRepoRoot()
	if repoRoot == "" {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Run `git init` if the directory should be a repository, then re-run the bd command
  2. cd into the actual repository root and re-run `bd hooks install --shared`
  3. Verify `git rev-parse --show-toplevel` succeeds from your current directory
  4. If in CI without .git, fetch the full checkout (git fetch / clone) before installing hooks

Example fix

// before
$ cd /tmp/proj-src && bd hooks install --shared
not in a git repository
// after
$ git init && bd hooks install --shared
Defensive patterns

Strategy: validation

Validate before calling

git rev-parse --show-toplevel >/dev/null 2>&1 && echo ok || echo 'not a git repository — run git init or cd into the repo'

Try / catch

if err := installHooksWithOptions(names, false, true, false, false); err != nil { if strings.Contains(err.Error(), "not in a git repository") { /* run git init or change directory, then retry */ } }

Prevention

When it happens

Trigger: installHooksWithOptions (shared mode) calls configureSharedHooksPath from a directory where git cannot find a work tree — no .git anywhere up the tree, GIT_DIR pointing nowhere, or an uninitialized repo.

Common situations: Running `bd hooks install --shared` in a temp directory or home dir outside any repo; running before `git init`; CI steps that download sources without the .git directory.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/ea68ac3d5b17ddc6. Report an issue: GitHub.