代码之家  ›  专栏  ›  技术社区  ›  Harry

如何在编译时获取克隆的git仓库的标签

  •  0
  • Harry  · 技术社区  · 4 月前

    我克隆了一个远程git仓库,并从中创建了一个新的分支 main 支。现在我想在编译时获取最新的repo标签(如果存在)。我能够在编译时获得最新的提交哈希。下面是我的代码

    // build.rs
    use std::process::Command;
    fn main() {
        let output = Command::new("git").args(&["rev-parse", "HEAD"]).output().unwrap();
        let git_hash = String::from_utf8(output.stdout).unwrap();
        println!("cargo:rustc-env=GIT_HASH={}", git_hash);
    }
    
    // main.rs
    fn main() {
        println!("{}", env!("GIT_HASH"));
    }
    
    2 回复  |  直到 4 月前
        1
  •  1
  •   frankenapps    4 月前

    我将使用以下命令获取 最新的 (以您想定义的任何方式)标签: git describe --tags --abbrev=0 (使用 git describe ).

    因此,这将是我的解决方案:

    build.rs

    use std::{path::Path, process::Command};
    fn main() {
        // Check if the tags changed.
        if Path::new(".git/refs/tags").exists() {
            println!("cargo:rerun-if-changed=.git/refs/tags");
        }  
    
        if Path::new(".git/packed-refs").exists() {
            println!("cargo:rerun-if-changed=.git/packed-refs");
        }  
    
        // Get the "latest" tag and store its name in the GIT_TAG environment variable.
        let output = Command::new("git").args(&["describe", "--tags", "--abbrev=0"]).output().unwrap();
        let git_tag = String::from_utf8(output.stdout).unwrap();
        println!("cargo:rustc-env=GIT_TAG={}", git_tag);
    }
    

    main.rs

    fn main() {
        println!("{}", env!("GIT_TAG"));
    }
    

    这个想法是,每当系统上与git标签相关的文件发生变化时,都会运行构建脚本。

    请注意,如果您有两个标签指向同一个提交,这将导致问题。

    根据您喜欢的shell,可能有更好的选择,但这似乎是最好的跨平台命令。

        2
  •  1
  •   vht981230    4 月前

    如果您使用的是远程存储库,则应使用以下命令从远程存储库中提取标签 git fetch --tags 然后使用 git rev-list --tags <latest commit hash> 获取最新提交的标签

    // git fetch --tags : fetch latest tag from remote repository
    Command::new("git").args(&["fetch", "--tags"]).output()
    
    // git describe --tags "$(git rev-list --tags --max-count=1)" : get latest tag name
    let revlist_output = Command::new("git").args(&["rev-list", "--tags", "--max-count=1"]).output().unwrap();
    let git_hash = String::from_utf8(revlist_output.stdout).unwrap();
    git_hash.pop();
    let describe_output = Command::new("git").args(&["describe", "--tags", git_hash]).output().unwrap();
    let tag_name = String::from_utf8(describe_output.stdout).unwrap();