В качестве подхода наилучшей практики рассмотрим:
#!/usr/bin/env bash
# ^^^^ important: [[ ]] is not guaranteed to work with bin/sh
whitelist_re='(foo|bar)'
workdir=/home/athur/workwork/test/repo
cd -- "$workdir" || exit
git add -A
while IFS= read -r filename; do
if [[ $file =~ $whitelist ]]; then
echo "$file is on whitelist" >&2
else
echo "$file is not on whitelist; commit aborted." >&2
exit 1
fi
done < <(git diff --cached --name-only)
Чтобы пройти через изменения:
- Shebang указывает
bash
как оболочку, которая гарантирует, что расширения, такие как [[ ]]
и <(...)
, будут доступны - гарантия не сделана с /bin/sh
.
- Цикл
while read
используется вместо того, чтобы пытаться перебрать ориентированные на строки данные с for
; см. DontReadLinesWithFor для объяснения причин этого изменения.
- Белый список задается как ERE-совместимое регулярное выражение, так что
=~
можно использовать для проверки соответствия значения.
- Вместо использования
git diff --cached --name-status
и последующего использования cut
для последующего удаления данных о статусе мы используем --name-only
для генерации только имен.
- Использование имен переменных в нижнем регистре соответствует соглашениям, приведенным в http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html,, определяя, что определяемые POSIX инструменты будут использовать имена переменных оболочки и окружения all-caps для своих собственных целей, и что имена, содержащие как минимум один символ нижнего регистра, являются зарезервировано для использования приложения. (Имейте в виду, что установка переменной оболочки перезаписывает любую переменную среды с таким же именем, поэтому эти соглашения применяются, даже если
export
не используется).
Кстати, если вы просто хотите узнать, существуют ли какие-либо несоответствия, не зная, какие это файлы, вы можете использовать:
#!/bin/sh
# ^^ actually safe here, as no non-POSIX functionality is used
whitelist_re='foo|bar'
if git diff --cached --name-only | grep -qEv "$whitelist_re"; then
echo "At least one file is not on whitelist; commit aborted" >&2
exit 1
fi