Ghext: independent git HEAD extractor

Ghext is a small library that pulls HEAD hashes from git repositories. Deploy it as a regular library or use it within build.zig.

libgit2 or its bindings would be a heavy dependency. This library is light and capable of delivering even without git installed (MO builds, very edgy cases, etc.).

I wanted to see if I could drop heap allocations before the upcoming release, but after figuring out the build system usage, it became less relevant, so probably later.

build.zig:

const build_options = b.addOptions();

exe.root_module.addOptions("build_options", build_options);
build_options.addOption([]const u8, "head_hash", try hash());

inline fn hash() ![]const u8 {
    const gxt = @import("ghext").Ghext.read(std.heap.page_allocator) catch unreachable;
    return gxt.hash;
}

app.zig:

const build_options = @import("build_options");
const hash = build_options.head_hash[0..7];

Any feedback is appreciated!
Cheers!!

2 Likes

[0.6.0] - 2025-05-28

Documentation

  • Update installation
  • Update usage
  • Update returned value

Features

  • [breaking] Improve hash getter

Refactor

  • Move validation subroutine

[0.7.0] - 2025-05-30

Bug Fixes

  • Use BoundedArray
  • Improve error handling

Documentation

  • Update installation
  • Update app usage
  • Update build usage
  • Drop standard usage
  • Comment HashLen
  • Update example
  • Fix manifest example

Features

  • [breaking] Add state
  • Expose PATH
  • Add GIT switch

Refactor

  • Optimize hash()

Styling

  • Move deinit()

Testing

  • Add hash_dirty
  • Fix ghx.state definitions
  • Rename cases

Build

  • Update paths

Switched to support build.zig exclusively, improved logic, and added couple variables to support edge cases.

[0.7.1] - 2025-06-01

Bug Fixes

  • Deallocate on errors
  • Improve head detection
  • Handle trailing slash

Documentation

  • Update installation

Miscellaneous tasks

  • Ignore test files

Refactor

  • Move deallocations

Styling

  • Fix test formatting
  • Reformat readWithoutGit()

Testing

  • Add headless
  • Add branch
  • Add hash invalid
  • Optimize errors
  • Expand cases
  • Move head files
  • Add testDir()
  • Add empty path
2 Likes

My git-foo is quite weak, nor do I work on a large codebase that requires knowledge on more than a handful of git commands, so forgive my ignorance, but what is the use-case of this?

No worries! Sometimes, developers choose to include a commit hash in the version string (xtxf version 0.11.1 7f6ebb3-dirty). This highlights to the user what exactly was built during the shipping (dirty indicates uncommitted changes, which might be a red flag in production). In testing/reporting, it helps the developers to trace bugs/etc. since that way you can narrow down what commit(s) could be the root of the issue (especially helpful for dev/nightly builds).

In packaging, this could be used to validate the authenticity of the binary.

The reason I wrote it is that I feel that using a full-featured library just for this is an overkill.

1 Like

[0.7.2] - 2025-06-04

Bug Fixes

  • Adjust array size

Documentation

  • Update installation

Refactor

  • Rename functions

Testing

  • Add hash long 256 (checked)

Build

  • Update zon file

0.7.6

Bug Fixes

  • Switch to std.Io

Operations

  • Bump actions/upload-pages-artifact from 4 to 5
  • Bump zig to 0.16