NOTE:
对于那些寻找最新的、(或多或少)全面且经过充分测试的解决方案的人,我托管相应的公共存储库 [1 http://bitbucket.Alexander.Shukaev.name/git-hooks]。目前,两个重要的钩子依赖于git-clang-format
已实施:pre-commit
and pre-receive
。理想情况下,同时使用它们时,您可以获得最自动化和最简单的工作流程。与往常一样,我们非常欢迎提出改进建议。
NOTE:
目前,pre-commit
hook [1 http://bitbucket.Alexander.Shukaev.name/git-hooks] 要求git-clang-format.diff
补丁(也是我写的)[1 http://bitbucket.Alexander.Shukaev.name/git-hooks] 应用于git-clang-format
。该补丁的动机和用例示例总结在提交给 LLVM/Clang 的官方补丁审查中 [2 http://reviews.llvm.org/D15465]。希望它很快就会被上游接受并合并。
我已经设法实现第二个问题的解决方案。我不得不承认,由于 Git 文档稀少且缺乏示例,所以很难找到它。我们先看一下对应的代码改动:
# ...
clang_format() {
git clang-format --commit="${commit}" --style='file' "${@}"
}
# ...
for sha1 in $(list "${sha1_range}"); do
git checkout --force "${sha1}" > '/dev/null' 2>&1
if [ "$(list --count "${sha1}")" -eq 1 ]; then
commit='4b825dc642cb6eb9a060e54bf8d69288fbee4904'
else
commit='HEAD~1'
fi
diff="$(clang_format --diff)"
# ...
done
# ...
正如你所看到的,而不是重复做git reset --soft 'HEAD~1'
,我现在明确指示git-clang-format
进行操作HEAD~1
与--commit
选项(而其默认值是HEAD
这在我的问题中提出的初始版本中有所暗示)。然而,这仍然不能单独解决问题,因为当我们遇到root提交这将再次导致错误,如下所示HEAD~1
将不再引用有效的修订版(类似于不可能执行的操作)git reset --soft 'HEAD~1'
)。这就是为什么对于这个特殊情况,我指示git-clang-format
对抗(魔法)4b825dc642cb6eb9a060e54bf8d69288fbee4904
hash [3 http://colinschimmelfing.com/blog/gits-empty-tree/, 4 https://stackoverflow.com/q/9765453/1743860, 5 http://git.wiki.kernel.org/index.php/Aliases#Obtaining_the_Empty_Tree_SHA1, 6 http://comments.gmane.org/gmane.comp.version-control.git/180511]。要了解有关此哈希的更多信息,请查阅参考资料,但简而言之,它指的是 Git空树对象— 没有任何上演或承诺的内容,这正是我们所需要的git-clang-format
在我们的例子中进行操作。
NOTE:
你不必记住4b825dc642cb6eb9a060e54bf8d69288fbee4904
用心记住,最好不要对其进行硬编码(以防万一这个神奇的哈希值将来会发生变化)。事实证明,它总是可以检索git hash-object -t tree '/dev/null'
[5 http://git.wiki.kernel.org/index.php/Aliases#Obtaining_the_Empty_Tree_SHA1, 6 http://comments.gmane.org/gmane.comp.version-control.git/180511]。因此,在我上述的最终版本中pre-receive
钩子,我有commit="$(git hash-object -t tree '/dev/null')"
反而。
P.S.我仍在寻找第一个问题的高质量答案。顺便说一句,我在官方 Git 邮件列表上提出了这些问题,但到目前为止还没有收到答案,真是遗憾......