Git pre-commit hook: измененные / добавленные файлы

Я пишу хук перед фиксацией. Я хочу бежать php -l против всех файлов с расширением.php. Однако я застрял.

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

Я пытался использовать git diff а также git ls-files, но я думаю, что мне нужна помощь здесь.

6 ответов

Решение

git diff --cached --name-status покажет сводную информацию о том, что поставлено, так что вы можете легко исключить удаленные файлы, например:

M       wt-status.c
D       wt-status.h

Это указывает на то, что wt-status.c был изменен, а wt-status.h был удален в области стадирования (индекс). Итак, чтобы проверить только файлы, которые не были удалены:

steve@arise:~/src/git <master>$ git diff --cached --name-status | awk '$1 != "D" { print $2 }'
wt-status.c
wt-status.h

Вам придется перепрыгивать через дополнительные обручи, чтобы иметь дело с именами файлов с пробелами (опция -z для git diff и некоторые более интересные парсинги)

Немного аккуратный способ получить тот же список:

git diff --cached --name-only --diff-filter=ACM

Это вернет список файлов, которые необходимо проверить.

Но только бег php -l на вашей рабочей копии, возможно, не то, что нужно делать. Если вы делаете частичную фиксацию, то есть просто выбираете подмножество различий между вашим текущим рабочим набором и HEAD для фиксации, тогда тест будет выполняться на вашем рабочем наборе, но будет сертифицировать фиксацию, которой никогда не было на вашем диск.

Чтобы сделать это правильно, вы должны извлечь все подготовленное изображение во временную область и выполнить тест там.

rm -rf $TEMPDIR
mkdir -p $TEMPDIR
git checkout-index --prefix=$TEMPDIR/ -af
git diff --cached --name-only --diff-filter=ACM | xargs -n 1 -I '{}' \bin\echo TEMPDIR/'{}' | grep \\.php | xargs -n 1 php -l

См. Создание лучшего хука перед фиксацией для Git для другой реализации.

Ни один из ответов здесь не поддерживает имена файлов с пробелами. Лучший способ для этого - добавить -z флаг в сочетании с xargs -0

git diff --cached --name-only --diff-filter=ACM -z | xargs -0 ...

Это то, что дает git во встроенных примерах (см. .Git / hooks / pre-commit.sample)

Вот что я использую для проверки Perl:

git diff --cached --name-status | while read st file; do
        # skip deleted files
        if [ "$st" == 'D' ]; then continue; fi
        # do a check only on the perl files
        if [[ "$file" =~ "(.pm|.pl)$" ]] && ! perl -c "$file"; then
                echo "Perl syntax check failed for file: $file"
                exit 1
        fi
done

для PHP это будет выглядеть так:

git diff --cached --name-status | while read st file; do
        # skip deleted files
        if [ "$st" == 'D' ]; then continue; fi
        # do a check only on the php files
        if [[ "$file" =~ ".php$" ]] && ! php -l "$file"; then
                echo "PHP syntax check failed for file: $file"
                exit 1
        fi
done

git diff --cached недостаточно, если вызов commit был указан с флагом -a, и нет способа определить, был ли этот флаг брошен в ловушку. Было бы полезно, если бы аргументы для коммитов были доступны хуку для изучения.

чтобы понять, что файлы изменились в конкретной папке, я делаю так:

      modifiedFrontendFiles=$(git diff --cached --name-status --relative=frontend)

if [ -n "$modifiedFrontendFiles" ]; then
    npm run lint
    npm run lint-css
    npm run format
    git add .
fi

в моем случае я проверяю, что изменения находятся в папке внешнего интерфейса

Другие вопросы по тегам