xai-org/grok-build · error

no .git file or directory found at {}

Error message

no .git file or directory found at {}

What it means

find_worktree_git_dir resolves a worktree's git directory. If the path it checks contains neither a `.git` file (linked worktree) nor a `.git` directory (regular repo), it bails with this message naming the worktree path. The library throws it because without a git dir there is no index to copy or stats to update.

Source

Thrown at crates/codegen/xai-fast-worktree/src/git/discovery.rs:39

            .ok_or_else(|| anyhow::anyhow!("invalid .git file format: {}", content.trim()))?
            .trim();

        // git may write a RELATIVE pointer (worktrees added with a relative
        // path). Resolve it against the worktree dir — otherwise downstream
        // index lookups join it against the CWD and break (mirrors
        // `read_worktree_gitdir` in api.rs).
        let raw_path = Path::new(raw);
        let resolved = if raw_path.is_relative() {
            worktree_path.join(raw_path)
        } else {
            raw_path.to_path_buf()
        };
        Ok(dunce::canonicalize(&resolved).unwrap_or(resolved))
    } else if git_path.is_dir() {
        // Regular repository
        Ok(git_path)
    } else {
        anyhow::bail!(
            "no .git file or directory found at {}",
            worktree_path.display()
        )
    }
}

/// Find the worktree root (working directory root) for a path.
///
/// This handles both regular repositories and worktrees correctly.
/// For a regular repo at `/repo`, returns `/repo`.
/// For a worktree at `/worktrees/wt1`, returns `/worktrees/wt1`.
/// For a subdirectory `/repo/subdir`, returns `/repo`.
pub(crate) fn find_worktree_root(path: &Path) -> Result<PathBuf> {
    let repo = gix::discover(path)
        .with_context(|| format!("failed to discover git repo at {}", path.display()))?;

    // workdir() returns the working directory root for both repos and worktrees
    let work_dir = repo

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Verify the path is a worktree root containing .git: run `ls -a <path>/.git` and correct the path if it's missing.
  2. If .git was pruned/lost, recreate the worktree with `git worktree add <path> <ref>` instead of repairing it.
  3. If rsync/copy tooling dropped dotfiles, re-copy with dotfiles included (e.g. `rsync -a` without `--exclude=.git`).
  4. Check for a stale registration: `git worktree list` and `git worktree prune` to clean entries pointing at non-existent checkouts.

Example fix

// before: calling with a subdirectory of the checkout
let git_dir = find_worktree_git_dir(&Path::new("/srv/wt/main/src"))?;
// after: guard that the target actually has .git
let root = Path::new("/srv/wt/main");
if !root.join(".git").exists() {
    anyhow::bail!("{} is not a git worktree root", root.display());
}
let git_dir = find_worktree_git_dir(root)?;
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_worktree_root(path: &std::path::Path) -> anyhow::Result<()> {
    let git = path.join(".git");
    if !git.exists() {
        anyhow::bail!("{} is not a git repo/worktree (no .git)", path.display());
    }
    Ok(())
}

Type guard

fn has_git_dir(path: &std::path::Path) -> bool {
    path.join(".git").is_dir() || path.join(".git").is_file()
}

Try / catch

match find_worktree_git_dir(p) {
    Err(e) if e.to_string().contains("no .git file or directory") => {
        eprintln!("{} is not a worktree; run 'git worktree add' first", p.display());
    }
    Err(e) => return Err(e),
    Ok(git_dir) => use(git_dir),
}

Prevention

When it happens

Trigger: Calling find_worktree_git_dir (directly, or via copy_git_index / update_index_stats) on a directory where `<path>/.git` does not exist — the directory isn't a git repo or worktree at all, or is an orphaned bare checkout whose .git was deleted/moved.

Common situations: Pointing the library at the worktree's checkout content directory instead of its root; a worktree whose .git file was deleted after `git worktree prune` or an rsync that skipped dotfiles; running cleanup on a directory that was already removed; typos in the worktree path.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/cefcca2e65b127cf. Report an issue: GitHub.