From 580135241b9618fdce6f4acca390e41d14e4b937 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Tue, 30 Jun 2026 21:30:30 -0400 Subject: [PATCH] build: update how changing the currently checked out commit is detected Add support for building from a git worktree. Previously, the compiler configure script was only rerun on changing which branch is currently checked out. Now, any changes to the `HEAD` reflog will be detected, which, happens to contain the commit hash of the currently checked out commit on the last line, so will necessarily have unique contents for any given commit. While there could be false negatives due to the reflog being cleaned after a couple months, this is not only unlikely to actually occur, involving a specific series of steps over the course of a third of a year, the end result is that the compiled compiler reports the wrong version, and can easily be fixed by simply e.g. changing to another commit and back, something which developers already frequently do. Additionally, the alternative of having to hash longer and longer reflogs to detect a change on the last line would hardly be preferable. --- build.zig | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/build.zig b/build.zig index c98dcc649ca0773a12490c2d43dddc1ff344b873..03774ca9ac707c2c01d8c8d7815aa0aa1cb4bbfd 100644 --- a/build.zig +++ b/build.zig @@ -268,7 +268,29 @@ pub fn build(b: *std.Build) !void { } // Ensure git version changes get picked up. - b.dependOnFileContents(b.path(".git/HEAD")); + git: { + const io = b.graph.io; + const git_file = b.root.openFile(io, ".git", .{ .allow_directory = false }) catch |err| switch (err) { + error.IsDir => { + b.dependOnFileContents(b.path(".git/logs/HEAD")); + break :git; + }, + else => |e| return e, + }; + defer git_file.close(io); + var line_buffer: ["gitdir: ".len + std.Io.Dir.max_path_bytes + 1]u8 = undefined; + var git_file_reader = git_file.reader(io, &line_buffer); + if (std.mem.cutPrefix(u8, std.mem.trimEnd(u8, try git_file_reader.interface.allocRemaining( + arena, + .limited("gitdir: ".len + std.Io.Dir.max_path_bytes + "\r\n".len), + ), "\r\n"), "gitdir: ")) |git_dir| { + const head_file = b.pathJoin(&.{ git_dir, "logs", "HEAD" }); + b.dependOnFileContents(if (std.Io.Dir.path.isAbsolute(head_file)) + b.graph.cwdRelativePath(head_file) + else + b.path(head_file)); + } + } const version_string = b.fmt("{d}.{d}.{d}", .{ zig_version.major, zig_version.minor, zig_version.patch }); -- 2.54.0