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

时间:2008-09-15 12:04:32

标签: svn git version-control

我最近问过keyword expansion in 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属性

但是,通过几个前/后提交挂钩模拟这个关键字的东西似乎并不太棘手。我是第一个想要这个的人吗?有没有人有一些代码可以做到这一点?

4 个答案:

答案 0 :(得分:39)

这里发生了什么: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关键字,则可能需要从此explanation by 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命令中获取shell转义,只需编写自己的Perl脚本以分别扩展和删除RCS关键字,并将这些脚本用作过滤器

请注意,确实不希望为绝对必要的文件执行此操作,否则git将失去其大部分速度。

答案 1 :(得分:22)

  

不幸的是,RCS关键字   替代打破了这个。例如,   使用$ Date $需要git   结帐以触摸中的每个文件   切换分支时的树。

事实并非如此。 $ 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过滤器)不正确。它会插入结帐的时间/日期,或者导致其运行的任何内容。

答案 2 :(得分:6)

这是一个示例项目,其中包含将GCS关键字支持添加到git项目所需的配置和过滤器代码:

https://github.com/turon/git-rcs-keywords

设置并不像想要的那么简单,但似乎有效。它使用用perl编写的涂抹/清理过滤器对(类似于emk的答案所描述的),是的,它将触及所有带有.gitattributes中设置的扩展名的文件,通常会使事情变慢一些。

答案 3 :(得分:1)

您可以在文件上设置ident属性,但这会产生类似

的字符串
$Id: deadbeefdeadbeefdeadbeefdeadbeefdeadbeef$

其中deadbeef...是与该文件对应的blob的sha1。如果你确实需要关键字扩展,并且你需要在git repo中(而不是导出的存档),我认为你将不得不使用ident gitattribute与自定义脚本一起使用为你扩展。使用钩子的问题是工作树中的文件与索引不匹配,git会认为它已被修改。