在Git中,如何将当前提交哈希写入同一提交中的文件

Fel*_*ura 118 git hook

我试图用Git钩子做一些奇特的东西,但我真的不知道怎么做(或者如果可能的话).

我需要做的是:在每次提交时,我想要获取其哈希值,然后使用此哈希值更新提交中的文件.

有任何想法吗?

Cas*_*bel 79

我建议您做一些类似于您的想法:将SHA1放在未跟踪的文件中,作为构建/安装/部署过程的一部分生成.这显然很容易(git rev-parse HEAD > filename或者可能git describe [--tags] > filename),并且它避免做任何疯狂的事情,比如结束与git的跟踪不同的文件.

然后,您的代码可以在需要版本号时引用此文件,或者构建过程可以将信息合并到最终产品中.后者实际上是git本身如何获得其版本号 - 构建过程从repo中获取版本号,然后将其构建到可执行文件中.

  • 有人可以一步一步地详细说明如何做到这一点吗?或者至少是朝着正确的方向推动? (4认同)

Bar*_*rtz 12

有人向我指出了关于ident的"man gitattributes"部分,其中包含:

IDENT

当为路径设置属性ident时,git用$ Id:替换blob对象中的$ Id $,后跟40个字符的十六进制blob对象名称,然后在结帐时使用美元符号$.任何以$ Id开头且以worktree文件中的$结尾的字节序列在签入时将替换为$ Id $.

如果你考虑一下,这就是CVS,Subversion等也是如此.如果查看存储库,您将看到存储库中的文件总是包含,例如$ Id $.它永远不会包含它的扩展.仅在结帐时才会扩展文本.

  • `ident`是文件本身的哈希,而不是提交的哈希.来自http://git-scm.com/book/en/Customizing-Git-Git-Attributes#Keyword-Expansion:"但是,该结果的用途有限.如果您在CVS或Subversion中使用了关键字替换,那么可以包含一个日期戳 - SHA并不是那么有用,因为它是相当随机的,你无法判断一个SHA是否比另一个更老或更新.`filter`需要工作,但它可以将提交信息输入(和输出)文件. (7认同)

kol*_*pto 11

编写当前提交哈希值是不可能的:如果您设法预先计算未来的提交哈希值 - 它会在您修改任何文件后立即更改.

但是,有三种选择:

  1. 使用脚本递增'commit id'并将其包含在某处.丑陋
  2. .gitignore你要存储哈希的文件.不是很方便
  3. pre-commit,存储以前的提交哈希 :)你没有在99.99%的情况下修改/插入提交,所以,这将工作.在最坏的情况下,您仍然可以识别源修订版.

我正在制作一个钩子脚本,将它发布在'完成后',但仍然 - 早于Duke Nukem Forever发布:))

UPD:代码.git/hooks/pre-commit:

#!/usr/bin/env bash
set -e

#=== 'prev-commit' solution by o_O Tync
#commit_hash=$(git rev-parse --verify HEAD)
commit=$(git log -1 --pretty="%H%n%ci") # hash \n date
commit_hash=$(echo "$commit" | head -1)
commit_date=$(echo "$commit" | head -2 | tail -1) # 2010-12-28 05:16:23 +0300

branch_name=$(git symbolic-ref -q HEAD) # http://stackoverflow.com/questions/1593051/#1593487
branch_name=${branch_name##refs/heads/}
branch_name=${branch_name:-HEAD} # 'HEAD' indicates detached HEAD situation

# Write it
echo -e "prev_commit='$commit_hash'\ndate='$commit_date'\nbranch='$branch'\n" > gitcommit.py
Run Code Online (Sandbox Code Playgroud)

现在我们唯一需要的是一个将对转换prev_commit,branch为实际提交哈希的工具:)

我不知道这种方法是否可以将合并提交分开.很快就会检查出来


leg*_*cia 10

这可以通过使用gitattributes中filter属性来实现.您需要提供一个插入提交ID的命令,以及一个删除它的命令,这样它插入的文件不会因为提交ID而改变.smudgeclean

因此,commit id永远不会存储在文件的blob中; 它只是扩展了你的工作副本.(实际上,将提交ID插入blob将成为无限递归的任务.)任何克隆此树的人都需要为自己设置属性.

  • **不可能**任务,而不是递归任务.提交哈希取决于依赖于文件哈希的树哈希,这取决于文件内容.你必须得到自我一致性.除非您为SHA-1哈希找到一种*[通用]定点*. (7认同)
  • 这是一个非常好的解决方案,但是请记住,这涉及到在克隆存储库时必须手动安装的挂钩。 (2认同)

小智 5

在提交框之外思考!

将其弹出到文件挂钩/检出后

#!/bin/sh
git describe --all --long > config/git-commit-version.txt
Run Code Online (Sandbox Code Playgroud)

您可以在任何使用该版本的地方使用该版本。