简体   繁体   English

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

[英]Deriving application build version from `git describe` - how to get a relatively straightforward string?

UPDATE UPDATE

I see that this question has become somewhat popular. 我看到这个问题已经变得有点流行了。 It's now years into my admittedly enjoyable Git use, and I have learned a lot since then. 现在已经是我公认的Git使用年限了,从那以后我学到了很多东西。 Please , pretty please read the last paragraph before going on about your Git adventures with whatever you will have learned from this Q&A. 拜托拜托之前,不管你会从这个Q&A得知事情对你的Git冒险阅读最后一段。


I want to compose application build version that is automatically derived from GIT branch name I am on (when building) and the number of commits since the branch has diverged. 我想编写应用程序构建版本,该版本是从我所在的GIT分支名称(构建时)和自分支分歧后的提交数量自动派生的。 I believe this will be unique for any commit in my GIT repository? 我相信这对我的GIT存储库中的任何提交都是唯一的吗? Branch names are unique, and commits are linked to each other along a branch? 分支名称是唯一的,并且提交沿着分支相互链接? If and when I tag a commit, I can also have the version be prefixed with that tag. 如果我标记提交,我也可以使用该标记作为前缀。

In a way git describe does what I want, but it does not include the branch name I am on, and it includes abbreviated commit SHA-1 hash, which I don't think I need as it does not add anything to the entropy of the string and may be redundant (I may be wrong here, so please correct me). 在某种程度上git describe做我想要的,但它不包括我所在的分支名称,它包括缩写的提交SHA-1哈希,我认为我不需要它,因为它不会添加任何东西到熵字符串,可能是多余的(我可能在这里错了,所以请纠正我)。

What are my options? 我有什么选择? And am I thinking in the right direction here at all? 我在这里想的是正确的方向吗? I am just a bit tired of appending numbers to versions when I have more important things to deal with with regards to software development. 当我有更多关于软件开发的重要事项时,我只是厌倦了为版本添加数字。

I never build with a dirty working tree, by the way. 顺便说一下,我永远不会用肮脏的工作树建造。 Ie I always commit changes to the repository before building a public release. 即我在构建公共发布之前总是将更改提交到存储库。

I am now aware that Git branches are just commit references, and so, many branches (and tags!) may point to a single commit. 我现在知道 Git分支只是提交引用,因此,许多分支(和标记!)可能指向单个提交。 Therefore, the question "which branch does this commit belong to / lie on" is not entirely valid with Git. 因此,问题“这个提交属于哪个分支/谎言”对Git来说并不完全有效。 Git does track a "current" branch you're on -- the one it has checked out for you -- but at the same time any number of other branches may be pointing to the same commit and arguably no single branch can be chosen as "main" unless you want to mean the one currently checked out to disk. Git 跟踪你正在使用的“当前”分支 - 它已经为你检查过的分支 - 但同时任何数量的其他分支可能指向同一个提交,并且可以说没有任何一个分支可以被选择为“main”除非您想要表示当前已签出到磁盘的那个。 Please read the following answer on this page for elaboration. 请阅读本页面上以下答案进行详细说明。

The thing you have you to understand about git is that branches are essentially merely commit bookmarks. 关于git,你要了解的是分支本质上只是提交书签。 The fact that you were on the foo branch when you made the 0deadbeef commit is immaterial to the commit itself; 你做0deadbeef提交时你在foo分支上的事实对于提交本身并不重要; the branch is not part of its identity. 分支不是其身份的一部分。

(Mercurial bakes the branch name into the commit. In a variety of ways, this is inferior, as Dustin Sallings explains .) (Mercurial将分支名称加入提交。 在各种方面,这是次等的,正如Dustin Sallings所解释的那样 。)

Even assuming that git describe would just use the currently checked out branch – if you have a mergy history, there could be multiple paths leading to the same most recent tagged commit that git describe would use. 即使假设git describe只使用当前检出的分支 - 如果你有一个古怪的历史,可能会有多条路径导致git describe使用的最新标记提交。 So there isn't even necessarily any one branch. 所以甚至没有一个分支。

Another note: you may object that even if “3rd commit from tag X” is ambiguous in the general case, git describe could just look at the graph and figure out whether it is ambiguous and if not, leave out the hash. 另一个注意事项:您可能会反对即使“标记X中的第3次提交”在一般情况下是不明确的, git describe也可以查看图形并确定它是否含糊不清,如果没有,则省略哈希。 However, there is nothing stopping anyone starting a branch on top of that tag at a later time – so then your describe string would become ambiguous retrospectively . 然而,有什么能够阻止任何人在稍后的时间开始对标签顶部的分支-所以那么你的describe字符串将变得模糊追溯

