Friday, March 7, 2014

Cleaning up whitespace additions in git

I wrote a previous post on cleaning up end of line whitespace using git... But I've now run into a similar issue, the IDE used by several of the devlopers on my project
likes to change surrounding whitespace indentation of lines. This means if you change just one line, the indentation changes will swamp the real changes, making the diff unhappy to look at.

You can view a diff without showing whitespace changes in git using --ignore-space-change or --ignore--all-space. However unforunately the command

git rebase -f master --ignore-space-change


doesn't do what one might hope.

However all is not lost. You can get the same kind of behaviour by plumbing together git format-patch and git am.

git branch fixed 40caad7
git checkout fixed
git format-patch --stdout --ignore-all-space fixed..original | git am --ignore-whitespace


This takes the the changes from 40caad7 to original and applies them to the new fixed branch, but removes/fixes whitespace changes.

however this is not nice to use - so you can wrap it up into a little git alias like this: (newlines inserted for clarity - you'll need to remove them if you use it)

[alias]
cleanwhite = "!f() {
⏎  orig=$(git rev-parse HEAD) ; ⏎ mergebase=$(git merge-base HEAD $1) ; ⏎ git reset --hard$1 ;
⏎  git format-patch --stdout --ignore-all-space $mergebase..$orig | git am --ignore-whitespace ;
⏎ } ; f"


Now cleaning up your current base is as simple as

\$ git cleanwhite master


Which will clean up all commits whitespace from your current commit back to where you diverged from master.