如何使用 Git 的 `describe` 命令导出应用程序构建版本字符串?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3300746/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 04:26:09  来源:igfitidea点击:

How to derive application build version string with Git's `describe` command?

gitversioningauto-versioning

提问by amn

I want to compose application build version that is automatically derived from the Git branch name I am on (when building) and the number of commits since the branch has diverged. I believe this will be unique for any commit in my Git repository? 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.

我想编写应用程序构建版本,该版本自动派生自我所在的 Git 分支名称(构建时)以及自分支出现分歧以来的提交次数。我相信这对于我的 Git 存储库中的任何提交来说都是独一无二的吗?分支名称是唯一的,并且提交沿分支相互链接?如果当我标记一个提交时,我也可以让版本以该标记为前缀。

In a way git describedoes 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. I.e. I always commit changes to the repository before building a public release.

顺便说一句,我从来没有用肮脏的工作树建造。即我总是在构建公共版本之前提交对存储库的更改。

采纳答案by Aristotle Pagaltzis

The thing you have you to understand about git is that branches are essentially merely commit bookmarks. The fact that you were on the foobranch when you made the 0deadbeefcommit is immaterial to the commit itself; the branch is not part of its identity.

您需要了解的关于 git 的事情是分支本质上只是提交书签。提交foo时您在分支上这一事实0deadbeef对提交本身无关紧要;分支不是其身份的一部分。

(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 describewould 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 describewould use. So there isn't even necessarily any onebranch.

即使假设git describe只使用当前检出的分支——如果你有合并历史,可能有多个路径通向git describe将使用的相同的最新标记提交。所以甚至不一定有任何一个分支。

Another note: you may object that even if “3rd commit from tag X” is ambiguous in the general case, git describecould just look at the graph and figure out whether it isambiguous and if not, leave out the hash. However, there is nothing stopping anyone starting a branch on top of that tag at a later time – so then your describestring would become ambiguous retrospectively.

另一个注意事项:您可能会反对,即使“标签 X 的第三次提交”在一般情况下是不明确的,git describe只需查看图表并确定它是否不明确,如果不是,则省略哈希。但是,没有什么可以阻止任何人稍后在该标签之上开始分支——因此,您的describe字符串在追溯时会变得模棱两可。

Bottom line is that the onlyunambiguous identifier of a commit is its hash. So that must be in there. What git describedoes 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的模型的范围内。

回答by Jeet

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. Everything else is redundant, in the sense that any information they provide can be figured out or derived from the 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 (i.e. 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.

正如亚里士多德所指出的,实际上 SHA-1 本身就是提供明确构建标签以及有关发展历史背景的完整信息所必需和足够的。其他一切都是多余的,因为它们提供的任何信息都可以从 SHA-1 中找出或推导出来。然而,人类可能也喜欢立即显而易见的实际分支的补充上下文信息(或者,至少这个人喜欢),因此将分支名称嵌入到标签中。出于这个原因(即信息的即时人工解析),我的大多数项目还使用更长的构建标识“描述”,除了构建标识“标签”之外,还包括构建所基于的提交的日期和时间' 上面给出。

回答by Jakub Nar?bski

git describe --longwould always output version number like this: v1.2-10-gdeadbee, which means 10th commit since annotatedtag 'v1.2' that points at commit with shortened SHA-1 'deadbee'. So all you have to do is to tag branch start (branching point of a branch) e.g. <branch>-start.

git describe --long将始终输出这样的版本号:v1.2-10-gdeadbee,这意味着自注释标记“v1.2”以来的第 10 次提交,该标记指向具有缩短的 SHA-1 'deadbee' 的提交。所以你所要做的就是标记分支开始(分支的分支点),例如.<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; 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.

需要缩写提交 SHA-1 哈希来区分不明确的情况,因为“自标记 'x' 以来的第三次提交”(例如)并不能唯一区分一次提交;在存在非线性、分支开发的情况下,可能有多个提交符合上述描述。例如,在下面的 ASCII 艺术图所示的情况下,标有 * 的两个提交都符合“自标记 '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.

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

So what you have to do would be to take git describe --longoutput (the --longoption is here to avoid ambiguities with parsing, see git describe manpage), parse it, and add current branch info (from e.g. git symbolic-ref HEAD, notfrom pasing git branchoutput) yourself.

因此,您需要做的是获取git describe --long输出(--long此处的选项是为了避免解析时出现歧义,请参阅git describe 手册页),解析它,然后自己添加当前分支信息(例如来自git symbolic-ref HEAD而不是来自 pasinggit branch输出)。

回答by Olaf Mertens

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
  1. 如果当前提交有标签,请使用该标签
  2. 如果没有可用的标签,请使用分支名称和 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`"