nikivdev/code · error · anyhow::Error
git {} failed: {}
Error message
git {} failed: {} What it means
`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.
Source
Thrown at src/explain_commits.rs:111
hasher.update(b"\n");
hasher.update(message.as_bytes());
hasher.update(b"\n");
hasher.update(diff.as_bytes());
format!("{:x}", hasher.finalize())
}
// -- Git helpers --
fn git_capture_in(repo_root: &Path, args: &[&str]) -> Result<String> {
let output = Command::new("git")
.current_dir(repo_root)
.args(args)
.output()
.context("failed to run git")?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
bail!("git {} failed: {}", args.join(" "), stderr.trim());
}
Ok(String::from_utf8_lossy(&output.stdout).to_string())
}
struct CommitInfo {
sha: String,
short_sha: String,
message: String,
subject: String,
author: String,
date: String,
diff: String,
files: Vec<String>,
}
fn get_commit_info(repo_root: &Path, sha: &str) -> Result<CommitInfo> {
let short_sha = &sha[..7.min(sha.len())];View on GitHub (pinned to a747e741ae)
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
Example fix
// before f explain-commits HEAD~99..HEAD // git log HEAD~99..HEAD failed: fatal: ambiguous argument // after f explain-commits HEAD~5..HEAD # range that exists in this repo
Defensive patterns
Strategy: validation
Validate before calling
// pre-flight checks before running explain commands
if !std::path::Path::new(".git").exists() {
bail!("not a git repository — run from a repo checkout");
}
let ok = std::process::Command::new("git")
.args(["rev-parse", "--verify", "HEAD~5"])
.status().map(|s| s.success()).unwrap_or(false);
if !ok { bail!("ref HEAD~5 does not exist in this repo"); } Try / catch
match result {
Err(e) if e.to_string().starts_with("git ") => {
// message is "git {args} failed: {stderr}" — surface stderr to the user
eprintln!("git failure: {e}");
}
other => other?,
} Prevention
- 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
When it happens
Trigger: `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.
Common situations: 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.
Understand the failure class
Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.
Related errors
- Lin.app is not running
- failed to stash working tree: {}
- git status failed with {}
- git add failed with {}
- git commit failed with {}
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/ca4f77e646d8b343.
Report an issue: GitHub.