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

j'écris un crochet pré-commit. Je veux lancer php -l contre tous les fichiers avec .PHP extension. Cependant, je suis coincé.

j'ai besoin d'obtenir une liste des fichiers nouveaux/modifiés qui sont mis en scène. 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.

54
demandé sur igorw 2010-03-09 23:49:01

5 réponses

git diff --cached --name-status montrera un résumé de ce qui est mis en scène, de sorte que vous pouvez facilement exclure les fichiers supprimés, par exemple:

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

indique le statut wt.c a été modifié et le statut wt.h a été enlevé dans la zone de rassemblement (indice). Ainsi, pour vérifier seulement les fichiers qui n'ont pas été supprimés:

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

, Vous devez sauter à travers les cerceaux de traiter avec les noms de fichiers avec des espaces bien (option-z pour git diff et un peu plus intéressante analyse)

42
répondu araqnid 2017-03-13 00:31:46

une façon légèrement plus claire d'obtenir la même liste est:

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

renvoie la liste des fichiers à vérifier.

mais lancer php -l sur votre copie de travail n'est peut-être pas la bonne chose à faire. Si vous faites une partielle s'engager c'est à dire juste en sélectionnant un sous-ensemble des différences entre votre travail actuel et la TÊTE pour la validation, le test sera exécuté sur votre jeu de travail, mais sera de certification une révision qui n'a jamais existé sur votre disque.

pour le faire correctement, vous devez extraire toute l'image mise en scène à une zone de température et effectuer le test là .

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 la Construction d'une meilleure pre-commit hook Git pour une autre mise en œuvre.

76
répondu LarryH 2013-07-22 14:44:23

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 il 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
7
répondu Marian HackMan Marinov 2010-11-05 23:45:06

aucune des réponses ici ne supporte les noms de fichiers avec des espaces. La meilleure façon pour cela est d'ajouter le drapeau -z en combinaison avec xargs -0

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

C'est ce qui est donné par git dans les échantillons intégrés (voir .git/hooks / pre-commit.échantillon )

7
répondu eddygeek 2017-02-20 13:05:15

git diff --cached n'est pas suffisante si le commit appel a été spécifié avec l'option-a, et il n'y a aucun moyen de déterminer si le drapeau a été lancée dans le crochet. Il serait utile si les arguments à commettre devraient être disponibles au crochet pour l'examen.

1
répondu mpersico 2015-09-10 17:16:44