Git pre-commit hook : changed/added files

A slightly neater way of obtaining the same list is:

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

This will return the list of files that need to be checked.

But just running php -l on your working copy may not be the right thing to do. If you are doing a partial commit i.e. just selecting a subset of the differences between your current working set and the HEAD for the commit, then the test will be run on your working set, but will be certifying a commit that has never existed on your disk.

To do it right you should extract the whole staged image to a temp area and perform the test there .

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

See Building a better pre-commit hook for Git for another implementation.


git diff --cached --name-status will show a summary of what's staged, so you can easily exclude removed files, e.g.:

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

This indicates that wt-status.c was modified and wt-status.h was removed in the staging area (index). So, to check only files that weren't removed:

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

You will have to jump through extra hoops to deal with filenames with spaces in though (-z option to git diff and some more interesting parsing)