xai-org/grok-build · error · anyhow::Error

invalid .git file format: {}

Error message

invalid .git file format: {}

What it means

Thrown by find_worktree_git_dir when a worktree's `.git` path is a file but its content does not start with `gitdir: `. A valid worktree `.git` file must be a single line of the form `gitdir: <path>` pointing at the real repository gitdir; anything else means the file is corrupt or not actually a worktree pointer.

Source

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

use std::path::{Path, PathBuf};

use anyhow::{Context, Result};

/// Find the worktree's git directory from its `.git` file.
///
/// Worktrees have a `.git` file (not directory) that points to the actual git dir.
/// For regular repos, returns the `.git` directory.
pub(crate) fn find_worktree_git_dir(worktree_path: &Path) -> Result<PathBuf> {
    let git_path = worktree_path.join(".git");

    if git_path.is_file() {
        // Worktree: .git is a file containing "gitdir: <path>"
        let content = std::fs::read_to_string(&git_path)
            .with_context(|| format!("failed to read .git file at {}", git_path.display()))?;

        let raw = content
            .strip_prefix("gitdir: ")
            .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!(

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Inspect the `.git` file and restore the correct `gitdir: <path-to-main-repo>/.git/worktrees/<name>` line
  2. Recreate the worktree with `git worktree add` to regenerate a valid `.git` file
  3. Run `git worktree repair` / `git worktree prune` from the main repository to fix or clean stale worktree pointers
  4. If the path is relative, ensure the resolved path exists relative to the worktree directory

Example fix

// before (.git file content)
/main/repo/.git/worktrees/wt1
// after
gitdir: /main/repo/.git/worktrees/wt1
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_gitfile(path: &Path) -> bool {
    std::fs::read_to_string(path)
        .map(|c| c.starts_with("gitdir: "))
        .unwrap_or(false)
}
// call find_worktree_git_dir only if git_path is a file && is_valid_gitfile(...)

Type guard

fn valid_gitdir_pointer(s: &str) -> Option<&str> {
    s.strip_prefix("gitdir: ").map(str::trim)
}

Try / catch

match find_worktree_git_dir(git_path) {
    Ok(p) => p,
    Err(e) if e.to_string().contains("invalid .git file format") => {
        // regenerate worktree or repair .git pointer
        fallback_discover_with_gix(git_path)?
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling find_worktree_git_dir (directly or via copy_git_index / update_index_stats) on a repo where `.git` is a malformed or truncated file, a placeholder file, or a file written by a tool that does not follow the git worktree convention.

Common situations: Manual editing or overwriting of `.git` with a path but missing the `gitdir: ` prefix; aborted worktree creation leaving a partial `.git`; syncing tools that flatten the file; Windows/CRLF or stray whitespace edge cases handled only partially by the trim.

Related errors


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