我使用 Mercurial hooks 将版本号嵌入到应用程序中的方法有多好?
这不是一个具体的问题,我更喜欢对我当前的方法进行批评。
我想在我正在开发的程序中包含程序版本号。这不是商业产品,而是研究应用程序,因此了解哪个版本生成结果非常重要。
我的方法的工作原理如下:
- 我的 .hg/hgrc 文件链接中有一个指向 version_gen.sh 的“预提交”挂钩
- version_gen.sh 仅包含:
hg Parent --template "r{rev}_{date|shortdate}" > > version.num
- 在makefile中,主脚本中的
version="%__VERSION__%
行被version.num文件的内容替换。
是否有更好的方法来做到这一点?我能看到的唯一真正的缺点是,如果您只提交一个特定文件,version.num 将被更新,但它不会被提交,如果我尝试添加总是提交该文件,这将导致无限循环(除非我创建了一些临时文件来表明我已经在提交中,但这看起来很难看......)。
This is not quite a specifc question, and more me like for a criticism of my current approach.
I would like to include the program version number in the program I am developing. This is not a commercial product, but a research application so it is important to know which version generated the results.
My method works as follows:
- There is a "pre-commit" hook in my .hg/hgrc file link to version_gen.sh
- version_gen.sh consists solely of:
hg parent --template "r{rev}_{date|shortdate}" > version.num
- In the makefile, the line
version="%__VERSION__%
in the main script is replaced with the content of the version.num file.
Are there better ways of doing this? The only real short coming I can see is that if you only commit a specfic file, version.num will be updated, but it won't be commited, and if I tried to add always committing that file, that would result in an infite loop (unless I created some temp file to indicate I was already in a commit, but that seems ugly...).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
问题
正如您所发现的,您确实创建了一个Catch-22 这里的情况。
在提交更改之前,您无法真正将有意义的信息放入
version.num
文件中,并且由于您将version.num
存储在存储库中,因此无法提交更改存储库,直到您填充version.num
文件。我的解决方案
我的建议是:
hg忘记
version.num
文件。version.num
添加到您的.hgignore
文件中。调整
version_gen.sh
使其包含:hg Parent --template "r{node|short}_{date|shortdate}" > version.num
在 makefile 中,确保在使用
version.num
设置版本参数之前运行version_gen.sh
。我的原因
为 @Ry4an 建议,让构建系统在构建时将修订信息插入到软件中,使用来自版本控制系统的信息是一个更好的选择。唯一的问题是,如果您尝试从存储库的
hg archive
编译代码,构建系统无法提取相关信息。然而,我倾向于阻止这种情况 - 在我自己的构建系统中,如果无法提取修订信息,则构建失败。
另外,如 @Kai Inkinen 建议,使用修订版号是不可移植的。一台机器上的版本 21 可能在另一台机器上版本 22。虽然这现在可能不是问题,但如果您开始与其他人合作,将来可能会成为问题。
最后,我在 我的问题,涉及与您自己的问题类似的问题:
然后在对建议使用
keyword
扩展的答案的评论中:The problem
As you've identified, you've really created a Catch-22 situation here.
You can't really put meaningful information in the
version.num
file until the changes are committed and because you are storingversion.num
in the repository, you can't commit changes to the repository until you have populated theversion.num
file.My solution
What I would suggest is:
hg forget
theversion.num
file.version.num
to your.hgignore
file.Adjust
version_gen.sh
to consist of:hg parent --template "r{node|short}_{date|shortdate}" > version.num
In the makefile, make sure
version_gen.sh
is run beforeversion.num
is used to set the version parameter.My reasons
As @Ry4an suggests, getting the build system to insert revision information into the software at build time, using information from the Version Control System is a much better option. The only problem with this is if you try to compile the code from an
hg archive
of the repository, where the build system cannot extract the relevant information.I would be inclined to discourage this however - in my own build system, the build failed if revision information couldn't be extracted.
Also, as @Kai Inkinen suggests, using the revision number is not portable. Rev 21 on one machine might be rev 22 on another. While this may not be a problem right now, it could be in the future, if you start colaborating with other people.
Finally, I explain my reasons for not liking the Keyword extension in a question of mine, which touches on similar issues to your own question:
Then in comments to an answer which suggested using the
keyword
extension anyway:您尝试执行的操作称为“关键字扩展”,Mercurial 核心不支持该操作。
您可以将该扩展集成到 make 文件 中,或者(更简单)使用 关键字扩展。
What you are trying to do is called Keyword Expansion, which is not supported in Mercurial core.
You can integrate that expansion in make file, or (simpler) with the Keyword extension.
令人担忧的是您使用了预提交挂钩。您不应该将 version_gen.sh 的其余部分放入源文件中,而应放入构建/发布工件中,您可以使用“更新”挂钩更准确地执行此操作。
您不希望 Makefile 在每次提交时都在存储库中实际更改,这只会使合并变得糟糕。您希望在构建之前检查文件后插入版本,这就是更新挂钩的作用。
That you use a pre-commit hook is what's concerning. You shouldn't be putting the rest of version_gen.sh into the source files thesemves, just into the build/release artifacts which you can do more accurately with an 'update' hook.
You don't want the Makefile to actually change in the repo with each commit, that just makes merges hell. You want to insert the version after checking out the files in advance of a build, which is is what an update hook does.
在像 Mercurial 这样的分布式系统中,实际的“版本号”并不一定在每个环境中都意味着相同的事情。即使这是一个单人项目,并且您非常小心地只拥有中央存储库,您仍然可能想要使用 sha1-sum 来代替,因为这对于给定存储库状态来说确实是唯一的。 sha1 可以通过模板 {node} 获取
作为建议,我认为更好的工作流程是使用标签,顺便说一句,这些标签也是存储库本地的,直到您将它们推送到上游。不要将您的号码写入文件,而是使用有意义的标签(例如
)来标记您的发布代码
RELEASE_2
或
RELEASE_2010-04-01
或者也许编写此脚本并使用模板来创建标签?
然后,您可以将标记添加到非版本化(在 .hgignore 中)的 version.num 文件中,以添加到构建中。通过这种方式,您可以为版本指定有意义的名称,并将版本与唯一标识符联系起来。
In distributed systems like Mercurial, the actual "version number" does not necessarily mean the same thing in every environment. Even if this is a single person project, and you are really careful with having only your central repo, you would still probably want to use the sha1-sum instead, since that is truly unique for the given repository state. The sha1 can be fetched through the template {node}
As a suggestion, I think that a better workflow would be to use tags instead, which btw are also local to your repository until you push them upstream. Don't write your number into a file, but instead tag your release code with a meaningful tag like
RELEASE_2
or
RELEASE_2010-04-01
or maybe script this and use the template to create the tag?
You can then add the tag to your non-versioned (in .hgignore) version.num file to be added into the build. This way you can give meaningful names to the releases and you tie the release to the unique identifier.