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

  1. Read the stderr appended to the message; it contains git's actual diagnostic (e.g. 'fatal: pathspec ... did not match any files').
  2. Check that the repo has at least one commit (HEAD exists) before unstaging files in a fresh repository; use `git rm --cached` semantics otherwise.
  3. Verify the entry path matches a file actually reported by git status and that the working directory is inside the worktree.
  4. 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

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


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)