Bottom line is that the only unambiguous identifier of a commit is its hash. 底线是提交的唯一明确标识符是其哈希。 So that must be in there. 所以那必须在那里。 What git describe does is add some redundant (and in case of the commit number, ambiguous) information that makes the description more useful to the kind of spatial/relational comprehension that humans orient themselves with, within the confines of the Git model. git describe做法是在Git模型的范围内添加一些冗余 (并且在提交编号,模糊的情况下)信息使得描述对于人类定向的空间/关系理解更有用。

Here is what I use: 这是我使用的:

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

It produces something like: 它产生如下:

master-6de772e

As noted by Aristotle, in actuality the SHA-1 by itself is all that is necessary and sufficient to provide an unambiguous build tag, as well as full information regarding the developmental historical context. 正如亚里士多德所指出的,实际上SHA-1本身就是提供明确的构建标记以及有关发展历史背景的完整信息所必需和充分的。 Everything else is redundant, in the sense that any information they provide can be figured out or derived from the SHA-1. 其他一切都是多余的,因为他们提供的任何信息都可以从SHA-1中找出或得出。 However, humans might like the supplementary contextual information of the actual branch immediately evident as well (or, at least, this human does), and hence the embedding of the branch name into the label. 然而,人们可能也喜欢实际分支的补充上下文信息(或者,至少,这个人类),并且因此将分支名称嵌入到标签中。 For this reason also (ie immediate human parsing of the information), most of my projects also use a longer build identity 'description' that includes the date and time of the commit that the build was based on in addition to the build identity 'label' given above. 由于这个原因(即直接人工解析信息),我的大多数项目也使用更长的构建标识“描述”,其中包括构建所基于的提交的日期和时间以及构建标识的标签'如上所述。

git describe --long would always output version number like this: v1.2-10-gdeadbee , which means 10th commit since annotated tag 'v1.2' that points at commit with shortened SHA-1 'deadbee'. git describe --long总是输出这样的版本号: v1.2-10-gdeadbee ,这意味着自注释标记'v1.2'以来第10次提交指向提交时缩短的SHA-1'deadbee'。 So all you have to do is to tag branch start (branching point of a branch) eg < branch >-start . 因此,您所要做的就是标记分支开始(分支的分支点),例如< branch >-start

The abbreviated commit SHA-1 hash is required to distinguish between ambiguous situations, because "3rd commit since tag 'x'" (for example) does not uniquely distinguish a commit; 需要使用缩写的提交SHA-1哈希来区分不明确的情况,因为“第3次提交,因为标记'x'”(例如)不能唯一地区分提交; there can be more than one commit that fits mentioned description in the presence of nonlinear, branchy development. 在存在非线性,分支开发的情况下,可以存在多个适合所述描述的提交。 For example in the situation shown on the ASCII-art diagram below both commits marked with * fits "3rd commit since tag 'x'" description. 例如,在下面的ASCII-art图中显示的情况下,标记为*的提交都符合“自标记'x'”描述以来的第3次提交。

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

Note that in "merged in" case as shown above you can't use branch name to distinguish between those two commits with the same description. 请注意,在上面显示的“merged in”情况下,您不能使用分支名称来区分具有相同描述的两个提交。

So what you have to do would be to take git describe --long output (the --long option is here to avoid ambiguities with parsing, see git describe manpage ), parse it, and add current branch info (from eg git symbolic-ref HEAD , not from pasing git branch output) yourself. 所以你要做的就是采取git describe --long输出( - --long选项在这里是为了避免解析的歧义,请参阅git describe manpage ),解析它,并添加当前分支信息(例如git symbolic-ref HEAD而不是来自pit git branch输出)你自己。

Official releases should have a tag with their version number. 官方发行版应该有一个带有版本号的标签。 In this case I suggest the following approach: 在这种情况下,我建议采用以下方法:

  1. If the current commit has a tag, use that tag 如果当前提交具有​​标记,请使用该标记
  2. If no tag is available, use the branch name and the SHA1-key 如果没有可用的标记,请使用分支名称和SHA1密钥

This single command should work: 这个单一命令应该有效:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM