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 = repoView on GitHub (pinned to bc7f02eddd)
Solutions
- Verify the path is a worktree root containing .git: run `ls -a <path>/.git` and correct the path if it's missing.
- If .git was pruned/lost, recreate the worktree with `git worktree add <path> <ref>` instead of repairing it.
- If rsync/copy tooling dropped dotfiles, re-copy with dotfiles included (e.g. `rsync -a` without `--exclude=.git`).
- 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
- Always pass the worktree root, never a subdirectory.
- Copy/rsync worktrees with dotfiles preserved (-a, no --exclude=.git).
- Run `git worktree prune` to drop registrations for deleted checkouts.
- Check `cat <path>/.git` points to a valid worktrees entry.
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
- worktree creation task failed: {e}
- path '{}' is not within git repository '{}'
- git {shown} failed in {}: {}
- git worktree add failed: {}
- git status failed: {}
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/cefcca2e65b127cf.
Report an issue: GitHub.