首先澄清一下:post-commit
hook 不能在 commit 中添加 commit-id 到文件,因为 commit id 依赖于 top tree(代表顶层目录)的 commit,top tree 的 id 又依赖于其成员的 id,而 a文件取决于其内容...并且此内容将包含提交 ID。不可能。
但是让我们看一下不同的解决方案:
实时、服务器端脚本
如果您的 Web 应用程序是从非裸 git 存储库实时部署的(我希望您知道自己在做什么。推入非裸存储库,即带有签出/工作树的存储库),那么您的 Web 应用程序可以使用git rev-parse HEAD
(提供提交的 SHA-1),或更好git describe --dirty
(该--dirty
选项将使返回的字符串包含您在工作区中是否有未提交更改的信息),或git describe --always HEAD
.
git rev-parse HEAD
给出类似的东西7611062b4ba6d1ebc4cf3e63c11204a4f5057660
,而git describe --dirty
给出类似的东西v1.7.3.2-95-g7611062
(这意味着在提交标记为'v1.7.3.2'之后提交带有缩写SHA-1的7611062
提交,95次提交),但这取决于您使用带注释的标签标记发布。
这种情况的一个变体是让 Web 应用程序从存储库中检查 HEAD,该存储库位于同一文件系统的其他位置,例如git --git-dir=/path/to/.git describe HEAD
.
旁注:如果你使用 Ruby,你可能想要使用grit库。版本的等价物git rev-parse HEAD
可能是(未经测试!):
require 'grit'
include Grit
repo = Repo.new("/var/git/app.git")
head = repo.commits('HEAD', 1)
app_version = head.id
从 git checkout 提供的实时静态文件
编辑: 添加部分 2010-10-23 13:33 +0000
如果您从非裸 git 存储库(不是您的情况)的结帐(工作树)提供文件,您可以使用gitattribute的“涂抹”和“清洁”命令filter
在结帐/签入时执行类似 CVS 的关键字扩展。
在.gitattributes
文件中,您将定义filter
应该对哪个属性起作用的文件:
*.rb 过滤器=commitid
例如,您在 git 配置文件(例如 in .git/config
)中定义过滤器
[过滤“提交”]
smudge = sed -e "s/\$Revision: ?\$/\$Revision: $(git rev-parse HEAD)\$/1"
clean = sed -e "s/\$Revision: ?[^$]*\$/\$Revision: \$/1"
过滤器将在结帐时将smudge
'$Revision: $' 替换为例如'$Revision: v1.7.3.2-95-g7611062'(这意味着签出文件将包含这个类似CVS 的关键字扩展)。将clean
文件内容存储在 git 对象数据库(在 git 存储库中)时,过滤器将删除扩展;否则你会在比较文件等方面遇到问题。
部署使用git archive
如果您改为部署您的网络应用程序,那么它不会驻留在实时存储库中(它有其怪癖。推入它,并且可能存在安全缺陷),并且您使用git archive
某处(例如压缩应用程序将其上传到您的托管站点),您可以使用关键字替换。
首先,您需要告诉 Git 您希望将文件中的关键字替换为git archive
. 您可以通过设置export-subst
给定文件来做到这一点,例如通过添加到.gitattributes
文件
*.rb 出口替代品
然后添加到包含/生成页脚的文件中,例如
$格式:%H$
它将被提交哈希替换(参见漂亮格式描述,例如在git-log手册页中)。
已部署,使用一些部署脚本
如果您使用某种脚本/脚本机制来部署您的 Web 应用程序,您应该遵循Jefromi 的建议,让您的部署脚本嵌入版本信息。
您将不得不询问其他人如何设置Capistrano(假设您将其用于部署)以发布:部署将您的 'app.rb' 文件中的 '@@VERSION@@' 占位符替换为git describe --always HEAD
... Git 项目 Makefile用于sed
那个。