从`git describe`派生应用程序构建版本 - 如何获得相对简单的字符串?

时间:2010-07-21 15:06:01

标签: git versioning auto-versioning

更新

我看到这个问题有点流行了。现在已经是我公认的Git使用年限了,从那以后我学到了很多东西。 非常请阅读最后一段,然后再继续了解您在本Q& A中学到的任何Git冒险。


我想编写应用程序构建版本,该版本是从我所在的GIT分支名称(构建时)和自分支分歧后的提交数量自动派生的。我相信这对我的GIT存储库中的任何提交都是唯一的吗?分支名称是唯一的,并且提交沿着分支相互链接?如果我标记提交,我也可以使用该标记作为前缀。

在某种程度上git describe做我想要的,但它不包括我所在的分支名称,它包括缩写的提交SHA-1哈希,我认为我不需要它,因为它没有在字符串的熵中添加任何东西并且可能是多余的(我可能在这里错了,所以请纠正我)。

我有什么选择?我在这里想的是正确的方向吗?当我有更多关于软件开发的重要事项时,我只是厌倦了为版本添加数字。

顺便说一句,我从不用肮脏的工作树建造。即在构建公开发布版之前,我总是将更改提交到存储库。

我现在知道 Git分支只是提交引用,因此,许多分支(和标记!)可能指向单个提交。因此,问题“这个提交属于哪个分支/谎言”对于Git来说不是完全有效。 Git 跟踪你所在的“当前”分支 - 它已经为你检查过 - 但同时任何数量的其他分支可能指向同一个提交并且可以说是除非您想要表示当前已检出磁盘的分支,否则不能选择单个分支作为“主”。请阅读following answer on this page进行详细说明。

4 个答案:

答案 0 :(得分:10)

答案 1 :(得分:9)

关于git你要了解的是分支本质上只是提交书签。当你进行foo提交时,你在0deadbeef分支上的事实对于提交本身并不重要;分支不是其身份的一部分。

(Mercurial将分支名称烘焙到提交。In a variety of ways, this is inferior, as Dustin Sallings explains。)

即使假设git describe只使用当前签出的分支 - 如果你有一个古怪的历史,可能会有多条路径导致git describe将使用的同一个最近的标记提交。所以甚至没有任何一个分支。

另一个注意事项:您可能会反对即使“标记X中的第3次提交”在一般情况下不明确,git describe也可以查看图表并确定是否暧昧,如果没有,请忽略哈希。但是,没有什么可以阻止任何人稍后在该标记的顶部开始分支 - 那么你的describe字符串会变得模糊不清追溯

一句话是,提交的唯一明确标识符是其哈希值。所以那必须在那里。 git describe所做的是添加一些冗余(并且在提交编号的情况下,含糊不清)信息使得描述对于人类自我定位的空间/关系理解更有用,在Git模型的范围内。

答案 2 :(得分:5)

正式版本应该有一个带有版本号的标签。 在这种情况下,我建议采用以下方法:

  1. 如果当前提交有标记,请使用该标记
  2. 如果没有可用的标记,请使用分支名称和SHA1密钥
  3. 这个单一命令应该有效:

    git describe --exact-match 2> /dev/null || echo "`git symbolic-ref HEAD 2> /dev/null | cut -b 12-`-`git log --pretty=format:\"%h\" -1`"
    

答案 3 :(得分:4)

git describe --long将始终输出如下版本号: v1.2-10-gdeadbee ,这意味着自带注释的标记'v1.2'后第10次提交指向缩短SHA-1'死区'的提交。因此,您所要做的就是标记分支开始(分支的分支点),例如<branch>-start

需要使用缩写的提交SHA-1哈希来区分不明确的情况,因为“第3次提交,因为标记'x'”(例如)不能唯一地区分提交;在存在非线性,分支开发的情况下,可以存在多个适合所述描述的提交。例如,在下面的ASCII-art图中显示的情况下,标记为*的提交都适用于“自标记'x'”描述以来的第3次提交。

          /-.---*---.-\                   
         /             \                  
.---x---.---.---*---.---M---.    <--- branch

请注意,在上面显示的“merged in”情况下,您不能使用分支名称来区分具有相同描述的两个提交。

所以你需要做的就是取git describe --long输出(--long选项在这里是为了避免解析时出现歧义,请参阅git describe manpage),解析它,并添加当前分支信息(来自例如git symbolic-ref HEAD来自pasing git branch输出)。