web-dev-qa-db-fra.com

Git pré-commit hook: fichiers modifiés / ajoutés

J'écris un hook de pré-validation. Je veux courir php -l contre tous les fichiers avec l'extension .php. Cependant je suis coincé.

J'ai besoin d'obtenir une liste des fichiers nouveaux/modifiés qui sont mis en scène. les fichiers supprimés doivent être exclus.

J'ai essayé d'utiliser git diff et git ls-files, mais je pense que j'ai besoin d'un coup de main ici.

58
igorw

git diff --cached --name-status affichera un résumé de ce qui est organisé, vous pouvez donc facilement exclure les fichiers supprimés, par exemple:

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

Cela indique que wt-status.c a été modifié et wt-status.h a été supprimé dans la zone de transit (index). Donc, pour vérifier uniquement les fichiers qui n'ont pas été supprimés:

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

Vous devrez sauter à travers des cerceaux supplémentaires pour gérer les noms de fichiers avec des espaces (option -z pour git diff et une analyse plus intéressante)

47
araqnid

Une manière un peu plus soignée d'obtenir la même liste est:

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

Cela renverra la liste des fichiers qui doivent être vérifiés.

Mais juste en cours d'exécution php -l sur votre copie de travail n'est peut-être pas la bonne chose à faire. Si vous effectuez une validation partielle, c'est-à-dire en sélectionnant simplement un sous-ensemble des différences entre votre ensemble de travail actuel et le HEAD pour la validation, alors le test sera exécuté sur votre ensemble de travail, mais sera certifiant une validation qui n'a jamais existé sur votre disque.

Pour le faire correctement, vous devez extraire toute l'image mise en scène dans une zone temporaire et y effectuer le test.

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

Voir Construire un meilleur hook de pré-validation pour Git pour une autre implémentation.

86
LarryH

Voici ce que j'utilise pour mes vérifications 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

pour PHP cela ressemblera à ceci:

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
10

Aucune des réponses ici ne prend en charge les noms de fichiers avec des espaces. La meilleure façon d'y parvenir est d'ajouter le -z drapeau en combinaison avec xargs -0

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

C'est ce que donne git dans les exemples intégrés (voir . Git/hooks/pre-commit.sample)

8
eddygeek

git diff --cached n'est pas suffisant si l'appel de validation a été spécifié avec l'indicateur -a, et il n'y a aucun moyen de déterminer si cet indicateur a été jeté dans le hook. Il serait utile que les arguments à valider soient disponibles pour le crochet pour examen.

0
mpersico