我有一个恼人的问题。我们正在运行linting作为预先提交的钩子。问题在于它正在工作目录而不是实际的提交。这有两个问题:如何提交提交,而不是工作目录?
提交是坏的,但linting通过。
如果您在修复linting问题后忘记进行更改,则会发生这种情况。承诺是好的,但linting失败。
我经常有一些调试代码,我不打算提交。这些变化确实没有意义,而且处理起来很麻烦。
现在,问题是我该如何编写一个更智能的提交前钩子,而不是工作目录,最好不改变工作目录?
我有一个恼人的问题。我们正在运行linting作为预先提交的钩子。问题在于它正在工作目录而不是实际的提交。这有两个问题:如何提交提交,而不是工作目录?
提交是坏的,但linting通过。
如果您在修复linting问题后忘记进行更改,则会发生这种情况。
承诺是好的,但linting失败。
我经常有一些调试代码,我不打算提交。这些变化确实没有意义,而且处理起来很麻烦。
现在,问题是我该如何编写一个更智能的提交前钩子,而不是工作目录,最好不改变工作目录?
这一般很困难。
最直接的方法是将索引提取到临时目录中。这有一些明显的缺点:特别是,居住在工作树中的忽略文件不会被带入临时目录。更糟糕的是,临时目录只有这个存储库的文件:任何环境(例如子模块和/或超级项目)都不会被转移。
承载这些东西是可能的,但可能消耗很多空间和/或时间。
下面是将整个工作树(包括子模块)到一个临时目录,然后提取索引目录顶上是一个简单的方法:
#! /bin/sh -e
tmpdir=$(mktemp -d)
trap "rm -rf $tmpdir" 0 1 2 3 15
# remainder assumes we are at top of work-tree, which is true in
# practice in git hooks, even if it is not documented anywhere.
# step 1: copy current tree to tmp dir
tar cf - . | (cd $tmpdir; tar xf -)
# step 2: extract current index to tmp dir
git --work-tree=$tmpdir checkout -- .
# step 3: run tests
... tests go here ...
对于预提交的钩子想修改文件(例如,使用gofmt
或clang-format
),这与一般想法混淆,因为现在修改的文件位于被删除的临时目录中。
我建议使用'rsync'或'cp -ap'而不是2'tar's。除此之外 - 完美的答案! – phd
谢谢。我还没有时间尝试这一点呢。一旦我确认它正在工作,我会接受你的答案。 –
仅限分段差异。 – ElpieKay
听起来有棱角。不要构建依赖于预提交钩子的进程。它们只是为了方便而且很容易被禁用。我们使用不同的分支来代表我们产品的主要版本,并偶尔会向旧分支发布错误修复。由于我们使用最新版本的eslint,linting在基于旧版本的分支上失败。我们只是使用'--no-verify'来推送到服务器,但是我们的构建过程更加健壮,并且确保在合并发布分支之前(使用正确版本)通过(通过PR) – JDB
@JDB Jenkins也会运行在提交之前将linting合并为master,所以该进程不依赖于预提交钩子。问题在于詹金斯通常超载,在实际运行之前可能需要很长时间。预先提交钩子是好的,因为它提供了更快的反馈,并防止Jenkins上不必要的负载。 –