banner
davirain

davirain

twitter
github
知乎
twitter

How to access the submitted git commit in a Rust program

Code example#

use std::{borrow::Cow, process::Command};

fn main() {
	// Make git hash available via GIT_HASH build-time env var:
	output_git_short_hash();
}

fn output_git_short_hash() {
	let output = Command::new("git").args(["rev-parse", "HEAD"]).output();

	let git_hash = match output {
		Ok(o) if o.status.success() => {
			let sha = String::from_utf8_lossy(&o.stdout).trim().to_owned();
			Cow::from(sha)
		},
		Ok(o) => {
			println!("cargo:warning=Git command failed with status: {}", o.status);
			Cow::from("unknown")
		},
		Err(err) => {
			println!("cargo:warning=Failed to execute git command: {}", err);
			Cow::from("unknown")
		},
	};

	println!("cargo:rustc-env=GIT_HASH={}", git_hash);
	println!("cargo:rerun-if-changed=../.git/HEAD");
	println!("cargo:rerun-if-changed=../.git/refs");
	println!("cargo:rerun-if-changed=build.rs");
}

Code Explanation#

The purpose of this code is to use the Rust std::process::Command module to execute a Git command, retrieve the Git hash of the current code repository, and set it as the value of the GIT_HASH environment variable. This code is implemented by creating a build.rs file in the root directory of a Rust project.

Here's how this code works:

  1. In the build.rs file, a function output_git_short_hash() is defined. It uses the Rust std::process::Command module to execute a Git command and assigns the result to the output variable.
  2. If the Git command is executed successfully, the function retrieves the Git hash from output.stdout and stores it in the git_hash variable.
    Cow is a string type in Rust that allows runtime determination of whether to use String or &str to represent the string.
  3. If the Git command fails to execute, the function outputs a warning message and sets git_hash to "unknown".
  4. Finally, the function sets the GIT_HASH environment variable to the value of git_hash and uses the cargo:rerun-if-changed directive to inform Cargo when to rerun the build script.
    In this example, Cargo will rerun the build script when ../.git/HEAD, ../.git/refs, or build.rs files are changed.
  5. In main.rs or other Rust files, you can access the GIT_HASH environment variable and retrieve the Git hash using std::env::var("GIT_HASH").

In summary, this code allows you to retrieve the Git hash of a Rust project by executing a Git command and set it as an environment variable for easy access by other Rust files.

In the fourth step, the cargo:rerun-if-changed directive is used to inform Cargo when to rerun the build script.
This directive is a special comment provided by Cargo, the Rust compiler, to control the build and rebuild behavior of a project.

Specifically, the cargo:rerun-if-changed directive tells Cargo that changes to certain files will require the project to be rebuilt, allowing Cargo to automatically rerun the build script when these files change. The syntax of the directive is as follows:

cargo:rerun-if-changed=<filename>;

where <filename> represents the name or path of the file to monitor, which can be a relative or absolute path.

In this example, the cargo:rerun-if-changed directive tells Cargo to rerun the build script when:

  • The ../.git/HEAD file changes.
  • Any file in the ../.git/refs folder changes.
  • The build.rs file changes.
  • These file changes typically indicate changes to the Git code repository, requiring the retrieval of the Git hash and recompilation of the project.

Note that the cargo:rerun-if-changed directive can only be used in the build.rs file and must be on a separate line, not mixed with other code. This is because the directive is actually a comment, not Rust code, and cannot be included within functions, structs, or other Rust language constructs.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.