Search code examples
diffgit-diff

diff files for whitespace changes while ignoring indentation


I am trying to see the effects of a formatter I am using. Many lines will have indentation changes, while a few will other changes, like a newline between an open and close brace. I want to ignore all changes to the indentation, while keeping other whitespace changes.

The best solution I've come up with is just stripping the leading whitespace with sed before feeding it into diff:

diff <(sed 's/^\s*//' inputfile) <(sed 's/^\s*//' formattedfile)

but that has the downside of stripping the indentation for the displaying of the diff as well.

Is there a way for me to do this with diff, git diff, or even another tool I could download?


Solution

  • GNU diff has -Z to ignore trailing space. We can abuse this:

    s2e()(sed -E 's/;/;</g; s/^([ \t]*)(.*)/\2;>\1/')
    e2s()(sed -E 's/^([<>] )(.*);>([ \t]*)$/\1\3\2/; s/;</;/g')
    
    diff -Z <(s2e<file1) <(s2e<file2) | e2s
    

    For -u:

    e2s_u()(sed -E 's/^([ +-])(.*);>([ \t]*)$/\1\3\2/; s/;</;/g')
    
    diff -Zu <(s2e<file1) <(s2e<file2) | e2s_u
    

    Basically:

    • use some character as an escape (;)
    • encode all occurrences (;<)
    • move leading whitespace to end after delimiter (;>)
    • run diff
    • put back leading whitespace and remove delimiter
    • decode the escape character

    If you also want -Z to behave as normal, I think you could set:

    • escape = \t
    • encoded escape = \t
    • delimiter = \t\t