如何获取Git构建号并将其嵌入文件中?

17

我想介绍一种从Git版本中提取版本常量的方法。我知道如何在svn中以非常hackish的方式实现这一点,

您有什么关于如何在Git中实现此功能的想法吗?


你想把它嵌入像 $Id$ 这样的文件中吗?那不是很实用。如果你只是想描述一个完整的构建,可以使用 git describe - Daenyth
是的,我确实想做类似的事情,甚至可能写一个文件version.log,我可以解析它。 - qodeninja
类似于$ID$ - 抱歉,我需要在我的PHP代码中重复使用该构建号。 - qodeninja
Git不是一个缩写,它只是"Git",而不是"GIT"。 - user229044
6个回答

10

对我来说,git describe 最初没有给出哈希标识。然而以下命令可以:

git describe --all --long

这会产生类似于kubi描述的格式。假设你只想要最后一部分(hashtag),那么以下代码可以实现(保存到version.txt文件中):

git describe --all --long | tr "-" " " | awk '{ print $3 }' > version.txt

编辑:正如一位朋友指出的,如果你希望这样做的话,实际上可以仅使用cut来完成:

git describe --all --long | cut -d "-" -f 3 > version.txt

这实际上更接近我想要的东西。现在我只需要找到一种将其嵌入文件中的方法。我想在代码中引用构建 ID。 - qodeninja
1
这似乎是一个不同的问题,但绝对可行。在PHP中:$git_version = file_get_contents("version.txt"); - 现在$git_version包含哈希值 :) - Niels Abildgaard

7

以下是我的工作内容:

在我的构建过程中,我运行以下脚本(因为我现在不在Xcode上,所以这里是改编的)

git describe --all > version.txt

在我的应用程序中,我从这个文件中读取版本号并在必要时向用户显示它。确保将version.txt添加到.gitignore中。以这种方式做的好处是,如果您标记了您的发布 git describe 就会输出标签,否则它会输出提交哈希。


5
这让我得到了分支名称,但没有版本号。 - qodeninja
2
它将会给你<最后可达标签>-<自标签以来的提交数>-<8位哈希值>。 - kubi
1
@kubi 不是。它是带有前缀“g”的7位数字哈希值。 - Genghis Khan
对我来说,这是git describe命令(不带--all选项)(我正在使用1.9.5.msysgit.0版本)。 - lib

4

注意:有趣的是看到Git本身如何计算自己的构建号。
这仅在Git 2.12(2017年第一季度)中演变出来。

