为什么git的预提交钩子会验证HEAD是否存在?

时间:2016-06-13 09:29:55

标签: git githooks pre-commit-hook

在它的预提交钩子git似乎验证HEAD存在。如果它没有默认为空树的特殊散列来比较索引。

if git rev-parse --verify HEAD >/dev/null 2>&1
then
        against=HEAD
else
        # Initial commit: diff against an empty tree object
        against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi

默认的哈希值是一个特殊的哈希值。我读到我也可以通过

获得它
git hash-object -t tree < /dev/null

against稍后会像这样使用

# If there are whitespace errors, print the offending file names and fail.
exec git diff-index --check --cached $against --

为什么钩子会这样做?在什么情况下我能够提交但是HEAD会无效?

1 个答案:

答案 0 :(得分:1)

HEAD始终指向当前提交,因为:

  • 它包含当前分支的名称(例如ref: refs/heads/master)或
  • 它直接指向实际的提交ID(&#34;分离的HEAD&#34;),因此它包含原始的SHA-1哈希字符串。

如果HEAD包含原始哈希值,那么HEAD肯定是有效的,因为它必须指向真正的提交。但是......在一个全新的空库中会发生什么?

您位于分支master上,因此HEAD会读取ref: refs/heads/master。但分支master的提示是什么? master本身存储了哪些提交ID?

存储库中没有提交。你会在哪里master点?

Git解决此问题的方法是让master无效。 git rev-parse --verify HEAD失败时的情况:HEADmaster,但master尚不存在。

在内部,Git将此称为&#34;未出生的分支&#34;,或有时&#34;孤儿分支&#34;。使用git checkout --orphan newbranch将Git置于新创建的相同状态(除非它真的没有创建)分支newbranchHEAD引用现在包含ref: refs/heads/newbranch,但仍然没有newbranch。因此,每个未出生的分支状态都是这样的,但每次创建一个新的空库时,都会看到一个特定的状态。