use super::{pop_keyboard_enhancement, push_keyboard_enhancement};
use crate::git::git_capture;
use ratatui::DefaultTerminal;
use std::process::Command;
const EMPTY_TREE: &str = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
fn has_difftool(dir: &str) -> bool {
["diff.tool", "merge.tool"]
.iter()
.any(|k| git_capture(dir, &["config", k]).is_some_and(|v| !v.is_empty()))
}
pub fn difftool_commit(
terminal: &mut DefaultTerminal,
enhanced: bool,
dir: &str,
hash: &str,
path: &str,
) -> String {
let base = if commit_has_parent(dir, hash) {
format!("{hash}^")
} else {
EMPTY_TREE.to_string()
};
run_difftool(terminal, enhanced, dir, &[&base, hash, "--", path])
}
fn commit_has_parent(dir: &str, hash: &str) -> bool {
git_capture(dir, &["rev-list", "--parents", "-n", "1", hash])
.map(|s| s.split_whitespace().count() > 1)
.unwrap_or(false)
}
pub fn run_difftool(
terminal: &mut DefaultTerminal,
enhanced: bool,
dir: &str,
args: &[&str],
) -> String {
if !has_difftool(dir) {
return "no difftool set - configure one: git config --global diff.tool <tool>".to_string();
}
if enhanced {
pop_keyboard_enhancement();
}
ratatui::restore();
let status = Command::new("git")
.arg("-C")
.arg(dir)
.arg("difftool")
.arg("-y")
.args(args)
.status();
*terminal = ratatui::init();
if enhanced {
push_keyboard_enhancement();
}
let _ = terminal.clear();
match status {
Ok(s) if s.success() => String::new(),
Ok(_) => "difftool exited with an error".to_string(),
Err(e) => format!("could not launch difftool: {e}"),
}
}