Why isn't my git pre-commit hook trimming white space from the end of lines?

Regarding your script : on your last instrcution before exiting, you probably wanted to call git diff rather than git diff-index, didn't you ?


Regarding the action "removing trailing whitespaces from my files before committing" :

  • most editors allow to run this action on file save, and it is probably the simplest way to have your trailing spaces removed from files you edited yourself

  • using git specific triggers : a more adapted way would be to use a clean filter in git attributes (see the Keyword Expansion section of the git book) :

clean filter

This would apply the changes when you "git add" each file, rather than when you commit :

# choose a name for your filter (e.g : 'trimspace'), and write
# the two 'clean' and 'smudge' action :
$ git config filter.trimspace.clean 'sed -e "s/[[:space:]]*$//g"'
$ git config filter.trimspace.smudge cat

# edit the `.gitattributes` file at the root of your repo,
# and target all the files you may want to trim :
$ cat .gitattributes
*.txt filter=trimspace
*.c filter=trimspace
*.py filter=trimspace
...

# from now on : running `git add` will auto trim targeted files when
# they are added to the index

First, make sure the hook is in a folder referenced by a global hook path (available since Git 2.9)

git config --global core.hooksPath /path/to/my/centralized/hooks

Then, check the pre-commit hook is executable, and actually runs: Add at least one echo at the start, to validate its execution on a commit.


The variable $against seems to be causing issue here. The $against variable is not initialized here which seems to be the cause for the failure.

As you mentioned that your code dies at that line. If I remove the line exec git diff-index --check --cached $against --, your code executes fine (no error situation).

Coming to that particular line: That line is used to print out any of the lines if whitespace still remains in them. But, I found that code is partially written.

The full code needs to be:

#!/bin/sh
#
# This hook script verifies that there are no whitespace errors in the files to be committed

if git rev-parse --verify HEAD >/dev/null 2>&1
then
 against=HEAD
else
 # Initial commit: diff against an empty tree object
 against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi

# Redirect output to stderr.
exec 1>&2

# If there are whitespace errors, print the offending file names and fail.
exec git diff-index --check --cached $against --

The code can be found at this site.

You need to perform a comparison in the last line but $against is undefined. This code will define it properly either to HEAD or some dummy tree object if HEAD is not present.

After adding this code, it works properly in my system (Ubuntu 16.04LTS, Git version 2.7.4)

Try adding the full code and let me know if it works for you.

Thanks