我最近问过 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$

如果你在让 shell 逃逸时遇到困难 smudgeclean 要使用命令,只需分别编写自己的 Perl 脚本来扩展和删除 RCS 关键字,然后使用这些脚本作为过滤器。

请注意,您 真的 不想对超出绝对必要的文件执行此操作,否则 git 将失去大部分速度。

其他提示

不幸的是,RCS关键字替代打破了这一点。例如,使用$ date $将需要git neckout在切换分支时触摸树上的每个文件。

那不是真的。$日期$等扩展到签入时保留的值。无论如何,这更有用。因此,它不会在其他修订或分支上发生更改,除非文件实际上被重新签入。来自 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 中设置的扩展名的所有文件,通常会稍微减慢速度。

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

$Id: deadbeefdeadbeefdeadbeefdeadbeefdeadbeef$

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top