use std::fs; use std::path::PathBuf; #[derive(Debug, Clone, PartialEq, Eq)] pub struct GitVersion { pub branch: String, pub commit: String, } pub fn get_git_version(git_path: &PathBuf) -> Result { let head_path = git_path.join(".git/HEAD"); // Read HEAD file let head_content = fs::read_to_string(&head_path) .map_err(|e| format!("Failed to read .git/HEAD: {}", e))?; let head_content = head_content.trim(); // Check if HEAD points to a ref if head_content.starts_with("ref:") { let ref_path = head_content.strip_prefix("ref:").unwrap().trim(); let full_ref_path = git_path.join(".git").join(ref_path); // Read the ref file to get the commit hash let commit_hash = fs::read_to_string(&full_ref_path) .map_err(|e| format!("Failed to read ref file: {}", e))? .trim() .to_string(); // Extract branch name from ref path let branch = ref_path .strip_prefix("refs/heads/") .unwrap_or(ref_path) .to_string(); Ok(GitVersion { branch, commit: commit_hash, }) } else { // Detached HEAD state - just use the commit hash Ok(GitVersion { branch: "detached".to_string(), commit: head_content.to_string(), }) } } #[cfg(test)] mod tests { use super::*; #[test] fn test_git_version() { // This test will only work if run in a git repository if let Ok(version) = get_git_version(".") { assert!(!version.commit.is_empty()); assert!(!version.branch.is_empty()); } } }