如何在Rust项目中获取和显示Git版本信息

在Rust项目中,如何获取当前代码的Git版本信息(如commit hash、分支名称或标签)并在程序运行时显示?最好能通过Cargo构建时自动获取这些信息,而不是手动维护。有没有现成的crate可以简化这个过程?需要确保在非Git目录下运行时也能正常处理。

2 回复

在Cargo.toml中添加build-dependencies

[build-dependencies]
vergen = "7"

创建build.rs

use vergen::EmitBuilder;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    EmitBuilder::builder()
        .git_sha(false)
        .git_describe(true, true, None)
        .emit()?;
    Ok(())
}

在main.rs中使用:

fn main() {
    println!("Version: {}", env!("VERGEN_GIT_DESCRIBE"));
}

在Rust项目中获取和显示Git版本信息,可以通过以下方法实现:

方法一:使用built crate(推荐)

  1. Cargo.toml中添加依赖:
[dependencies]
built = "0.7"
  1. 创建build.rs文件:
// build.rs
fn main() {
    built::write_built_file().expect("Failed to acquire build-time information");
}
  1. 在main.rs中使用:
use std::path::Path;

fn main() {
    // 获取构建信息
    let built = built::Built::new().unwrap();
    
    println!("Git版本: {:?}", built.git_version());
    println!("Git提交哈希: {:?}", built.git_commit_hash());
    println!("Git提交日期: {:?}", built.git_commit_date());
    println!("Git是否干净: {:?}", built.git_dirty());
    println!("Git HEAD: {:?}", built.git_head());
}

方法二:手动处理Git信息

build.rs中:

// build.rs
use std::process::Command;

fn main() {
    // 获取Git提交哈希
    if let Ok(output) = Command::new("git").args(&["rev-parse", "HEAD"]).output() {
        if output.status.success() {
            let hash = String::from_utf8(output.stdout).unwrap();
            println!("cargo:rustc-env=GIT_HASH={}", hash.trim());
        }
    }

    // 获取Git描述
    if let Ok(output) = Command::new("git").args(&["describe", "--always", "--dirty"]).output() {
        if output.status.success() {
            let describe = String::from_utf8(output.stdout).unwrap();
            println!("cargo:rustc-env=GIT_DESCRIBE={}", describe.trim());
        }
    }
}

在main.rs中:

fn main() {
    println!("Git哈希: {}", env!("GIT_HASH"));
    println!("Git描述: {}", env!("GIT_DESCRIBE"));
}

方法三:使用vergen crate

[dependencies]
vergen = "8.0"
use vergen::EmitBuilder;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    EmitBuilder::builder()
        .git_sha(true)
        .git_commit_date()
        .git_describe(true, true, None)
        .emit()?;
    
    println!("Git SHA: {}", env!("VERGEN_GIT_SHA"));
    println!("提交日期: {}", env!("VERGEN_GIT_COMMIT_DATE"));
    println!("Git描述: {}", env!("VERGEN_GIT_DESCRIBE"));
    
    Ok(())
}

推荐使用方法一,它提供了最完整的Git信息且使用简单。这些信息在编译时获取,运行时直接读取,不会影响程序性能。

回到顶部