use std::path::Path;
use std::process::Command;
use super::state::{StatusEntry, parse_status_porcelain_z};
pub fn run_git(cwd: &Path, args: &[&str]) -> anyhow::Result<String> {
let output = Command::new("git")
.args(args)
.current_dir(cwd)
.output()
.map_err(|e| anyhow::anyhow!("failed to spawn git {args:?}: {e}"))?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr).into_owned();
return Err(anyhow::anyhow!(
"git {args:?} failed ({}): {stderr}",
output.status
));
}
Ok(String::from_utf8_lossy(&output.stdout).into_owned())
}
pub fn status_porcelain_z(cwd: &Path) -> anyhow::Result<Vec<StatusEntry>> {
let raw = run_git(cwd, &["status", "--porcelain", "-z"])?;
Ok(parse_status_porcelain_z(raw.as_bytes()))
}
pub fn diff_head(cwd: &Path) -> anyhow::Result<String> {
let head_ok = Command::new("git")
.args(["rev-parse", "--verify", "HEAD"])
.current_dir(cwd)
.output()
.map(|o| o.status.success())
.unwrap_or(false);
if head_ok {
run_git(cwd, &["diff", "HEAD", "--no-ext-diff", "--no-color"])
} else {
Ok(String::new())
}
}