jdx/mise · error
git merge-file failed: {}
Error message
git merge-file failed: {} What it means
`git merge-file` exit status encodes the number of conflicts as a positive code, and success is 0. A negative code (or None) means the process itself failed — it was killed by a signal or never ran — rather than reporting merge conflicts. The tool treats conflicts (positive codes) as a normal 'no clean merge' result, but a negative code is an infrastructure failure, so it bails with git's stderr.
Source
Thrown at src/system/history/shadow.rs:1370
std::fs::write(&t, theirs)?;
let output = self.git.output_unchecked(PlumbingCall::new([
"merge-file",
"-p",
"-L",
"local",
"-L",
"base",
"-L",
"remote",
&o.to_string_lossy(),
&b.to_string_lossy(),
&t.to_string_lossy(),
]))?;
// exit status is the number of conflicts; negative on error
match output.status.code() {
Some(0) => Ok(Some(output.stdout)),
Some(code) if code > 0 => Ok(None),
_ => bail!(
"git merge-file failed: {}",
String::from_utf8_lossy(&output.stderr).trim()
),
}
}
/// Runs a network command with the user's git configuration.
pub(crate) fn network<'a>(
&self,
args: impl IntoIterator<Item = &'a str>,
) -> Result<std::process::Output> {
self.git.network_output(PlumbingCall::new(args))
}
const ANNOTATION_TRAILER: &'static str = "Mise-Annotation: ";
/// An annotation is an empty ordinary child commit, so labels and
/// descriptions travel with the same ancestry without rewriting it.View on GitHub (pinned to afd2eddd3a)
Solutions
- Run `git merge-file <ours> <base> <theirs>` manually on the reported files and observe the failure.
- Verify `git --version` works and that the temp directory is writable.
- Check for signal kills (OOM killer, AV interference) in system logs around the failure time.
- Re-run the dotfile sync; if persistent, reinstall or repair the system git.
Defensive patterns
Strategy: try-catch
Validate before calling
for f in [ours, base, theirs] {
assert!(Path::new(f).exists(), "merge-file input {f} missing");
} Try / catch
match history.three_way_merge(ours, base, theirs) {
Ok(Some(out)) => write_clean(out),
Ok(None) => prompt_manual_conflict_resolution(),
Err(e) if e.to_string().contains("git merge-file failed") => {
eprintln!("merge-file process failed (signal/IO): {e}");
fallback_to_manual_merge()?;
}
Err(e) => return Err(e),
} Prevention
- Keep temp files on a local writable filesystem
- Configure AV/endpoint tools to skip git temp files
- Repair a broken system git installation promptly
When it happens
Trigger: Three-way merging a dotfile when `git merge-file` cannot execute: the temp file paths are missing/unwritable, git is broken, or the child process is killed by a signal (negative exit code from a signal death).
Common situations: Antivirus or system cleanup deletes temp files mid-operation; a sandboxed/limited environment prevents git from writing temp files; the system git installation is damaged.
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 diff failed: {}
- git command failed with {status}
- git clone failed with {status}
- comparing checkpoints requires git
- listing snapshot files requires git
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/0c0468adb51da116.
Report an issue: GitHub.