16

I'd like to commit all my whitespace corrections in their own commit, to keep everything else pure from whitespace changes.

It's easy to filter out whitespace differences with git diff using something like this

git diff --ignore-all-space --ignore-space-change --ignore-space-at-eol --ignore-blank-lines

but how do I get a listing of only whitespace differences?

(It would also be useful to get a list of files that only have whitespace differences, so I can just add them all without going through them with git add -p to pick out the whitespace differences. But I suppose that's secondary.)

iconoclast
  • 21,213
  • 15
  • 102
  • 138
  • 1
    `diff -u <(git diff --stat --ignore-all-space --ignore-space-change --ignore-space-at-eol --ignore-blank-lines) <(git diff --stat)` for your second question, maybe? – Ry- Jun 26 '14 at 23:58

2 Answers2

3

Here's one way you could do it:

  • Start with a clean working directory (e.g. git reset --hard)

  • Use Whitespace Total Fixer to clean up all the whitespace errors. There are options to fix or ignore various issues but the default may be fine:

      find . -name "*.whatever_extension_you_need" -exec wtf -v -i {} \;
    
  • git diff will now show only the whitespace changes

  • Stage and commit the whitespace-only changes.

(FWIW, I wrote wtf; I'm sorry if it seems like shameless self-promotion, but I did write it specifically for situations like this one where a repository repeatedly becomes contaminated with whitespace issues that gum up your commits.)

You can also use wtf to simply check for whitespace errors rather than in-place fixing of them; this won't affect your files but it will print a (hopefully helpful) message to stderr about the issues it has found.

> find . -name "*.whatever_extension_you_need" -exec wtf -v {} \; > /dev/null

nightmare.txt LINE 8: WARNING: spaces followed by tabs in whitespace at beginning of line
nightmare.txt:
    CHOPPED 1 lines with trailing space
    CHOPPED 0 blank lines at EOF
    ADDED newline at EOF
    CHANGED 1 line endings which didn't match crlf from first line
    WARNED ABOUT 1 lines with tabs/spaces mix
Dan Lenski
  • 76,929
  • 13
  • 76
  • 124
  • 3
    Nothing wrong with shameless self-promotion in my opinion! Thanks for writing it and thanks for the answer. I'll test it when I get a chance. – iconoclast Sep 02 '14 at 21:31
  • 1
    best origin story EVER :) – cxw Jan 31 '18 at 18:56
  • 1
    If I understand correctly, this answer will isolate differences in whitespace *errors* (like if only one of the commits mixes tabs and spaces or leaves spaces at the end of a line) but not whitespace differences that are not errors (like if a block of code is indented further on one branch, either because of different editor settings, or because of an additional level of nesting in the code). – Joshua Goldberg Sep 14 '20 at 17:01
  • 1
    @Dan Lenski - Is @Joshua Goldberg's comment (immediately above) correct? (An aside: `wtf` looks like a great tool, thanks for making it!) – Johnny Utahh Mar 22 '23 at 17:28
  • Yes, @JoshuaGoldberg's comment is correct. `wtf` will find (and fix!) whitespace _errors_, but it won't find arbitrary whitespace differences. – Dan Lenski Mar 22 '23 at 23:17
3

You can temporarily apply the non-whitespace differences to the original, or a copy. Then you can compare using diff or git diff before reverting.

In a repository, you can do something analogous to the suggestions in Add only non-whitespace changes depending exactly what you're diffing. Something like:

git diff -U0 -w -b --ignore-blank-lines --no-color | git apply --ignore-whitespace --unidiff-zero -
git diff

When I wanted to do this with non-git files and process substitutions I used a small script that I wrote to do the same thing with temporary files.

Joshua Goldberg
  • 5,059
  • 2
  • 34
  • 39