35

如何启用ident $Id$Git 存储库中的文件?

4

4 回答 4

42

总结:在产品中嵌入版本信息的推荐方法是使用构建系统;有关详细信息和替代方法,请参见下文。


在 Git 中(我认为通常也在其他具有原子提交的 VCS 系统中)没有像version of a single file这样的东西。

$Id:$Git 确实支持关键字的按需扩展,但是:

  1. 仅应要求完成。您必须指定(可能使用通配符模式)一个文件(或一组文件)具有一个ident 属性集(在树中的 '.gitattributes' 文件中,或在本地存储库设置的 '.git/info/attributes' 中)。
  2. 它扩展为文件内容的 SHA-1(或更准确地说是$Id:<sha-1 of blob>$)。之所以这样选择,是因为 Git 不会去触碰分支切换或倒带时没有改变的文件;如果 '$Id:$' 扩展到修订信息,则需要更新每个版本控制的文件,例如在切换分支时。

Git 支持相当广泛的占位符集,$Format:...$这些占位符扩展到提交信息(例如$Format:%H$,被提交哈希替换)但是:

  1. 仅当在其输出文件中运行git archive时才会进行扩展。
  2. 它是根据请求完成的,通过export-subst属性控制。

嵌入版本信息的推荐方式是通过构建系统(在构建阶段)进行;例如,请参见 Git Web 界面中 Makefile 使用的 Git MakefileGIT-VERSION-GEN脚本,用于 git.git 存储库。

但是,您可以(ab)使用 clean/smudge 过滤器驱动程序(通过filter属性)来获得类似 CVS 的关键字扩展,在结帐时扩展关键字,并在将内容输入存储库时清理它们。

于 2009-11-25T12:39:47.010 回答
18

您可以通过ident在文件中添加您想要此功能的文件的模式来执行此.gitattributes操作。这将在签出文件时将 $Id$ 替换为 $Id:<40-digit SHA>$。请注意,它不会像在 CVS/SVN 中那样为您提供文件的修订号。

例子:

$ echo '*.txt ident' >> .gitattributes
$ echo '$Id$' > test.txt
$ git commit -a -m "test"

$ rm test.txt
$ git checkout -- test.txt
$ cat test.txt

链接到gitattributes(5) 手册页

于 2009-11-24T21:04:55.707 回答
2

Git 的 ident 不像 $Id$ 在其他版本控制系统中所做的那样。作为一个组合,将 RCS 与 git 一起使用:RCS 用于单个文件修订,而 git 用于检查整个项目。正如我所说,这是一个杂牌,但它确实有点道理(有时对于某些事情)。

于 2015-01-22T22:19:59.713 回答
1

Jakub Narębski他的回答中建议(10 多年前):

但是,您可以(ab)使用 clean/smudge 过滤器驱动程序(通过过滤器属性)来获得类似 CVS 的关键字扩展,在结帐时扩展关键字,并在将内容输入存储库时清理它们。

批评是(由Arioch 'The评论中)

如果过滤器驱动程序真的有任何力量,它会非常棒。
据了解,它似乎将文件名作为参数:这甚至比ident过滤器还要少,过滤器将 BLOB SHA1 作为参数

使用 Git 2.27(2020 年第二季度),git 内容过滤器不再无能为力!

Git 2.27 为涂抹/清洁转换过滤器提供了更多信息(例如,除了已经给出的路径之外,正在转换的 blob 出现在其中的树形对象)。

请参阅提交 0c0f8a7提交 4cf76f6提交 3f26785提交 dfc8cdc提交 13e7ed6提交 c397aac提交 ab90eca(2020 年 3 月 16 日)和提交 a860476(2020 年 3 月 10 日),作者为brian m。卡尔森(``)
(由Junio C Hamano 合并 -- gitster--4e4baee 提交中,2020 年 3 月 27 日)

convert: 允许传递额外的元数据来过滤进程

签字人:brian m. 卡尔森

在多种情况下,过滤器进程可以使用一些额外的元数据。

例如,有些人发现 ident 过滤器限制太多,并希望在他们弄脏的文件中包含提交或分支

此信息在结帐期间不可用,因为此时 HEAD 尚未更新,并且它也不会在存档中可用。

让我们添加一种方法来将此元数据传递给过滤器。

我们传递我们正在操作的 blob、treeish(如果存在,则优先于树的提交)和我们正在操作的 ref。

请注意,我们不会在所有情况下都传递此信息,例如在重新规范化或执行差异时,因为在这些情况下它没有意义。

我们目前从过滤过程中获得的数据如下所示:

command=smudge
pathname=git.c
0000

通过这一更改,我们将获得更像这样的数据:

command=smudge
pathname=git.c
refname=refs/tags/v2.25.1
treeish=c522f061d551c9bb8684a7c3859b2ece4499b56b
blob=7be7ad34bd053884ec48923706e70c81719a8660
0000

关于这种方法,有几点需要注意。

对于 checkout 之类的操作,treeish 将始终是提交,因为我们无法检查单个树,但对于其他操作,例如存档,我们最终只能对特定树进行操作,因此我们将仅提供树作为 treeish .

类似的注释适用于 refname,因为在很多情况下我们不会有 ref。

和:

convert: 为过滤器提供额外的元数据

签字人:brian m. 卡尔森

现在我们已经连接了代码库以将任何额外的元数据传递给过滤器,让我们收集我们想要传递的额外元数据。

我们传递此元数据的两个主要地方是结账和档案
在这两种情况下,读取 HEAD 不是一个有效的选项,因为直到写入工作树并且存档可以接受任意树之后,才会更新 HEAD 以进行检出。

在其他情况下,HEAD 通常会反映当前使用的分支的 refname。

在其他情况下,我们传递的数据量较少,例如git cat-file,我们实际上只能从逻辑上了解 blob。

于 2020-03-28T19:34:27.550 回答