11

我有几个 Rails 应用程序,我使用 Git 作为版本控制系统。我使用 GitHub 或 Beanstalk 作为存储库主机。

我想要做的在理论上很简单。以某种方式在 Web 应用程序的页脚中显示最新的提交 ID 号(哈希?)。因此,当我查看 Web 应用程序时,我可以检查它是否已正确提交和部署。

我可以想象有两种方法可以解决这个问题。第一个可能是 Git 的一个可能特性,它允许输出提交 ID。第二个是提交后的网络钩子(Beanstalk 和 GitHub 都允许这样做)。

有没有人找到一种方法来做到这一点,或类似的东西?

谢谢,

丹尼

4

3 回答 3

15

首先澄清一下:post-commithook 不能在 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那个

于 2010-10-23T09:28:49.803 回答
4

我相信您最终想要做的是,作为“构建”过程(部署,您的情况?)的一部分,将git rev-parse HEADgit describe HEAD(更好,假设您标记发布)的输出存储在文件中。然后,您的应用程序可以显示文件的内容。提交哈希实际上不可能是任何被跟踪内容的一部分(提交的哈希取决于被跟踪的内容)。当然,如果您的应用程序的 repo 用完了,您可以简单地从应用程序运行命令,但只执行一次要优雅得多。

顺便说一句,这是 git 本身采用的方法。它有一个很小的 ​​shell 脚本,基本上将git describe输出转储到GIT-VERSION-FILE,然后被编译以提供版本信息。

希望我没有误解您的情况-您说“允许输出提交 ID 的 Git 的可能功能”让我有些困惑。这是 git 的一个非常基本的能力。

于 2010-10-22T18:07:08.360 回答
0

首先,回答您的问题,在您的 ruby​​ 脚本中运行以下命令:

`git log -n1 | head -1`.split.last

第二:你是什么意思你使用 beanstalk 作为你的存储库主机?beantalk 不是排队服务器吗?

于 2010-10-22T18:09:12.307 回答