use std::path::Path;
use anyhow::Result;
use super::run_git_stdout;
pub fn diff_commit(workdir: &Path, oid: &str) -> Result<String> {
run_git_stdout(workdir, &["diff", &format!("{}^..{}", oid, oid)])
}
pub fn diff_commit_file(workdir: &Path, oid: &str, path: &str) -> Result<String> {
run_git_stdout(
workdir,
&["diff", &format!("{}^..{}", oid, oid), "--", path],
)
}
pub fn diff_cached_files(workdir: &Path, files: &[&str]) -> Result<String> {
let mut args = vec!["diff", "--cached", "--"];
args.extend(files);
run_git_stdout(workdir, &args)
}
pub fn diff_head_name_only(workdir: &Path) -> Result<String> {
run_git_stdout(workdir, &["diff", "HEAD", "--name-only"])
}
pub fn diff_head_file(workdir: &Path, path: &str) -> Result<String> {
run_git_stdout(workdir, &["diff", "HEAD", "--", path])
}
pub fn diff_head_file_is_binary(workdir: &Path, path: &str) -> Result<bool> {
let out = run_git_stdout(workdir, &["diff", "--numstat", "HEAD", "--", path])?;
Ok(out.starts_with("-\t"))
}
pub fn diff_file(workdir: &Path, path: &str) -> Result<String> {
run_git_stdout(workdir, &["diff", "--", path])
}
pub fn diff_cached_file(workdir: &Path, path: &str) -> Result<String> {
run_git_stdout(workdir, &["diff", "--cached", "--", path])
}
pub fn diff_file_is_binary(workdir: &Path, path: &str) -> Result<bool> {
let out = run_git_stdout(workdir, &["diff", "--numstat", "--", path])?;
Ok(out.starts_with("-\t"))
}
pub fn diff_cached_file_is_binary(workdir: &Path, path: &str) -> Result<bool> {
let out = run_git_stdout(workdir, &["diff", "--cached", "--numstat", "--", path])?;
Ok(out.starts_with("-\t"))
}
pub fn diff_commit_file_is_binary(workdir: &Path, oid: &str, path: &str) -> Result<bool> {
let out = run_git_stdout(
workdir,
&[
"diff",
"--numstat",
&format!("{}^..{}", oid, oid),
"--",
path,
],
)?;
Ok(out.starts_with("-\t"))
}
pub fn diff_commit_name_status(workdir: &Path, oid: &str) -> Result<Vec<(char, String)>> {
let out = run_git_stdout(
workdir,
&["diff", "--name-status", &format!("{}^..{}", oid, oid)],
)?;
let mut result = Vec::new();
for line in out.lines() {
let line = line.trim();
if line.is_empty() {
continue;
}
let mut fields = line.splitn(3, '\t');
let status_field = fields.next().unwrap_or("");
let path1 = fields.next().unwrap_or("").trim();
let path2 = fields.next().map(str::trim);
if status_field.is_empty() || path1.is_empty() {
continue;
}
let status = status_field.chars().next().unwrap_or('M');
let path = match (status, path2) {
('R' | 'C', Some(dest)) => dest.to_string(),
_ => path1.to_string(),
};
result.push((status, path));
}
Ok(result)
}
pub fn diff_head(workdir: &Path) -> Result<String> {
run_git_stdout(workdir, &["diff", "HEAD"])
}
pub fn diff_head_files(workdir: &Path, files: &[&str]) -> Result<String> {
let mut args = vec!["diff", "HEAD", "--"];
args.extend(files);
run_git_stdout(workdir, &args)
}