【问题标题】:Show the latest commit value within a web application?在 Web 应用程序中显示最新的提交值?
【发布时间】:2011-04-29 06:30:40
【问题描述】:

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

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

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

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

谢谢,

丹尼

【问题讨论】:

    标签: ruby-on-rails git version-control github amazon-elastic-beanstalk beanstalk-svn


    【解决方案1】:

    首先澄清一下:post-commit钩子不能在in一次提交中添加commit-id,因为commit id依赖于top tree(代表top directory)的commit,top tree的id反过来取决于其成员的 id,而文件的 id 取决于其内容……而该内容将包括提交 id。不可能。

    但是让我们来看看不同的解决方案:

    实时、服务器端脚本

    如果您的网络应用程序是从非裸 git 存储库实时部署的(我希望您知道自己在做什么。推入非裸存储库,即带有结帐/工作树的存储库),那么您的网络应用程序可以检查 HEAD通过使用 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 的内容(这意味着提交带有7611062 的缩写SHA-1,提交标记为'v1.7.3.2' 后有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 存储库的签出(工作树)提供文件(不是您的情况),您可以使用 filtergitattribute 的 'smudge' 和 'clean' 命令执行 CVS - 类似于结帐/签入时的关键字扩展。

    在.gitattributes 文件中,您将定义filter 属性应该作用于的文件:

    *.rb 过滤器=commitid

    您在 git 配置文件中定义过滤器(例如在.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 部署

    如果您改为部署您的网络应用程序,因此它不会驻留在实时存储库中(它有其怪癖 wrt. 推入它,并且可能存在安全缺陷),并且您在某处使用 git archive(例如压缩应用程序将其上传到您的托管站点),您可以使用关键字替换。

    首先你需要告诉 Git 你想用git archive 替换文件中的关键字。您可以通过为给定文件设置export-subst 来做到这一点,例如通过添加到.gitattributes 文件

    *.rb 出口替代品

    然后添加到包含/生成页面页脚的文件中,例如

    $格式:%H$

    它将被提交哈希替换(参见漂亮格式描述,例如在git-log 手册页中)。


    已部署,使用一些部署脚本

    如果您使用某种脚本/脚本机制来部署您的网络应用程序,您应该遵循Jefromi advice 让您的部署脚本嵌入版本信息。

    您将不得不询问其他人如何设置Capistrano(假设您将其用于部署)以发布:部署将您的“app.rb”文件中的“@@VERSION@@”占位符替换为@的结果987654352@... Git 项目 Makefile uses sed for that.

    【讨论】:

      【解决方案2】:

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

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

      希望我没有误解你的情况——你说“Git 的一个可能的特性允许输出提交 ID”让我有点困惑。这是 git 的一个非常基础的能力。

      【讨论】:

      • "希望我没有误解你的情况——你说“允许输出提交 ID 的 Git 的一个可能特性”让我有点困惑。这是一个非常基本的能力混蛋。”我认为您没有误解 - 这是我解释它的方式......一如既往地过于复杂!我希望有一种方法可以让我认为有一段代码只输出当前的构建版本。我能想到的最简单的方法是 GIT HEAD 值。
      【解决方案3】:

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

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

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

      【讨论】:

      • 使用git rev-parse HEAD,而不是git log -n1 | ...
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-27
      • 2021-03-22
      • 1970-01-01
      • 2016-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多