Запретите нажатия на git, содержащие вкладки в определенных файлах (например, * .cpp, * .h, CMakeLists.txt) - PullRequest
17 голосов
/ 21 октября 2010

Я бы хотел, чтобы мой удаленный репозиторий отклонял любые нажатия, содержащие файл с вкладкой, но только если файл принадлежит к определенному классу (на основе имени файла). Это возможно?
Я немного посмотрел на update hook в githooks, и я думаю, что это правильно.

Короче говоря, толчок должен быть отклонен, если:

  1. существует файл перечисленных типов (*.cpp, *.h, CMakeLists.txt)
  2. , содержащий один или несколько символов табуляции.

Ответы [ 3 ]

15 голосов
/ 10 ноября 2010

О-о, этот вопрос, похоже, проскочил сквозь трещины.Надеюсь, вы все еще там, Эсбен!

Вам нужен хук обновления , который запускается один раз для каждого обновления ссылки.Аргументами являются имя ссылки, имя старого объекта (commit 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 для всех желаемых, получает diff для них (с нулевыми строками контекста, так как нам все равно) и greps для добавленной строки (начиная с +), содержащей вкладку.Grep завершается успешно, если находит, что позволяет && запустить exit 1, что приводит к выходу из строя хука и отмене обновления!

Обратите внимание, что это немного отличается от ваших требований - он проверяетесли diff добавляет какие-либо символы табуляции.Это, вероятно, лучше в долгосрочной перспективе;как только вы убедились, что с вашим существующим кодом все в порядке, это то же самое, за исключением того, что намного быстрее, так как ему не нужно искать весь контент.

3 голосов
/ 21 октября 2010

Вы можете установить pre-push hook , но это не совсем в духе механизма публикации git.

Я бы предпочел:

1 голос
/ 04 апреля 2017

Основываясь на работе 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);
'

Это не точно , что вы просили, так как он не выполняет никакой проверки имени файла, но, надеюсь, это поможет независимо.

...