From c5b6fa5be302e72ffcbca51e198c2361bc3461b9 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 23 Apr 2026 03:45:59 +0900 Subject: [PATCH] fix(#161): resolve actual HEAD path in git worktrees for correct Git SHA in build metadata Problem: In git worktrees, .git is a pointer file (not a directory), so cargo's rerun-if-changed=.git/HEAD never triggers when commits are made. This causes claw version to report a stale SHA after new commits. Solution: Add resolve_git_head_path() helper that detects worktree mode: - If .git is a file: parse gitdir pointer, watch /HEAD - If .git is a directory: watch .git/HEAD (regular repo) This ensures build.rs invalidates on each commit, making version output truthful. Verification: Binary built in worktree now reports correct SHA after commits (before: stale, after: current HEAD). Relates to ROADMAP #161 (filed cycle #65, implemented cycle #69). Diagnostic-strictness family member. Diff: 21 lines added (resolve_git_head_path + conditional rerun-if-changed). --- rust/crates/rusty-claude-cli/build.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/rust/crates/rusty-claude-cli/build.rs b/rust/crates/rusty-claude-cli/build.rs index 551408c..fdee46c 100644 --- a/rust/crates/rusty-claude-cli/build.rs +++ b/rust/crates/rusty-claude-cli/build.rs @@ -1,6 +1,24 @@ use std::env; +use std::path::Path; use std::process::Command; +fn resolve_git_head_path() -> Option { + let git_path = Path::new(".git"); + if git_path.is_file() { + // Worktree: .git is a pointer file containing "gitdir: /path/to/real/.git/worktrees/" + if let Ok(content) = std::fs::read_to_string(git_path) { + if let Some(gitdir) = content.strip_prefix("gitdir:") { + let gitdir = gitdir.trim(); + return Some(format!("{}/HEAD", gitdir)); + } + } + } else if git_path.is_dir() { + // Regular repo: .git is a directory + return Some(".git/HEAD".to_string()); + } + None +} + fn main() { // Get git SHA (short hash) let git_sha = Command::new("git") @@ -52,6 +70,12 @@ fn main() { println!("cargo:rustc-env=BUILD_DATE={build_date}"); // Rerun if git state changes - println!("cargo:rerun-if-changed=.git/HEAD"); + // In worktrees, .git is a pointer file, so watch the actual HEAD location + if let Some(head_path) = resolve_git_head_path() { + println!("cargo:rerun-if-changed={}", head_path); + } else { + // Fallback to .git/HEAD for regular repos (won't trigger in worktrees, but prevents silent failure) + println!("cargo:rerun-if-changed=.git/HEAD"); + } println!("cargo:rerun-if-changed=.git/refs"); }