jdx/mise · error

git diff failed ({}): {}

Error message

git diff failed ({}): {}

What it means

In the general (non-fast-path) diff, git's exit code is checked after capturing stdout/stderr. Any code other than 0 (unchanged) or 1 (changed) is treated as a git failure, and the error includes the status and trimmed stderr to expose git's actual complaint.

Source

Thrown at src/system/history/shadow.rs:919

                    output: vec![],
                    changed: true,
                }),
                _ => bail!("git diff failed ({status})"),
            };
        }
        let output = self.git.output_unchecked(call)?;
        match output.status.code() {
            Some(0) => Ok(DiffResult {
                output: output.stdout,
                changed: false,
            }),
            Some(1) => Ok(DiffResult {
                output: output.stdout,
                changed: true,
            }),
            _ => {
                let stderr = String::from_utf8_lossy(&output.stderr);
                bail!("git diff failed ({}): {}", output.status, stderr.trim())
            }
        }
    }

    /// Decrypt only for this requested comparison. Git's no-index diff sees
    /// private temporary files, never plaintext objects in the repository.
    fn decrypted_diff(&self, a: &str, b: &str, opts: &DiffOpts) -> Result<DiffResult> {
        use std::io::Write;
        let mut paths = BTreeSet::new();
        for (tree, prefix) in [
            (a, opts.paths.as_ref().map(|p| p.0.as_str())),
            (b, opts.paths.as_ref().map(|p| p.1.as_str())),
        ] {
            for entry in self.ls_tree(tree)? {
                if entry.path.starts_with(".mise-history/") {
                    continue;
                }
                if let Some(prefix) = prefix {

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Read the stderr embedded in the message to identify git's specific failure
  2. Verify snapshot oids exist (`git cat-file -e <oid>`) and restore missing objects (`git fetch`/re-capture)
  3. Run `git fsck` on the history repository to find corruption
Defensive patterns

Strategy: try-catch

Validate before calling

// Shell: surface git's real error before calling the library
git cat-file -e "$FROM_OID" && git cat-file -e "$TO_OID" || echo "missing snapshot object"

Try / catch

match differ.diff(from, to, paths) {
    Err(e) if e.to_string().contains("git diff failed") => {
        eprintln!("{e}"); // message already embeds git's trimmed stderr
    }
    other => other?,
}

Prevention

When it happens

Trigger: diff runs git diff via output_unchecked and receives an exit code other than 0 or 1; the bail surfaces git's stderr (e.g. 'fatal: bad object <oid>').

Common situations: Missing/pruned git objects for old snapshots; bad object ids in stored history metadata; git version incompatibilities; permission problems reading the repository.

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 jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/9c8224aae6188976. Report an issue: GitHub.