//! Pure-filesystem git-hash stamp — **zero shell, zero `Command`, zero `git`**
//! (the pure-Rust / zero-shell LAW). We read `.git` state off disk ourselves and
//! export the resolved commit as `COLLECTORS_GIT_HASH`, which `--version`/`-V` and
//! the daemon health surface surface at runtime.
//!
//! Handles: a normal `.git` directory, a `.git` **file** (worktree / submodule:
//! `gitdir: <path>`), a symbolic `HEAD` (`ref: refs/heads/<branch>`) resolved
//! against loose refs OR `packed-refs`, a **detached** HEAD (raw 40-hex sha), and
//! the worktree `commondir` split (HEAD lives in the per-worktree gitdir, refs in
//! the common dir). Anything unresolvable falls back to `unknown` — the build
//! never fails for want of a hash.
use std::fs;
use std::path::{Path, PathBuf};
fn main() {
let manifest_dir =
PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".into()));
let hash = resolve_git_hash(&manifest_dir).unwrap_or_else(|| "unknown".to_string());
println!("cargo:rustc-env=COLLECTORS_GIT_HASH={hash}");
}
/// Resolve HEAD to a commit sha using only filesystem reads. `None` → caller
/// falls back to `unknown`.
fn resolve_git_hash(manifest_dir: &Path) -> Option<String> {
let git_dir = locate_git_dir(manifest_dir)?;
// The common dir holds packed-refs + refs/heads when HEAD lives in a worktree
// gitdir. `commondir` is a one-line file (relative to `git_dir` or absolute).
let common_dir = match fs::read_to_string(git_dir.join("commondir")) {
Ok(rel) => {
let rel = rel.trim();
let p = PathBuf::from(rel);
if p.is_absolute() { p } else { git_dir.join(p) }
}
Err(_) => git_dir.clone(),
};
let head_path = git_dir.join("HEAD");
rerun_if_changed(&head_path);
let head = fs::read_to_string(&head_path).ok()?;
let head = head.trim();
if let Some(reference) = head.strip_prefix("ref:") {
let reference = reference.trim();
// Prefer a loose ref in the worktree gitdir, then the common dir, then
// packed-refs.
for base in [&git_dir, &common_dir] {
let loose = base.join(reference);
if let Ok(sha) = fs::read_to_string(&loose) {
rerun_if_changed(&loose);
let sha = sha.trim();
if !sha.is_empty() {
return Some(sha.to_string());
}
}
}
// packed-refs: lines of `<sha> <refname>`, skip `#` comments and `^` peels.
let packed = common_dir.join("packed-refs");
rerun_if_changed(&packed);
let packed = fs::read_to_string(&packed).ok()?;
for line in packed.lines() {
let line = line.trim();
if line.is_empty() || line.starts_with('#') || line.starts_with('^') {
continue;
}
if let Some((sha, name)) = line.split_once(' ') {
if name.trim() == reference {
return Some(sha.trim().to_string());
}
}
}
None
} else if is_hex_sha(head) {
// Detached HEAD — the raw commit sha.
Some(head.to_string())
} else {
None
}
}
/// Find the real git dir for `manifest_dir`. `.git` is normally a directory but is
/// a `gitdir: <path>` pointer file inside a worktree or submodule.
fn locate_git_dir(manifest_dir: &Path) -> Option<PathBuf> {
let dot_git = manifest_dir.join(".git");
let meta = fs::metadata(&dot_git).ok()?;
if meta.is_dir() {
return Some(dot_git);
}
if meta.is_file() {
let contents = fs::read_to_string(&dot_git).ok()?;
let rel = contents.trim().strip_prefix("gitdir:")?.trim();
let p = PathBuf::from(rel);
return Some(if p.is_absolute() {
p
} else {
manifest_dir.join(p)
});
}
None
}
fn is_hex_sha(s: &str) -> bool {
s.len() >= 7 && s.chars().all(|c| c.is_ascii_hexdigit())
}
fn rerun_if_changed(p: &Path) {
// Only meaningful for paths that exist; harmless otherwise (cargo just watches
// for it to appear).
println!("cargo:rerun-if-changed={}", p.display());
}