How to have git-diff ignore all whitespace-change but leading one?

浪尽此生 提交于 2019-12-04 06:35:19

I couldn't solve your problem, but I worry that Git might be working against you here. Recall that --color-words=<regex> is a combination of --word-diff=color and --word-diff-regex=<regex>. The man git diff documentation says:

   --word-diff-regex=<regex>
       Use <regex> to decide what a word is, instead of considering runs
       of non-whitespace to be a word. Also implies --word-diff unless it
       was already enabled.

       Every non-overlapping match of the <regex> is considered a word.
       Anything between these matches is considered whitespace and
       ignored(!) for the purposes of finding differences. You may want
       to append |[^[:space:]] to your regular expression to make sure
       that it matches all non-whitespace characters. A match that
       contains a newline is silently truncated(!) at the newline.

       The regex can also be set via a diff driver or configuration
       option, see gitattributes(1) or git-config(1). Giving it
       explicitly overrides any diff driver or configuration setting.
       Diff drivers override configuration settings.

Note this part of the middle paragraph: "Anything between these matches is considered whitespace and ignored(!) for the purposes of finding differences." So, it sounds like Git trys to treat whitespace specially here, and that might be a problem.

The best I can get so far is

git diff --color-words='[[:space:]]|([[:alnum:]]|UTF_8_GUARD)+' --word-diff=plain

Note the removed ^ in front of [:space:]!

Here's an alternative using the substitution suggested at the question's end:

git config --global core.pager 'less --raw-control-chars'

such that unicode symbols are displayed correctly instead of some weird <c3>ish output. Add the following to your git configuration:

[diff "txt"]
    textconv = unwhite.sh

and, lacking a global solution, to .gitattributes something like

*.py diff=txt

Finally, unwhite.sh:

#!/bin/bash
awk 1 ORS='[7m\\n[27m\n' $1 | sed -e 's/ /␣/g' -e 's/\t/→/g'

Be advised there are raw escape (awk fails to support \e) characters before the [s, I display the newline-indicating \n in inverted colors to differ them from literal \ns. This may fail to copy paste, in which case you may have to manually insert them. Or try your luck with a unicode symbol such as instead.

I deviated from the original unicode symbols since they failed to display correctly on msysgit.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!