nikivdev/code · error
git diff --cached --name-only failed
Error message
git diff --cached --name-only failed
What it means
`staged_gitignore_files` shells out to `git diff --cached --name-only --diff-filter=ACMR` inside the repository root to list staged .gitignore files. When the subprocess exits with a non-zero status, the function bails with this message. This is not a parse error of the diff output itself — it means git itself rejected the invocation.
Source
Thrown at src/gitignore_policy.rs:459
if line.starts_with(' ') {
line_no = line_no.saturating_add(1);
}
}
}
Ok(violations)
}
fn staged_gitignore_files(repo_root: &Path) -> Result<Vec<String>> {
let output = Command::new("git")
.current_dir(repo_root)
.args(["diff", "--cached", "--name-only", "--diff-filter=ACMR"])
.output()
.context("failed to list staged files")?;
if !output.status.success() {
bail!("git diff --cached --name-only failed")
}
Ok(String::from_utf8_lossy(&output.stdout)
.lines()
.map(str::trim)
.filter(|s| s.ends_with(".gitignore"))
.map(|s| s.to_string())
.collect())
}
fn inspect_repo_gitignores(repo_root: &Path, policy: &GitignorePolicy) -> Result<Vec<Violation>> {
let blocked = blocked_lookup(policy);
let files = list_gitignore_files(repo_root);
let mut out = Vec::new();
for file in files {
let content = fs::read_to_string(&file)
.with_context(|| format!("failed to read {}", file.display()))?;View on GitHub (pinned to a747e741ae)
Solutions
- Verify the process runs inside a valid git repository: `git -C <repo_root> rev-parse --is-inside-work-tree`
- Check for a stale lock file and remove it: `rm <repo_root>/.git/index.lock` (only when no git process is running)
- If on a CI container, add the checkout dir to safe.directory: `git config --global --add safe.directory <repo_root>`
- Run the exact command manually to see git's real error: `git -C <repo_root> diff --cached --name-only --diff-filter=ACMR`
Example fix
// before
let output = Command::new("git")
.args(["diff", "--cached", "--name-only", "--diff-filter=ACMR"])
.current_dir(repo_root)
.output()
.context("failed to list staged files")?;
// after
let output = Command::new("git")
.args(["-C", repo_root.to_str().unwrap(), "rev-parse", "--is-inside-work-tree"])
.output()?;
anyhow::ensure!(output.status.success(), "not a git repo: {}", repo_root.display());
let output = Command::new("git")
.args(["diff", "--cached", "--name-only", "--diff-filter=ACMR"])
.current_dir(repo_root)
.output()
.context("failed to list staged files")?; Defensive patterns
Strategy: try-catch
Validate before calling
let ok = Command::new("git")
.args(["-C", repo_root.to_str().unwrap(), "rev-parse", "--is-inside-work-tree"])
.output()
.map(|o| o.status.success())
.unwrap_or(false);
if !ok { anyhow::bail!("{} is not a usable git repository", repo_root.display()); } Type guard
fn is_git_repo(repo_root: &Path) -> bool {
repo_root.join(".git").exists()
&& Command::new("git")
.args(["-C", repo_root.to_str().unwrap(), "rev-parse", "--git-dir"])
.output()
.map(|o| o.status.success())
.unwrap_or(false)
} Try / catch
match staged_gitignore_files(repo_root) {
Ok(files) => process(files),
Err(e) if e.to_string().contains("git diff --cached") => {
eprintln!("git unavailable/index locked: {e:#}");
eprintln!("hint: check for .git/index.lock or run outside a repo");
}
Err(e) => return Err(e),
} Prevention
- Always verify the working directory is a git repo before running staged-file helpers
- Check for `.git/index.lock` before invoking git index operations
- Add `safe.directory` config in CI containers running as a different user
- Surface the child process's stderr in the error, not just a static message
When it happens
Trigger: Running `git diff --cached` while not inside a git repository or in a repo whose .git dir is unreadable; a corrupt or locked git index (e.g. stale index.lock); a git version that does not support the flags; git exiting due to safe.directory ownership restrictions.
Common situations: Calling this helper from outside a git repo (repo_root mis-detected or a parent path passed in); running during a git operation that holds an index lock (rebase/merge in progress); CI containers where the checkout is owned by a different user than the process.
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
- failed to stash working tree: {}
- Lin.app is not running
- codex skill-eval launchd install failed: {}
- git status failed with {}
- git add failed with {}
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/e3fbd8372b563a26.
Report an issue: GitHub.