Skip to content

apr --version: build.rs doesn't pick up HEAD changes in worktrees without source-file modification #1862

@noahgift

Description

@noahgift

Symptom

In a git worktree, when HEAD moves (e.g. after git pull or branch reset) but no .rs source files change, cargo install --path crates/apr-cli reuses the cached binary and apr --version reports the stale commit hash.

Reproducer (in any aprender worktree)

git worktree add -b release/v0.35.0 /tmp/rel origin/main  # HEAD = 0d8d52b25
cd /tmp/rel
cargo install --path crates/apr-cli --force --features cuda
apr --version  # may report a stale hash from a previous build

Workaround

touch crates/apr-cli/build.rs && cargo install --path crates/apr-cli --force picks up the right hash.

Root cause

crates/apr-cli/build.rs:13-17 declares:

let git_head = std::path::Path::new("../../.git/HEAD");
if git_head.exists() {
    println!("cargo:rerun-if-changed=../../.git/HEAD");
    println!("cargo:rerun-if-changed=../../.git/refs/heads/");
}

In a worktree, ../../.git is a file (a gitdir: <path> pointer), not a directory. So ../../.git/HEAD does NOT exist as a path, the rerun-if-changed directives are not emitted, and build.rs is skipped on subsequent builds even when HEAD moves.

Fix sketch

Resolve the real git directory before declaring rerun-if-changed:

  1. git rev-parse --git-dir -> e.g. /home/x/src/foo/.git/worktrees/rel
  2. Watch <git-dir>/HEAD directly (works for primary checkout and worktrees)

Severity

Low — dev ergonomics only. Not a release blocker:

  • crates.io installs use the committed .git-sha fallback (build.rs path Feature Request: Model Serialization (Save/Load) #3), unaffected.
  • Release-tag builds via make publish run on a fresh checkout with no caching, unaffected.
  • Falsifier contract: apr-version-traceability-v1 F-VERSION-001.

Surfaced by

Release dogfood for v0.35.0 (2026-05-22) in worktree /tmp/aprender-release-v0.35.0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions