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
в моем случае я проверяю, что изменения находятся в папке внешнего интерфейса