我最近询问了Git中的关键字扩展,我愿意接受这个设计,不要在Git中真正支持这个想法.
无论好坏,我正在进行的项目需要SVN关键字扩展,如下所示:
svn propset svn:keywords "Id" expl3.dtx
保持这个字符串是最新的:
$Id: expl3.dtx 803 2008-09-11 14:01:58Z will $
但我非常想用Git来进行版本控制.不幸的是,根据文档,git-svn不支持这一点:
"除了svn:executable之外,我们忽略了所有SVN属性"
但是,通过一些前/后提交挂钩模拟这个关键字的东西似乎并不太棘手.我是第一个想要这个的人吗?有没有人有一些代码来做到这一点?
这里发生了什么:Git已经过优化,可以尽快在分支机构之间切换.特别是,git checkout
设计为不触及两个分支中相同的任何文件.
不幸的是,RCS关键字替换破坏了这个.例如,使用$Date$
将需要git checkout
在切换分支时触摸树中的每个文件.对于Linux内核大小的存储库,这将使一切都停止.
一般来说,最好的办法是标记至少一个版本:
$ git tag v0.5.whatever
...然后从Makefile中调用以下命令:
$ 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关键字,以下内容应该让您开始:
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
在我的系统上,我得到:
$Date: Tue Sep 16 10:15:02 EDT 2008$
如果您无法在smudge
和clean
命令中使用shell转义,只需编写自己的Perl脚本以分别扩展和删除RCS关键字,并将这些脚本用作过滤器.
请注意,您确实不希望为绝对必要的文件执行此操作,否则git将失去其大部分速度.
不幸的是,RCS关键字替换破坏了这个.例如,在切换分支时,使用$ Date $将需要git checkout来触摸树中的每个文件.
事实并非如此.$ Date $等扩展到在入住时保留的值.无论如何,这更有用.因此,除非文件实际上已重新签入,否则它不会在其他修订或分支上更改.从RCS手册:
$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过滤器不一致.它会插入结帐的时间/日期,或者导致其运行的任何内容.
这是一个示例项目,其中包含向git项目添加RCS关键字支持所需的配置和过滤器代码:
https://github.com/turon/git-rcs-keywords
设置并不像人们想的那么简单,但似乎有效.它使用用perl编写的涂抹/清除过滤器对(类似于emk的答案所描述的),是的,它将触及所有带有.gitattributes中设置的扩展名的文件,通常会减慢一些速度.