防止推送到包含某些文件中的选项卡的 git(例如 *.cpp、*.h、CMakeLists.txt)

发布于 2024-09-28 13:56:28 字数 276 浏览 5 评论 0原文

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

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

  1. 存在列出类型的文件(*.cpp*.hCMakeLists.txt)
  2. 包含一个或多个制表符。

I'd like my remote repository to refuse any pushes that contains a file that contains a tab, but only if the file belongs in a certain class (based on the filename). Is that possible?
I have looked a bit at the update hook in githooks, and I think that is the correct one.

So in short, a push should be rejected if:

  1. there is a file of the listed types (*.cpp, *.h, CMakeLists.txt)
  2. that contains one or more tab characters.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

想你的星星会说话 2024-10-05 13:56:28

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

您正在寻找一个 更新挂钩,该挂钩针对每个更新的引用运行一次。参数是引用的名称、旧对象名称(提交 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

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

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

| xargs -d'\n' git diff -U0 $old $new -- | grep -q '^+.* ' && exit 1

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

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

Uh oh, this question seems to have slipped through the cracks. Hope you're still out there, Esben!

You're looking for an update hook, which is run once for each ref updated. The arguments are the name of the ref, the old object name (commit SHA1), and the new object name.

So, all you really need to do is check the diff between the old and new and make sure it meets your standards. This isn't totally straightforward, of course, but it's totally manageable. Here's what I'd do:

Save the following script to .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

That lists all the files which differ between the old and new, greps for all the desired ones, gets the diff for them (with zero lines of context, since we don't care), and greps for an added line (starting with +) containing a tab. The grep exits success if it finds one, which will let the && run exit 1, causing the hook to exit failure and abort the update!

Note that this is slightly different from your requirements - it checks if the diff adds any tab characters. This is probably better in the long run; once you've made sure your existing code's okay, it's the same thing, except much faster since it doesn't have to search all the content.

| xargs -d'\n' git diff -U0 $old $new -- | grep -q '^+.* ' && exit 1

That lists all the files which differ between the old and new, greps for all the desired ones, gets the diff for them (with zero lines of context, since we don't care), and greps for an added line (starting with +) containing a tab. The grep exits success if it finds one, which will let the && run exit 1, causing the hook to exit failure and abort the update!

Note that this is slightly different from your requirements - it checks if the diff adds any tab characters. This is probably better in the long run; once you've made sure your existing code's okay, it's the same thing, except much faster since it doesn't have to search all the content.

断桥再见 2024-10-05 13:56:28

您可以设置一个 预推送挂钩,但这并不是真正的本着 git 发布机制的精神。

我宁愿选择:

You could setup a pre-push hook, but this is not really in the spirit of the git publication mechanism.

I would rather go with:

  • a pre-commit hook, preventing any commit with the wrong content
  • or a filter driver that you can easily associate with the right types of file, and which can fix or report any improper content.
四叶草在未来唯美盛开 2024-10-05 13:56:28

基于 benprew 的工作,这里有一个预脚本挂钩,如果任何制表符字符存在,它会显示错误已添加,以及相关的行号。将以下内容保存到 .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);
'

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

Based on benprew's work, here's a pre-script hook that displays an error if any tab characters have been added, as well as the relevant line number. Save the following to .git/hooks/pre-commit.

(Note: pre-commit is the filename. There shouldn't be any . extension)

#!/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);
'

It's not exactly what you asked for since it doesn't do any filename checking, but hopefully it helps regardless.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文