use crate::env;
use std::path::{Path, PathBuf};
use std::process::Command;
fn git(repo_root: &Path) -> Command {
let mut cmd = Command::new("git");
cmd.arg("-C").arg(repo_root);
cmd.env(env::DISABLED, "1");
cmd
}
pub fn detect_repo_root(cwd: &Path) -> PathBuf {
let mut cmd = git(cwd);
if let Ok(out) = cmd.args(["rev-parse", "--show-toplevel"]).output() {
if out.status.success() {
let text = String::from_utf8_lossy(&out.stdout);
let trimmed = text.trim();
if !trimmed.is_empty() {
return PathBuf::from(trimmed);
}
}
}
std::fs::canonicalize(cwd).unwrap_or_else(|_| cwd.to_path_buf())
}
pub fn git_head(repo_root: &Path) -> Option<String> {
let out = git(repo_root).args(["rev-parse", "HEAD"]).output().ok()?;
if out.status.success() {
let text = String::from_utf8_lossy(&out.stdout);
let trimmed = text.trim();
if !trimmed.is_empty() {
return Some(trimmed.to_string());
}
}
None
}
pub fn git_worktree_hash(repo_root: &Path) -> Option<String> {
let out = git(repo_root)
.args(["status", "--porcelain=v1", "-z"])
.output()
.ok()?;
if out.status.success() {
return Some(crate::util::sha256_hex(&out.stdout));
}
None
}