{"record":{"id":"ed8c782fda7aa23b","repo":"xai-org/grok-build","slug":"not-a-git-repository","errorCode":null,"errorMessage":"not a git repository: {}","messagePattern":"not a git repository: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-workspace/src/session/git.rs","lineNumber":419,"sourceCode":"    let head_commit = head_ref\n        .as_ref()\n        .and_then(|h| h.target())\n        .map(|oid| oid.to_string());\n    let head_branch = head_ref\n        .as_ref()\n        .and_then(|h| h.shorthand().filter(|s| *s != \"HEAD\").map(str::to_owned));\n    PersistedGitMetadata {\n        git_root_dir: Some(git_root.to_string_lossy().to_string()),\n        git_remotes: remotes.into_iter().collect(),\n        head_commit,\n        head_branch,\n    }\n}\npub fn find_git_root_from_path(path: &Path) -> Result<PathBuf> {\n    match discover_git_root(path) {\n        GitDiscoveryResult::Found(root) => Ok(root),\n        GitDiscoveryResult::NotARepo => {\n            anyhow::bail!(\"not a git repository: {}\", path.display())\n        }\n        GitDiscoveryResult::DiscoveryFailed(e) => Err(e),\n    }\n}\n/// Find the main repo root (not the worktree working directory).\n/// For regular repos this is the same as find_git_root_from_path.\n/// For worktrees, this returns the parent repo's root.\n/// Use this for worktree management operations (create/remove/apply).\npub fn find_main_repo_root_from_path(path: &Path) -> Result<PathBuf> {\n    let repo = Repository::discover(path)?;\n    repo.commondir()\n        .parent()\n        .map(|p| p.to_path_buf())\n        .ok_or_else(|| anyhow::anyhow!(\"Invalid git repository: {}\", path.display()))\n}\npub fn change_type_from_git2_delta(delta: git2::Delta) -> ChangeType {\n    match delta {\n        git2::Delta::Added => ChangeType::Create,","sourceCodeStart":401,"sourceCodeEnd":437,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-workspace/src/session/git.rs#L401-L437","documentation":"find_git_root_from_path() walks up from the given path via discover_git_root(); when the discovery reports NotARepo (no .git found up to the filesystem root), it bails naming the offending path. Callers use it to locate the repo root before worktree creation, resume, cleanup, or subdir offset computation.","triggerScenarios":"Calling create_worktree_for_resume, cleanup_worktree_on_failure, resume_local_session_in_worktree, or compute_subdir_offset with a path outside any git repository (e.g. /tmp, a home directory, or a session directory recorded before the repo was moved/deleted).","commonSituations":"Pointing a resume at a workspace copy without .git; repo deleted or .git removed; passing an absolute path on a different mount that has no repo ancestor; typos in the configured workspace path.","solutions":["Run `git -C <path> rev-parse --show-toplevel` to confirm the path is inside a repo","Pass the actual repo (or a path under it) instead of a scratch directory","Restore/re-clone the repository if .git was deleted","Fix the configured workspace/session path that points outside the repo"],"exampleFix":"// before\nlet root = find_git_root_from_path(Path::new(\"/tmp/session-123\"))?;\n// after\nlet root = find_git_root_from_path(Path::new(\"/home/dev/project/src/...\"))?; // inside the repo","handlingStrategy":"validation","validationCode":"fn ensure_inside_repo(p: &Path) -> anyhow::Result<()> {\n    let out = std::process::Command::new(\"git\").arg(\"-C\").arg(p).args([\"rev-parse\",\"--show-toplevel\"]).output()?;\n    if !out.status.success() { anyhow::bail!(\"{} is not inside a git repository\", p.display()); }\n    Ok(())\n}","typeGuard":"fn is_git_repo(p: &Path) -> bool { p.ancestors().any(|a| a.join(\".git\").exists()) }","tryCatchPattern":"match find_git_root_from_path(&path) {\n    Ok(root) => use_root(root),\n    Err(e) if e.to_string().starts_with(\"not a git repository\") => {\n        // prompt user to point at the repo or re-clone\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Store/resolve workspace paths from the repo root, never scratch dirs","Check for .git (or use git rev-parse) at startup before any session operations","Re-validate recorded session paths — repos can be moved or deleted","Canonicalize paths (dunce::canonicalize) before discovery"],"tags":["git","repository","path","validation"],"backgroundTag":"not-a-git-repository","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}