使用git-svn处理SVN关键字扩展

时间:2020-03-05 18:53:17  来源:igfitidea点击:

最近,我问到有关Git中关键字扩展的问题,我愿意接受这种设计,而不是真的在Git中支持该想法。

不管好坏,我目前正在研究的项目需要使用SVN关键字扩展,如下所示:

svn propset svn:keywords "Id" expl3.dtx

使此字符串保持最新:

$Id: expl3.dtx 803 2008-09-11 14:01:58Z will $

但是我很想使用Git来进行版本控制。不幸的是,根据文档,git-svn不支持此功能:

"We ignore all SVN properties except svn:executable"

但是用几个前后提交钩子来模拟这个关键字似乎并不难。我是第一个想要这个的人吗?有人有一些代码可以做到这一点吗?

解决方案

回答

我们可以在文件上设置ident属性,但这会产生类似以下的字符串

$Id: deadbeefdeadbeefdeadbeefdeadbeefdeadbeef$

其中," deadbeef ..."是与该文件相对应的Blob的sha1. 如果我们确实需要该关键字扩展,并且需要在git repo(而不是导出的存档)中使用它,我认为我们将不得不使用带有定制脚本的identgitattribute来进行扩展你。仅仅使用一个钩子的问题就是工作树中的文件与索引不匹配,而git会认为它已被修改。

回答

这是怎么回事: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$

如果我们在使smudgeclean命令中的外壳转义符工作时遇到困难,只需编写自己的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手册中:

$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过滤器的答案是错误的。它插入结帐的时间/日期,或者导致结帐运行的任何时间。