git-version

A Rust macro crate that embeds your Git tag, commit hash, and dirty state into your binary at compile time.

Library
Cargo
v0.3.9
132stars
BSD-2-Clause

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
34/100Needs Attention
Development Activity0
Maintenance0
Community56
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
78/100Good
Architecture78
Code Quality80
Innovation66
Learning Curve88

git-version provides procedural macros that capture your project’s Git version information — the current tag name, or the commit hash when no tag is present — and bake it directly into your compiled Rust program as a static string. If the working tree has uncommitted or untracked changes, the version gains a -modified suffix so release builds can flag dirty state.

The crate deliberately shells out to the installed git binary rather than linking libgit, keeping dependencies minimal at the cost of requiring git on the build machine’s PATH. It also exposes a macro to gather version strings for every submodule, which is useful for multi-repository builds and reproducible release tracking.

What You Get

  • A git_version! macro that yields a compile-time constant Git version string
  • Automatic -modified suffix when the working tree has uncommitted changes
  • A git_submodule_versions! macro for per-submodule version strings
  • Configurable arguments to customize the git describe invocation
  • Zero libgit dependency — it simply calls the git binary

Common Use Cases

  • Stamping release binaries with the exact Git tag or commit they were built from
  • Printing a —version output that reflects source provenance and dirty state
  • Tracking submodule revisions across a multi-repository build

Under The Hood

Architecture - The workspace splits into two crates: git-version (the public facade, git-version/src/lib.rs) re-exports the macros and documents usage, while git-version-macro holds the procedural-macro implementation that, at expansion time, spawns the git binary (via std::process::Command, running git describe and status checks) and emits the resulting string as a literal token. Because the work happens during macro expansion, the version is frozen into the compiled artifact with no runtime cost.

Tech Stack - Pure Rust (edition 2021), with git-version depending only on its sibling git-version-macro proc-macro crate; the macro crate uses the standard proc-macro toolchain. Dev-dependencies assert2 and tempfile support the tests. There is no libgit2 linkage — the crate relies on an external git executable in PATH.

Code Quality - Despite its small size (~16 KB of Rust), the crate carries integration tests under git-version/tests/version.rs that exercise real macro expansion, and a rustfmt.toml enforces formatting. The narrow scope keeps error paths simple, and the code is long-established with contributions from multiple maintainers.

API Design - The API is about as ergonomic as build-time versioning gets: const GIT_VERSION: &str = git_version!(); is the entire happy path, with optional named arguments for customizing the git invocation. The dirty-state suffix and submodule macro are discoverable from a short README, and there is essentially no boilerplate to get a working version string.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search