{"record":{"id":"a0bafaedbc08d579","repo":"jdx/mise","slug":"git-difftool-failed-status","errorCode":null,"errorMessage":"Git difftool failed ({status})","messagePattern":"Git difftool failed \\((.+?)\\)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/dotfiles/conflicts.rs","lineNumber":144,"sourceCode":"    let local = side_file(repo, conflict.local.as_ref(), path, \"local\")?;\n    let remote = side_file(repo, conflict.remote.as_ref(), path, \"remote\")?;\n    let git = crate::git::plumbing_binary().ok_or_else(|| eyre::eyre!(\"git is unavailable\"))?;\n    let mut command = Command::new(git);\n    crate::git::sanitize_git_command(&mut command);\n    command\n        .current_dir(repo.dir().parent().unwrap_or(repo.dir()))\n        .args([\"difftool\", \"--no-prompt\"]);\n    if let Some(tool) = tool {\n        command.arg(\"--tool\").arg(tool);\n    }\n    command.arg(\"--no-index\").arg(\"--\");\n    command.arg(local.file.path()).arg(remote.file.path());\n    let status = command\n        .status()\n        .wrap_err_with(|| format!(\"running Git conflict difftool for {}\", display_path(path)))?;\n    // Like `git diff --no-index`, difftool exits 1 when the sides differ.\n    if !matches!(status.code(), Some(0 | 1)) {\n        bail!(\"Git difftool failed ({status})\");\n    }\n    if local.mode != remote.mode {\n        miseprintln!(\"mode: {} -> {}\", local.mode, remote.mode);\n    }\n    Ok(())\n}\n\nstruct SideFile {\n    file: tempfile::NamedTempFile,\n    mode: String,\n    label: String,\n}\n\nfn side_file(\n    repo: &HistoryRepo,\n    object: Option<&Object>,\n    path: &Path,\n    side: &str,","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/cli/dotfiles/conflicts.rs#L126-L162","documentation":"The conflicts command shells out to `git difftool` to show local-vs-remote sides of a conflict. Git difftool may exit 1 when the sides differ (treated as success), but any other exit code or signal causes a bail with the exit status.","triggerScenarios":"`git difftool` exits with a code other than 0 or 1 while `mise dot conflicts` renders a conflict diff — usually a misconfigured diff tool or difftool erroring on the given files.","commonSituations":"`diff.tool` configured to a GUI tool unavailable headless; difftool command not found; difftool crashed on binary/huge files; custom difftool exits with a nonstandard code.","solutions":["Check the configured difftool (`git config diff.tool`, `difftool.<tool>.cmd`) and fix or switch to a working tool (e.g. `git config diff.tool vimdiff`)","Run the difftool manually on the two file paths from the error context to see its real error","Ensure the difftool exists on PATH and works headless (set a CLI-based tool in SSH/CI environments)","Re-run `mise dot conflicts` after fixing the difftool config"],"exampleFix":"// before\n$ git config diff.tool kaleidoscope   # GUI tool, not installed\n$ mise dot conflicts\nerror: Git difftool failed (exit status: 127)\n// after\n$ git config --global diff.tool vimdiff\n$ mise dot conflicts","handlingStrategy":"try-catch","validationCode":"git difftool --tool-help >/dev/null 2>&1 && echo \"difftool configured\" || echo \"configure diff.tool\"","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"Git difftool failed\") => {\n        // fix git diff.tool config or PATH, then retry\n    }\n    ...\n}","preventionTips":["Configure a CLI-friendly difftool (vimdiff, delta) for headless environments","Test `git difftool` manually before relying on `mise dot conflicts` in scripts"],"tags":["dotfiles","git","difftool"],"backgroundTag":"git-command-failed","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}