affaan-m/ECC · error
git reset failed for
Error message
git reset failed for {path}: {stderr} What it means
Thrown by unstage_path in ecc2/src/worktree/mod.rs when the underlying `git reset` command used to unstage a file exits with a non-zero status. The library shells out to git, captures stderr, and surfaces it verbatim so the caller can see the git-level cause. It is a wrapper around any git CLI failure during the unstage operation.
Solutions
- Read the stderr appended to the message; it contains git's actual diagnostic (e.g. 'fatal: pathspec ... did not match any files').
- Check that the repo has at least one commit (HEAD exists) before unstaging files in a fresh repository; use `git rm --cached` semantics otherwise.
- Verify the entry path matches a file actually reported by git status and that the working directory is inside the worktree.
- Ensure the git index is writable and not locked (check for .git/index.lock leftovers).
Example fix
// before: unstage blindly
unstage_path(&worktree, &entry)?;
// after: guard against empty HEAD / untracked file
if repo_has_head(&worktree) && !entry.untracked {
unstage_path(&worktree, &entry)?;
} Defensive patterns
Strategy: try-catch
Validate before calling
fn can_unstage(worktree: &WorktreeInfo, entry: &GitStatusEntry) -> bool {
!entry.untracked && std::path::Path::new(&worktree.path).join(".git").exists()
} Type guard
fn is_unstaged_entry(entry: &GitStatusEntry) -> bool { !entry.untracked && entry.unstaged } Try / catch
match unstage_path(&worktree, &entry) {
Ok(()) => refresh_status(),
Err(e) => eprintln!("unstage failed: {e:#}"), // stderr from git included
} Prevention
- Only pass entries taken directly from git status output, never arbitrary paths.
- Skip untracked entries — they cannot be unstaged via `git reset` in a repo without HEAD.
- Check for a stale .git/index.lock before index operations.
When it happens
Trigger: Calling unstage_path(worktree, entry) for a path where `git reset -- <path>` fails: path not tracked in HEAD (e.g. resetting an untracked file in a repo with no prior commits), path is outside the repo, pathspec ambiguity, or git repository corruption.
Common situations: Trying to unstage a file that was never committed in a brand-new repository with no HEAD; typo'd or non-ASCII path handling; running in a bare repo or a directory that is not a git worktree; permissions issues on .git/index.
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
- git restore failed for
- Base branch is not checked out in repo root (currently )
- git commit failed
- git log failed
- git rev-parse failed
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/05b96d23a270d04f.
Report an issue: GitHub.
Appendix: source
Thrown at ecc2/src/worktree/mod.rs:320
} else {
let stderr = String::from_utf8_lossy(&output.stderr);
anyhow::bail!("git add failed for {path}: {stderr}");
}
}
pub fn unstage_path(worktree: &WorktreeInfo, path: &str) -> Result<()> {
let output = Command::new("git")
.arg("-C")
.arg(&worktree.path)
.args(["reset", "HEAD", "--"])
.arg(path)
.output()
.with_context(|| format!("Failed to unstage {}", path))?;
if output.status.success() {
Ok(())
} else {
let stderr = String::from_utf8_lossy(&output.stderr);
anyhow::bail!("git reset failed for {path}: {stderr}");
}
}
pub fn reset_path(worktree: &WorktreeInfo, entry: &GitStatusEntry) -> Result<()> {
if entry.untracked {
let target = worktree.path.join(&entry.path);
if !target.exists() {
return Ok(());
}
let metadata = fs::symlink_metadata(&target)
.with_context(|| format!("Failed to inspect untracked path {}", target.display()))?;
if metadata.is_dir() {
fs::remove_dir_all(&target)
.with_context(|| format!("Failed to remove {}", target.display()))?;
} else {
fs::remove_file(&target)
.with_context(|| format!("Failed to remove {}", target.display()))?;
}View on GitHub (pinned to 8321021c54)