Trying to make a php syntax check hook for a git repository. I was happy when I found a code snippet that does exactly this.
But it seems that the snippet script has a flaw. It executes
git diff-index --cached --name-only HEAD
to get a list of files in the index. Now it runs php -l for each file on that list. The flaw is that a file might differ between the working copy and the staging area. If the staging area php has a syntax error, but the working copy version doesnt, no syntax error is found and the committ succeeds which was the thing to prevent.
Is this a nontrivial problem to solve, or is there some way to run php -l on the staging-version of each file?
The hooks are all stored in the hooks subdirectory of the Git directory. In most projects, that's . git/hooks .
If you want to manually run all pre-commit hooks on a repository, run pre-commit run --all-files . To run individual hooks use pre-commit run <hook_id> . The first time pre-commit runs on a file it will automatically download, install, and run the hook.
Conceptual Overview. All Git hooks are ordinary scripts that Git executes when certain events occur in the repository. This makes them very easy to install and configure. Hooks can reside in either local or server-side repositories, and they are only executed in response to actions in that repository.
I'm very happy using this php syntax validation hook. Hope it will fit your needs too.
It uses git diff-index --cached --full-index
.
I am not sure if there is a problem here.
The snippet you mention probably comes from the blog post Don’t Commit That Error.
And it includes:
Next, we call
git diff-index
with a few parameters.
First, we add--cached
to tell Git we only want files that are going to be committed.
Then, we add--name-only
to tell Git to only output the name of the files that are being committed.
It seems the files which are about to be committed are precisely the ones a pre-commit hook would want to inspect.
Even if they differ from the files in the working directory, it is their version (in the index) which is to be committed. And it is that same version which will be send to the php -l
process.
Actually, the problem is not in the git diff-index
itself (with or without --full-index
) is in the way you will read the file content in the index
exec("php -l " . escapeshellarg($file), $lint_output, $return);
result=$(git cat-file -p $sha | /usr/bin/env $PHP_BIN -l 2>/dev/null)
Using git cat-file
is the key here, to access an object in the Git repo (i.e. not in the "working directory")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With