How can I tell if git was executed with the "-a" flag in a pre-commit hook?

305 views Asked by At

I've got a git pre-commit hook which does linting. When it's invoked, it loops over the staged files and runs a linter on them. This works great.

However, when you run git commit -am 'Foo' it runs without having any staged files. How can I tell if it was invoked with -a or the --all flag? Is there an easier way to get the files which will be stored in git?

1

There are 1 answers

0
torek On

All the files in the index will be stored. You're looking for "files in the index that differ from their counterparts in HEAD", which you can find with git diff—or for scripts, git diff-index.

Note that the staged version may differ from the work-tree version as well, making checking everything especially annoying and tricky. (For an example, run git add -p on some complex change, and select part of it.)

Here's an example of a dummy pre-commit hook that shows the name and status of each file with respect to HEAD, i.e., what's different in the index vs the existing HEAD commit.

#! /bin/sh

git diff-index --cached -r --name-status HEAD

echo pre-commit fail
exit 1

Your task is to take the output from git diff-index --cached -r --name-status HEAD (perhaps with -z added, perhaps not) and figure out how to test the versions that are in the index, not the versions that are in the work-tree.

Note that you can use git checkout-index to extract the index to a work-tree. Of course, you'll want to avoid overwriting the real work tree, i.e., to establish a temporary work-tree elsewhere:

TMPTREE=$(mktemp -d)
...
git --work-tree=$TMPTREE checkout-index -- .

for instance. You may want to establish a temporary index, other than the regular index, for this as well, since this may disturb the cache aspect of the regular index:

TMPINDEX=$(mktemp)
NORMINDEX=${GIT_INDEX_FILE:-$(git rev-parse --git-dir)/.index}
cp $NORMINDEX $TMPINDEX
GIT_INDEX_FILE=$TMPINDEX GIT_WORK_TREE=$TMPTREE checkout-index -- .

Be sure to clean up your temporary files and/or directories when done.

(None of these code fragments is tested.)