Repository navigation
fix(build): re-stamp the commit when HEAD moves - #15
Merged
Merged
Conversation
`build.rs` declared only `rerun-if-changed=build.rs`, so Cargo reused the previous run's values whenever this file was unchanged. Any commit that did not touch it produced a binary stamped with an earlier commit, and the self-contract freshness check then compared against a value that had never been current. The header claimed the opposite — that a binary keeps reporting the commit it was built from. That held only until the next commit. Observed in practice: a `cargo install --path .` from a freshly merged `main` compiled the new source and still reported the previous commit, with `clean` beside it. Declare the files that decide `rev-parse HEAD` instead: `HEAD`, the branch ref it names, and `packed-refs`. Paths come from `git rev-parse --git-path`, so linked worktrees and submodules resolve rather than assuming `.git/`. Moving HEAD now re-runs this script, so switching branches relinks on the next build. That is the price of an accurate stamp: the commit cannot be re-read without re-running the reader. `LEIO_BUILD_DIRTY` is still only as fresh as the last run — no trigger can express "any tracked file differs from HEAD" — and the header now says so rather than implying the stamp is wholly self-maintaining. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug
build.rsbakes the source revision into the binary so staleness is detectable. Its header says a binary "keeps reporting the commit it was actually built from."It declared only
cargo:rerun-if-changed=build.rs, so Cargo reused the previous run's values whenever that file was unchanged. Any commit that didn't touchbuild.rsproduced a binary stamped with an earlier commit, and the self-contract freshness check then compared against a value that had never been current.The header described this as deliberate — no
.gittriggers, so branch switches never force a rebuild. But the consequence isn't limited to branch switches: the stamp refreshes only whenbuild.rsitself is edited, which is almost never.Observed:
cargo install --path .from a freshly mergedmaincompiled the new source and still reported the previous commit, withcleanbeside it.The fix
Declare the files that actually determine
git rev-parse HEAD:HEADsymbolic-ref --quiet, silent on a detached HEAD)packed-refs, since a packed ref has no loose filePaths come from
git rev-parse --git-path, so linked worktrees and submodules — where.gitis a file, not a directory — resolve rather than assuming.git/. Outside a git checkout every lookup returnsNone, nothing is emitted, and the stamp staysunknown.Cost, accepted deliberately
Moving HEAD now re-runs the script, so switching branches relinks on the next build. An accurate stamp isn't available more cheaply: the commit can't be re-read without re-running the reader. A stamp that is usually wrong seems worse than an occasional relink.
Known limit, documented not fixed
LEIO_BUILD_DIRTYis still only as fresh as the last run. Norerun-if-changedcan express "any tracked file differs from HEAD", so editing a source file flips the real dirty state without re-stamping. The header now sayscleanmeans "clean when last stamped", rather than implying the stamp is self-maintaining. The commit is the load-bearing half.Verification
Empty commit touching no files at all, then a rebuild — the case the old code could not handle:
Under the old
build.rsthe stamp would not have moved.cargo fmtandcargo clippy --all-targetsclean.🤖 Generated with Claude Code