Git:获取工作树当前状态的哈希值?

时间:2014-05-29 18:06:10

标签: git version-control

我想确保我的可执行文件是使用最新版本的代码构建的。

例如,我可以在编译时获取当前的git提交并将其烘焙到可执行文件中;然后,当运行可执行文件时,它会将其与当前的git提交进行比较,如果它们不匹配,则会抱怨代码已被修改并且已过期。

但是,在对代码进行少量更改后,有时我会在不进行提交的情况下重新编译。然后这种方法不起作用,因为它只考虑了已提交的更改。

有没有方便的方法以编程方式获取当前提交的哈希值PLUS工作目录的状态,使用git或其他方式?

此外,这种做法有名称吗?

2 个答案:

答案 0 :(得分:3)

可以在当前工作树中创建和存储大多数更改,包括所有暂存,未暂存和未跟踪的文件,同时尊重.gitignore。粗略地说,需要

#!/bin/sh
{   git diff-index --name-only HEAD
    git ls-files -o --exclude-standard
} \
| while read path; do
    test -f "$path" && printf "100644 blob %s\t$path\n" $(git hash-object -w "$path");
    test -d "$path" && printf "160000 commit %s\t$path\n" $(cd "$path"; git rev-parse HEAD);
done | sed 's,/,\\,g' | git mktree --missing

第一个差异列出了与HEAD不同的所有跟踪文件。

然后我们找到未跟踪的,但排除被忽略的。

然后,我们将这两个命令的输出通过管道输出,为所有文件构建git mktree输入。

它的输出经过sed,因为git mktree没有递归构造树,但这里的实际路径并不重要,因为我们只想要一个哈希码,没有一个存储实际内容以供检索。

最后,我们将此ls-tree格式化的输出传递给mktree,它构造指定的树并将其存储在Git中,并将哈希输出给我们。

通过一些额外的努力,我们还可以保留有关permissions甚至文件删除的信息。毕竟,这是Git在您进行实际提交时所做的事情。

有人可能会争辩说,所有这些环节在您希望存储更改以供将来参考的情况下非常有用,但是不希望在每次微小更改时对不必要的提交污染索引。因此,使用 micro -releases进行内部测试可能很有用,您可以将本地哈希记录为代码的实际版本,而不仅仅是非描述性-dirty标记,当您忘记为每个工作版本标记或提交代码时,查看代码的确切位置。有些人可能认为这是一个坏习惯,应该强迫你为每一次成功的构建做出承诺,无论多么小 - 很难与之争论,但话又说明了一切都是为了方便。

答案 1 :(得分:2)

如果你想做的就是确定是否任何未提交的修改,那很容易;只需运行git diff --quiet HEAD并检查返回码是否为非零。

如果您确实需要更改的哈希,那么具有相同的起始提交和相同的本地修改的两个用户将获得相同的哈希,这更棘手。我的第一个想法是将git diff HEAD的输出传递给sha1sum,并将其连接到提交哈希,但git diff的输出可能因不同的Git版本和配置选项而异。

或者,您可以使用git add -u . && git write-tree为当前工作树获取诚实的Git树对象。但这是一种破坏性的行动;它破坏了你指数中已经存在的部分阶段性变化。