最近,我问到有关Git中关键字扩展的问题,我愿意接受这种设计,而不是真的在Git中支持该想法。
不管是好是坏,我目前正在研究的项目都需要像这样的SVN关键字扩展:
1
| svn propset svn:keywords"Id" expl3.dtx |
使此字符串保持最新:
1
| $Id: expl3.dtx 803 2008-09-11 14:01:58Z will $ |
但是我很想使用Git进行版本控制。 不幸的是,根据文档,git-svn不支持此功能:
"We ignore all SVN properties except svn:executable"
但是用几个前后提交钩子来模拟这个关键字似乎并不难。 我是第一个想要这个的人吗? 有人有一些代码可以做到这一点吗?
这是怎么回事:Git经过优化,可以尽快在分支之间切换。特别地,git checkout被设计为不触摸两个分支中相同的任何文件。
不幸的是,RCS关键字替换打破了这一点。例如,使用$Date$要求git checkout在切换分支时触摸树中的每个文件。对于像Linux内核那样大小的存储库,这将使一切陷入停顿。
通常,最好的选择是标记至少一个版本:
...然后从您的Makefile中调用以下命令:
1 2
| $ git describe --tags
v0.5.15.1-6-g61cde1d |
在这里,git告诉我我正在使用匿名版本6提交超过v0.5.15.1的版本,并且SHA1哈希以g61cde1d开头。如果将此命令的输出粘贴到某个地方的*.h文件中,则表示您在工作,并且将发行的软件链接回源代码也没有问题。这是首选的处理方式。
如果您无法避免使用RCS关键字,则可能需要从Lars Hjemli的解释开始。基本上,$Id$非常简单,如果您使用的是git archive,也可以使用$Format$。
但是,如果您绝对不能避免使用RCS关键字,那么以下内容将帮助您入门:
1 2 3 4 5 6 7 8 9 10 11
| git config filter.rcs-keyword.clean 'perl -pe"s/\\\$Date[^\\\$]*\\\$/\\\$Date\\\$/"'
git config filter.rcs-keyword.smudge 'perl -pe"s/\\\$Date[^\\\$]*\\\$/\\\$Date: `date`\\\$/"'
echo '$Date$' > test.html
echo 'test.html filter=rcs-keyword' >> .gitattributes
git add test.html .gitattributes
git commit -m"Experimental RCS keyword support for git"
rm test.html
git checkout test.html
cat test.html |
在我的系统上,我得到:
1
| $Date: Tue Sep 16 10:15:02 EDT 2008$ |
如果在smudge和clean命令中无法使外壳转义起作用时,只需编写您自己的Perl脚本来分别扩展和删除RCS关键字,然后将这些脚本用作过滤器即可。
请注意,您确实不希望对超出绝对必要数量的文件进行更多操作,否则git将失去其大部分速度。
Unfortunately, RCS keyword
substitution breaks this. For example,
using $Date$ would require git
checkout to touch every file in the
tree when switching branches.
那是不对的。 $ Date $等扩展为在签入时保存的值。无论如何,这是有用的。因此,除非实际重新检入文件,否则它在其他修订版或分支上不会更改。
从RCS手册中:
1 2 3
| $Date$ The date and time the revision was checked in. With -zzone a
numeric time zone offset is appended; otherwise, the date is
UTC. |
这也意味着上面建议的带有rcs-keyword.smudge过滤器的答案是错误的。它插入结帐的时间/日期,或导致结帐运行的任何时间。
这是一个示例项目,其中包含将RCS关键字支持添加到git项目所需的配置和过滤器代码:
https://github.com/turon/git-rcs-keywords
它的设置并不像人们想要的那么简单,但是它似乎可以工作。它使用用perl编写的污迹/干净过滤器对(类似于emk的答案),是的,它将触摸所有扩展名为.gitattributes的文件,通常会降低速度。
您可以在文件上设置ident属性,但这会产生如下字符串
1
| $Id: deadbeefdeadbeefdeadbeefdeadbeefdeadbeef$ |
其中deadbeef...是与该文件相对应的Blob的sha1。如果您确实需要该关键字扩展,并且需要在git repo(而不是导出的存档)中使用它,我认为您将不得不使用ident gitattribute和一个自定义脚本来为该扩展进行扩展您。仅仅使用一个钩子的问题就是工作树中的文件与索引不匹配,而git会认为它已被修改。