2017-10-16 98 views
0

我有一个恼人的问题。我们正在运行linting作为预先提交的钩子。问题在于它正在工作目录而不是实际的提交。这有两个问题:如何提交提交,而不是工作目录?

  1. 提交是坏的,但linting通过。
    如果您在修复linting问题后忘记进行更改,则会发生这种情况。

  2. 承诺是好的,但linting失败。
    我经常有一些调试代码,我不打算提交。这些变化确实没有意义,而且处理起来很麻烦。

现在,问题是我该如何编写一个更智能的提交前钩子,而不是工作目录,最好不改变工作目录?

+0

仅限分段差异。 – ElpieKay

+0

听起来有棱角。不要构建依赖于预提交钩子的进程。它们只是为了方便而且很容易被禁用。我们使用不同的分支来代表我们产品的主要版本,并偶尔会向旧分支发布错误修复。由于我们使用最新版本的eslint,linting在基于旧版本的分支上失败。我们只是使用'--no-verify'来推送到服务器,但是我们的构建过程更加健壮,并且确保在合并发布分支之前(使用正确版本)通过(通过PR) – JDB

+0

@JDB Jenkins也会运行在提交之前将linting合并为master,所以该进程不依赖于预提交钩子。问题在于詹金斯通常超载,在实际运行之前可能需要很长时间。预先提交钩子是好的,因为它提供了更快的反馈,并防止Jenkins上不必要的负载。 –

回答

1

这一般很困难。

最直接的方法是将索引提取到临时目录中。这有一些明显的缺点:特别是,居住在工作树中的忽略文件不会被带入临时目录。更糟糕的是,临时目录只有这个存储库的文件:任何环境(例如子模块和/或超级项目)都不会被转移。

承载这些东西是可能的,但可能消耗很多空间和/或时间。

下面是将整个工作树(包括子模块)到一个临时目录,然后提取索引目录顶上是一个简单的方法:

#! /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 ... 

对于预提交的钩子想修改文件(例如,使用gofmtclang-format),这与一般想法混淆,因为现在修改的文件位于被删除的临时目录中。

+0

我建议使用'rsync'或'cp -ap'而不是2'tar's。除此之外 - 完美的答案! – phd

+0

谢谢。我还没有时间尝试这一点呢。一旦我确认它正在工作,我会接受你的答案。 –