Подтвердить что ты не робот

Запретить нажимать на git, содержащий вкладки в определенных файлах (например, *.cpp, *.h, CMakeLists.txt)

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

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

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

Ответ 1

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

Вы ищете крюк обновления, который запускается один раз для каждого обновленного обновления. Аргументами являются имя ref, старое имя объекта (commit SHA1) и новое имя объекта.

Итак, все, что вам действительно нужно сделать, это проверить разницу между старым и новым и убедиться, что она соответствует вашим стандартам. Конечно, это не совсем понятно, но вполне управляемо. Вот что я буду делать:

Сохраните следующие script - .git/hooks/update.

old=$2
new=$3

# that 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 любые символы табуляции. Это, вероятно, лучше в долгосрочной перспективе; как только вы убедитесь, что ваш существующий код в порядке, это то же самое, за исключением гораздо более быстрого, так как ему не нужно искать весь контент.

Ответ 2

Вы можете настроить предварительный щелчок, но это не совсем в духе механизма публикации git.

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

  • a pre-commit hook, предотвращая фиксацию с неправильным контентом
  • или фильтр, который вы можете легко связать с нужными типами файлов, и который может исправить или сообщить о некорректном контенте.

Ответ 3

Основываясь на benprew's, вот крюк 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);
'

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