HOWTO: Automatically Fix / Remove Trailing Whitespace in Git via a Pre-commit Hook

Post date: 24-Aug-2011 19:34:44

Notes

The supplied shell script will not work with Mac OS X and possibly other non-GNU operating systems as their "sed" implementation takes different parameters. However you should be able to modify it to fit your environment.

HOWTO

If you are here, you've seen the trailing whitespace errors shown by Git when committing changes. These errors can indeed cause problems. Not only when e-mailing patches but also when working with weird glue tools such as git-p4 which relies on patches to sync changes to Perforce. One way to deal with these is ignoring them. While that works, it does only until whitespace introduces unintended change in a patch and things explode. To avoid that it is better to keep your files clean from trailing whitespace which can be easily achieved by using a pre-commit hook in Git. This hook is a script which is ran before each commit to do something useful. In this case to clean trailing whitespace. To install such a hook you can do the following:

  1. In a terminal of some sort, go to your working git repository ($GIT_DIR):
      1. cd $GIT_DIR
  2. Now open a new file for writing:
      1. cat > .git/hooks/pre-commit
  3. Paste the following code in the terminal:
      1. #!/bin/sh
      2. if git-rev-parse --verify HEAD >/dev/null 2>&1 ; then
      3. against=HEAD
      4. else
      5. # Initial commit: diff against an empty tree object
      6. against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
      7. fi
      8. # Find files with trailing whitespace
      9. for FILE in `exec git diff-index --check --cached $against -- | sed '/^[+-]/d' | sed -r 's/:[0-9]+:.*//' | uniq` ; do
      10. # Fix them!
      11. sed -i 's/[[:space:]]*$//' "$FILE"
      12. git add "$FILE"
      13. done
      14. exit
  4. Hit "Enter" and then "Control+D" to end editing.
  5. Finally, make the file executable:
      1. chmod +x .git/hooks/pre-commit

Now every time you commit changes, Git will run the hook and clear trailing whitespace before actually saving the changes.

Credits

The original shell script can be found here.