9

I am trimming whitespace from git commits using git diff-index --check --cached HEAD --. I want to add Jest tests using snapshots, but the snapshot files include whitespace and my tests will always fail if I remove it. So I want to exclude the *.js.snap files from the whitespace check. How do I tell git to exclude *.js.snap (or, alternatively, **/__snapshots/*) files from git diff-index? I'm using bash on OSX.

In the meantime, I'm working around the problem by changing my commit hook to be interactive:

# If there are whitespace errors, print the offending file names and fail.
git diff-index --check --cached HEAD --
if [ $? -ne 0 ]; then
    # Allows us to read user input below, assigns stdin to keyboard
    exec < /dev/tty

    while true; do
        echo "Your commit introduces trailing whitespace.  Are you sure you want to commit? y/n"
        read yn
        case $yn in
            y ) exit 0;;
            n ) exit 1;;
        esac
    done
fi
Rick Hanlon II
  • 20,549
  • 7
  • 47
  • 53
undefined
  • 6,208
  • 3
  • 49
  • 59

2 Answers2

3

Git does have a way of specifying paths to exclude, though it's poorly documented and apparently not very well known. It's known as pathspec, and in this case can be used as follows:

git diff-index --check --cached HEAD -- ':!*.js.snap' .

where : is the special character that specifies that the pathspec is not just a regular path, and '!' specifies that files matching the rest of the path should be excluded from the list of matches.

Not as straightforward as Mercurial's -X or --exclude, but it's there.

undefined
  • 6,208
  • 3
  • 49
  • 59
1

As mentioned here, the path argument of git diff-index is of glob-style pattern, interpreted by the shell.

So this is more a shell issue than a git command problem.

See for instance "How can I use inverse or negative wildcards when pattern matching in a unix/linux shell?"

You can either try and activate shopt extglob, or (simpler), do a post-step to your script, looking (with git status) for any modified files with **/__snapshots/* in their full pathname, and cancelling their modification (git checkout).

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Thanks for taking the time to answer. I spent quite a lot of time playing with negative wildcards and GLOBIGNORE, but neither would work. Both only seemed to work with patterns that don't include more than one wildcard (`**/*`). – undefined Oct 05 '16 at 23:18
  • I'll still award you the bounty since I can't give it to myself, not that you are concerned with reputation at this point! – undefined Oct 05 '16 at 23:19
  • @undefined Thank you for this feedback, and +1 to your answer. I mentioned pathspec before here: http://stackoverflow.com/a/38931091/6309 and http://stackoverflow.com/a/35622183/6309, with examples in http://stackoverflow.com/a/33462321/6309 – VonC Oct 06 '16 at 06:35