20

我希望我的远程存储库拒绝任何包含包含选项卡的文件的推送,但前提是该文件属于某个类(基于文件名)。那可能吗?
我看了一点update hookin githooks,我认为这是正确的。

简而言之,如果出现以下情况,则应拒绝推送:

  1. 有一个列出类型的文件 ( *.cpp, *.h, CMakeLists.txt)
  2. 包含一个或多个制表符。
4

3 回答 3

15

哦哦,这个问题好像漏掉了。希望你还在外面,埃斯本!

您正在寻找一个更新钩子,它为每个更新的 ref 运行一次。参数是 ref 的名称、旧对象名称(提交 SHA1)和新对象名称。

因此,您真正需要做的就是检查新旧之间的差异,并确保它符合您的标准。当然,这并不完全简单,但它是完全可以管理的。这是我要做的:

将以下脚本保存到.git/hooks/update.

old=$2
new=$3

# that's a literal tab, because (ba)sh turns \t into t, not a tab
# make sure your editor doesn't expand it to spaces
git diff --name-only $old $new | egrep '(\.(cpp|h)$)|^CMakeLists.txt$' | xargs -d'\n' git diff -U0 $old $new -- | grep -q '^+.* ' && exit 1

这列出了所有新旧文件之间的差异,所有所需文件的 greps,获取它们的差异(零行上下文,因为我们不在乎),以及添加行的 greps(以 开头+)包含一个选项卡。grep 如果找到一个则退出成功,这将让&&run exit 1,导致钩子退出失败并中止更新!

请注意,这与您的要求略有不同 - 它检查差异是否添加了任何制表符。从长远来看,这可能会更好;一旦你确定你现有的代码没问题,它就是同样的事情,除了更快,因为它不必搜索所有内容。

于 2010-11-10T14:44:20.090 回答
3

你可以设置一个pre-push hook,但这并不真正符合 git 发布机制的精神。

我宁愿选择:

  • 提交钩子,防止任何内容错误的提交
  • 过滤器驱动程序,您可以轻松地将其与正确的文件类型相关联,并且可以修复或报告任何不当内容。
于 2010-10-21T13:01:44.643 回答
1

根据benprew 的工作,这里有一个 pre-script 钩子,如果添加了任何制表符,则会显示错误,以及相关的行号。将以下内容保存到.git/hooks/pre-commit.

注意:pre-commit是文件名。不应该有任何.扩展名)

#!/bin/sh

if git rev-parse --verify HEAD 2>/dev/null
then
  git diff-index -p -M --cached HEAD
else
    :
fi |
perl -e '
    my $found_bad = 0;
    my $filename;
    my $reported_filename = "";
    my $lineno;
    sub bad_line {
        my ($why, $line) = @_;
        if (!$found_bad) {
            print STDERR "*\n";
            print STDERR "* You have some suspicious patch lines:\n";
            print STDERR "*\n";
            $found_bad = 1;
        }
        if ($reported_filename ne $filename) {
            print STDERR "* In $filename\n";
            $reported_filename = $filename;
        }
        print STDERR "* $why (line $lineno)\n";
        print STDERR "$filename:$lineno:$line\n";
    }
    while (<>) {
        if (m|^diff --git a/(.*) b/\1$|) {
            $filename = $1;
            next;
        }
        if (/^@@ -\S+ \+(\d+)/) {
            $lineno = $1 - 1;
            next;
        }
        if (/^ /) {
            $lineno++;
            next;
        }
        if (s/^\+//) {
            $lineno++;
            chomp;
            if (/   /) {
                bad_line("TAB character", $_);
            }
        }
    }
    exit($found_bad);
'

它不完全符合您的要求,因为它不进行任何文件名检查,但希望无论如何它都会有所帮助。

于 2017-04-03T22:45:44.267 回答