{"record":{"id":"ca4f77e646d8b343","repo":"nikivdev/code","slug":"git-failed-ca4f77","errorCode":null,"errorMessage":"git {} failed: {}","messagePattern":"git (.+?) failed: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/explain_commits.rs","lineNumber":111,"sourceCode":"    hasher.update(b\"\\n\");\n    hasher.update(message.as_bytes());\n    hasher.update(b\"\\n\");\n    hasher.update(diff.as_bytes());\n    format!(\"{:x}\", hasher.finalize())\n}\n\n// -- Git helpers --\n\nfn git_capture_in(repo_root: &Path, args: &[&str]) -> Result<String> {\n    let output = Command::new(\"git\")\n        .current_dir(repo_root)\n        .args(args)\n        .output()\n        .context(\"failed to run git\")?;\n\n    if !output.status.success() {\n        let stderr = String::from_utf8_lossy(&output.stderr);\n        bail!(\"git {} failed: {}\", args.join(\" \"), stderr.trim());\n    }\n\n    Ok(String::from_utf8_lossy(&output.stdout).to_string())\n}\n\nstruct CommitInfo {\n    sha: String,\n    short_sha: String,\n    message: String,\n    subject: String,\n    author: String,\n    date: String,\n    diff: String,\n    files: Vec<String>,\n}\n\nfn get_commit_info(repo_root: &Path, sha: &str) -> Result<CommitInfo> {\n    let short_sha = &sha[..7.min(sha.len())];","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/explain_commits.rs#L93-L129","documentation":"`git_capture_in` runs a `git` subprocess with the given args and bails when git exits non-zero, formatting the full command and trimmed stderr into the message. It propagates any git failure (bad ref, not a repo, unknown revision) from all commit-info/explain call paths.","triggerScenarios":"`git_capture_in` is called (by get_commit_info, get_commits_in_range, get_last_n_commits, explain_new_commits_since, run_cli) and the spawned `git <args>` returns a non-success exit status; stderr text is embedded in the message.","commonSituations":"Running `f explain` outside a git repository; invalid commit range like `HEAD~50..HEAD` with too few commits; detached/unborn HEAD; git not on PATH produces the related 'failed to run git' context error instead; corrupt .git directory.","solutions":["Read the embedded stderr — it names the git-level cause (e.g. 'not a git repository', 'unknown revision')","Run the command from inside a valid git repository (git rev-parse --git-dir to check)","Verify the commit range/ref arguments exist: git log --oneline -5 or git rev-parse <ref>","Ensure git is installed and on PATH","Test the same git command manually to reproduce the failure"],"exampleFix":"// before\nf explain-commits HEAD~99..HEAD   // git log HEAD~99..HEAD failed: fatal: ambiguous argument\n// after\nf explain-commits HEAD~5..HEAD    # range that exists in this repo","handlingStrategy":"validation","validationCode":"// pre-flight checks before running explain commands\nif !std::path::Path::new(\".git\").exists() {\n    bail!(\"not a git repository — run from a repo checkout\");\n}\nlet ok = std::process::Command::new(\"git\")\n    .args([\"rev-parse\", \"--verify\", \"HEAD~5\"])\n    .status().map(|s| s.success()).unwrap_or(false);\nif !ok { bail!(\"ref HEAD~5 does not exist in this repo\"); }","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().starts_with(\"git \") => {\n        // message is \"git {args} failed: {stderr}\" — surface stderr to the user\n        eprintln!(\"git failure: {e}\");\n    }\n    other => other?,\n}","preventionTips":["Always run explain commands inside a valid git repository","Validate commit ranges/refs exist before passing them","Keep git installed and on PATH","Never amend/rebase history your range depends on mid-run"],"tags":["git","subprocess","cli"],"backgroundTag":"git-command-failed","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}