我提交时如何将Git提交ID填充到文件中?

Bes*_*ces 33 git

我想创建一个Git hook(s),它将在我的源代码中填充我将要生成的提交的提交id到一个文件(基本上是变量替换).这可能与Git有关吗?或者是通过将变量解析为git id,我将改变sha 1,从而结束了"鸡或鸡蛋"问题.

twa*_*erg 36

我用于类似情况的解决方案是这样的:

  1. 将字符串$Id$放在您想要识别的文件中(例如test.html),可能在文件的注释或其他非功能部分中,它不会导致问题.
  2. 在您.gitattributes的标签中,使用ident关键字标记相关文件(例如*.html ident).

这样做的结果是,当git checkout将文件从对象数据库复制到工作目录中时,它会扩展$Id$要读取的字符串$Id: <sha-1 of file>$,并git add在您要检入时转换该转换,因此仅在对象数据库中存储该文件的版本永远包含$Id$,而不是扩展形式.

这是一个开始,但不幸的是,找到包含具有特定哈希的文件的提交并不是那么容易,也不一定是一对一的.所以,此外,我还用export-subst属性标记这些文件(例如*.html ident export-substin .gitattributes),并添加一个额外的字符串,就像$Format:%ci$ ($Format:%h$)文件中的某个地方一样.

git checkout并且git add不影响这些标签,虽然如此,在我的仓库版本总是正是字符串.为了扩展这些标签,你必须使用git archive创建项目特定版本的tar-ball(或.zip),然后用它来部署该版本 - 你将无法复制文件,或者make install其他什么,因为这git archive是唯一可以扩展这些标签的东西.

我给出的两个标签作为示例扩展到YYYY-MM-DD HH:MM:SS +TZOFFSET (HASH),HASH在这种情况下是实际的提交哈希,所以它更有用.

您可以在说明符下的帮助页面中找到其他可能有用的$Format:$说明符.git log--pretty-format

  • 官方文档:[关键字扩展](https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes#_keyword_expansion) (4认同)

And*_*mar 7

您可以创建一个过滤器,在提交和结帐时对文件进行替换.这些被称为"涂抹"和"清洁"过滤器,它们的操作通过控制.gitattributes.例如:

*.c     filter=yourfilter
Run Code Online (Sandbox Code Playgroud)

这告诉git yourfilter为所有.c文件运行过滤器.然后你必须告诉git是什么yourfilter意思:

git config --global filter.yourfilter.clean script1
git config --global filter.yourfilter.smudge script2
Run Code Online (Sandbox Code Playgroud)

然后你要编写一个脚本(sed,Perl,Python或其他任何东西)来替换表达式,例如$LastSha$with $LastSha: <sha>$checkout("smudge").另一个脚本在提交之前反转扩展("clean".)

有关详细示例,请在Pro Git书中搜索"关键字扩展".

  • @BestPractices根本无法完成,请参阅[kostix的答案](http://stackoverflow.com/a/16525425/1290731) (2认同)

kos*_*tix 7

做你想做的事情是不可能的:提交的SHA-1哈希是在整个存储库快照上计算的,包括每个成员文件,所以有鸡和蛋的问题 - 计算提交的哈希你需要知道所有文件的内容包括它.


Jon*_*rns 6

你可以用post-commit钩子做到这一点.这是git-scm网站的摘录

整个提交过程完成后,后提交挂钩运行.它不需要任何参数,但您可以通过运行git log -1 HEAD轻松获得最后一次提交.通常,此脚本用于通知或类似的东西.

这将是获取输出的情况git log -1 HEAD,然后使用类似于sed替换文件中的变量的工具.但是,这会修改您的工作目录,除非您要将这些更改丢弃,否则您最终会得到一个永久修改的工作目录.

如果您只想在代码中的某个变量中使用当前提交哈希,则只需执行git log -1 HEADcat .git/HEAD将输出存储在变量中

如果您只想要问题标题中的id(哈希),则可以使用该--format标志.git log -1 HEAD --format=%H

  • 这样的`post-commit`钩子会修改工作目录.每次提交时,都会存储**之前**提交的SHA1,然后修改工作目录以包含上次提交的SHA1. (5认同)
  • @Andomar钩子可能会修改工作目录,但如果修改的文件是`.gitignored`(即出于构建目的或某些东西,不被`git`跟踪),这仍然有用.尽管如此......从提问者那里了解确切的用例可能会有所帮助. (2认同)