如何使用 Git 的“describe”命令派生应用程序构建版本字符串?
我想编写应用程序构建版本,该版本是从我所在的 Git 分支名称(构建时)以及分支分歧以来的提交次数自动派生的。我相信这对于我的 Git 存储库中的任何提交都是唯一的?分支名称是唯一的,并且提交沿着分支相互链接?如果当我标记提交时,我还可以让版本以该标记为前缀。
在某种程度上 git describe 做了我想要的,但它不包括我所在的分支名称,并且它包括缩写的提交 SHA-1 哈希,我认为我不需要它不向字符串的熵添加任何内容,并且可能是多余的(我在这里可能是错的,所以请纠正我)。
我有什么选择?我的思考方向正确吗?当我有关于软件开发的更重要的事情需要处理时,我只是有点厌倦了在版本中附加数字。
顺便说一句,我从来不会用一棵肮脏的工作树来建造。即,我总是在构建公开版本之前向存储库提交更改。
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.
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).
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
git describe --long
总是会输出这样的版本号:v1.2-10-gdeadbee,这意味着自 annotated 标记以来的第 10 次提交v1.2' 指向带有缩短的 SHA-1 'deadbee' 的提交。因此,您所要做的就是标记分支开始(分支的分支点),例如<branch>-start
。需要使用缩写的提交 SHA-1 哈希来区分不明确的情况,因为“自标记‘x’以来的第 3 次提交”(例如)不能唯一区分提交;在存在非线性、分支开发的情况下,可能有多个提交符合上述描述。例如,在下面的 ASCII-art 图所示的情况下,两个标有 * 的提交都符合“自标记‘x’以来的第 3 次提交”描述。
请注意,在如上所示的“合并”情况下,您不能使用分支名称来区分具有相同描述的这两个提交。
因此您要做的就是采用
git描述 --long
输出(这里使用--long
选项是为了避免解析时出现歧义,请参阅 git 描述手册页) ,解析它,并自己添加当前分支信息(例如来自git symbolic-ref HEAD
,不是来自 pasinggitbranch
输出)。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'. So all you have to do is to tag branch start (branching point of a branch) e.g.<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.
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 --long
output (the--long
option 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
, not from pasinggit branch
output) yourself.这是我使用的:
它产生类似的内容:
正如亚里士多德所指出的,实际上 SHA-1 本身就足以提供明确的构建标签以及有关发展历史背景的完整信息。其他一切都是多余的,因为它们提供的任何信息都可以从 SHA-1 中计算或导出。然而,人们可能也喜欢立即显而易见的实际分支的补充上下文信息(或者,至少这个人喜欢),因此将分支名称嵌入到标签中。也出于这个原因(即立即人工解析信息),我的大多数项目还使用更长的构建身份“描述”,其中除了构建身份“标签之外,还包括构建所基于的提交的日期和时间” ' 上面给出。
Here is what I use:
It produces something like:
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.
正式版本应该有一个带有版本号的标签。
在这种情况下,我建议采用以下方法:
此单个命令应该有效:
Official releases should have a tag with their version number.
In this case I suggest the following approach:
This single command should work:
关于 git,您需要了解的是,分支本质上只是提交书签。当您进行
0deadbeef
提交时,您位于foo
分支上这一事实对于提交本身来说并不重要;分支机构不是其身份的一部分。(Mercurial 将分支名称烘焙到提交中。 正如达斯汀·塞林斯 (Dustin Sallings) 所解释的那样,从很多方面来说,这都是较差的。)
即使假设
gitdescribe
只会使用当前签出的分支 - 如果您有合并历史记录,则可能会有是通向git describe
将使用的相同最新标记提交的多个路径。所以甚至不一定有任何一个分支。另请注意:您可能会反对,即使“来自标签 X 的第三次提交”在一般情况下是不明确的,
gitdescribe
也可以只查看图表并找出它是否是 不明确,如果不明确,则省略散列。但是,没有什么可以阻止任何人稍后在该标记之上启动分支 - 因此您的describe
字符串将变得不明确。回顾。最重要的是,提交的唯一明确标识符是它的哈希值。所以那一定是在那里。
gitdescribe
所做的是添加一些冗余(并且在提交编号的情况下不明确)信息,使描述对于人类的空间/关系理解更有用在 Git 模型的范围内定位自己。The thing you have you to understand about git is that branches are essentially merely commit bookmarks. The fact that you were on the
foo
branch when you made the0deadbeef
commit is immaterial to the commit itself; 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.)
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 thatgit describe
would use. 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. However, there is nothing stopping anyone starting a branch on top of that tag at a later time – so then yourdescribe
string would become ambiguous retrospectively.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.