Search code examples
gitantcheckstylepre-commit-hookpre-commit

Attempting to run pre-commit git hook for checkstyle returns multiple "File not found!" errors


I can run the checkstyle fine through ant on the command line. Unfortunately, with this pre-commit checkstyle git hook installed, when I try to commit via the git shell or cmd prompt I get the following (sample of) errors:

C:\mydirectory\M:0: File not found!
C:\mydirectoryr\:100644:0: File not found!
C:\mydirectory\100644:0: File not found!
C:\mydirectory\5cc4b0103c82b3a661fdc6ff59dc8d1b61a0c40b:0: File not found!
C:\mydirectory\73993b57357353af71a1485cfbaef41e94374b8e:0: File not found!
C:\mydirectory\M:0: File not found!
C:\mydirectory\:100644:0: File not found!
C:\mydirectory\100644:0: File not found!
C:\mydirectory\e7f29d65671ddb488de68b9b5886d24efefe9fd6:0: File not found!
C:\mydirectory\aea31a8e04ae560f2278fb860d1570de0ea41c82:0: File not found!
C:\mydirectory\M:0: File not found!
C:\mydirectory\:100644:0: File not found!
C:\mydirectory\100644:0: File not found!
C:\mydirectory\752c83417a18655b6f6f5ac1f4fe31a2933f0189:0: File not found!
C:\mydirectory\5ed1470dc9d4d8e16c1c34319578609b330aa58b:0: File not found!
C:\mydirectory\M:0: File not found!
C:\mydirectory\:100644:0: File not found!
C:\mydirectory\100644:0: File not found!
C:\mydirectory\4339530856664f202ec1d770d364945d9809e5e9:0: File not found!
C:\mydirectory\ef9f65deaab96aea185f3f5fc2184d5871a5f8ee:0: File not found!

where "mydirectory" is the path to the root of my web-app. I honestly have no idea what's going on. I've been up for hours working on this, so apologies if there isn't enough information. Ask any questions you have and I'll get back to you when I wake up. Thanks in advance.


Solution

  • I suspect you copied (cut and pasted) the sample code. In the process, a critical tab character in the sed command was replaced with spaces, which won't work: it really needs to be a tab.

    The sample hook could be improved to avoid the whole space-vs-tab distinction, by supplying --name-only to get the file names, eliminating the need for the sed ... | uniq part entirely. (It would also be wise to use a diff filter to extract only added-or-modified files, with rename detection explicitly disabled: add --diff-filter=AM --no-renames along with --name-only.) However, even this leaves the sample hook subtly wrong:

    • It uses git diff-index (spelled as git-diff-index, the old spelling before the great renaming) to find only those files that are modified in the index. This is good and correct.
    • But then it runs the style-checker on the files as found in the work-tree. If the work-tree files differ from the index contents, this is wrong; if they do not, the care used in the first step is unnecessary.

    Fixing the second problem is a bit tricky: it requires either:

    1. copying the index versions of the file to someplace else so that the style-checker can check them; or
    2. using git stash --keep-index to stash the work-tree versions away, replacing the work-tree versions with the versions that are intended to be committed. Once this is done, the git diff command must change, and after the check is run, the saved stash can be re-instated and the commit done or skipped as appropriate.

    Method 2 is the one I have seen used more often, but it requires extra care in case the git commit is run with no changes in place. In this case, the git stash step does nothing. In addition, there's a bug in git stash that no one seems to care enough to fix. If you choose Method 2, see this answer.