请参见提交 a765974 (由 Ramsay Jones(``)于2016年12月4日提交)。
协助者:Jeff King(peff
(由Junio C Hamano -- gitster --合并于提交0a45050,2016年12月19日)

GIT-VERSION-GEN 

VN=$(git describe --match "v[0-9]*" HEAD 2>/dev/null) 
# instead of
VN=$(git describe --match "v[0-9]*" --abbrev=7 HEAD 2>/dev/null)

GIT-VERSION-GEN:不要强制使用 'describe' 的缩写长度

Git 二进制文件的默认版本名称是通过在构建二进制文件所用的提交上运行 "git describe" 命令来计算的,基于一个标签,其名称与 "v[0-9]*" 匹配,例如 v2.11.0-rc2-2-g7f1dc9

在早期的时候,9b88fce ("Makefile: use git-describe to mark the git version.", 2005-12-27),我们使用 "--abbrev=4" 来获取最小化的简写提交对象名称。
之后,在 bf50515 ("Git 1.7.10.1", 2012-05-01) 中,这被更改为匹配默认的最小值 7 个字符。

现在,“默认最小值”会根据代码库的大小自动进行调整,指定特定的简写长度没有意义;自 Git 1.7.10.1 以来,我们想要的只是“默认情况下使用合理的值”。

这是在Git 2.11中引入的:请参见“通常认为在给定代码库中唯一标识更改所需的git sha的数量有多少?”的最后一部分。只需从“git describe”的调用中删除“--abbrev=<number>”,让命令选择它认为合适的内容,考虑最终用户的配置和存储库内容。

3
为了在php中获取Git版本,我使用类似以下的代码(将路径更改为.Git目录):
public static function getGitRevision()
     {
         $rev = trim(file_get_contents(NT_Path::ROOT . "/.git/HEAD"));

         if (substr($rev, 0, 4) == 'ref:') {
             $ref =  end(explode('/', $rev));
             $rev = trim(file_get_contents(NT_Path::ROOT . "/.git/refs/heads/{$ref}"));
         }

         return $rev;
     }

0
这是我完成它的方式。注意:获取修订版本的Python代码来自this帖子。

BuildInfo.hpp

#ifndef BUILDINFO_HPP_
#define BUILDINFO_HPP_

struct BuildInfo
{
    static const char Name[];
    static const char GitRevision[];
};

#endif

(自动生成)BuildInfo.cpp

#include "BuildInfo.hpp"

const char BuildInfo::Name[] = "MyAppNAme";
const char BuildInfo::GitRevision[] = "5e854351b342acff6a3481d9106076df379c449a";

GenerateBuildInfo.py。这是一个用于生成 BuildInfo.cpp 的 Python 脚本。需要注意的是,它可以轻松地适应短或长的版本号或其他仓库信息。它还可以转换为生成 C 代码而不是 CPP,因此与两者兼容。
import sys
import os
import subprocess

#args: [0]: this script path [1]: Output file name [2]: Application name string

# Return the git revision as a string
def git_version():
    def _minimal_ext_cmd(cmd):
        # construct minimal environment
        env = {}
        for k in ['SYSTEMROOT', 'PATH']:
            v = os.environ.get(k)
            if v is not None:
                env[k] = v
        # LANGUAGE is used on win32
        env['LANGUAGE'] = 'C'
        env['LANG'] = 'C'
        env['LC_ALL'] = 'C'
        out = subprocess.Popen(cmd, stdout = subprocess.PIPE, env=env).communicate()[0]
        return out

    try:
        out = _minimal_ext_cmd(['git', 'rev-parse', 'HEAD'])
        GIT_REVISION = out.strip().decode('ascii')
    except OSError:
        GIT_REVISION = "Unknown"

    return GIT_REVISION

if len(sys.argv) < 2 :
    exit("No output file name argument provided")
elif len(sys.argv) >= 3 :
    name = sys.argv[2]
else :
    name = ""

revision = git_version()
if (revision == "Unknown") :
    exit("Cant get git revision")

with open(sys.argv[1], "w") as f :
    f.write('#include "BuildInfo.hpp"\r\n\r\n')
    f.write('const char BuildInfo::Name[] = "' + name + '";\r\n')
    f.write('const char BuildInfo::GitRevision[] = "' + revision + '";\r\n')
    f.close()

使用构建信息

#include "BuildInfo.hpp"
...
PrintRevision(BuildInfo::GitRevision);

为了生成 BuildInfo.cpp,在构建后的步骤中我调用以下命令(在本例中是从 Eclipse IDE 中调用):
python ${ProjDirPath}/build/GenerateBuildInfo.py ${ProjDirPath}/src/BuildInfo.cpp ${ProjName}

0

不要把它放在文本文件中,然后每次获取其内容,这似乎非常有效:

sed -i.bak "s/$version = '.*';/$version = '`git rev-parse --short HEAD | tr -d '\n'`';/g" version.php

version.php文件的内容如下:

<?php
$version = 'some version string';

然后,只需像包含设置文件一样,在脚本中包含该文件。

如果你愿意,你也可以使用git describe --all --long作为版本字符串,对于我的目的,我更喜欢使用git-ref-parse --short HEAD生成的git哈希值。

或者作为一个常量可能更好:

sed -i.bak "s/define('VERSION','.*');/define('VERSION','`git describe --all --long | cut -d "-" -f 3`');/g" version.php

以及 version.php:

<?php
define('VERSION','some version string');

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接