忽略git-diff在提交之间的所有空白更改。

103

我正在检查代码库并纠正空格的不规则性,一般来说,我会更正缩进等问题,并且我想确保我没有无意中进行任何其他更改,因此我使用git diff -w来显示所有已更改文件中的差异,同时忽略空格差异。问题在于,实际上这并不会完全忽略 所有 空格差异,至少不是我认为的仅仅是空格差异。例如,在下面由git diff -w输出的内容中:

-"Links":
-{
-
-    "Thermal":
-
-{
-
+  "Links": {
+    "Thermal": {

您可以看到,我只做了以下三件事:

  1. 删除了多余的空行,
  2. 在打开值得大括号后将其替换为右括号,并
  3. 根据上下文进行了缩进

这个问题 起初似乎提供了一个答案,但它处理的是两个特定文件之间的区别,而不是两个特定提交之间的区别。通过搜索发现的其他所有结果也都没有结果。例如,这个问题 是关于合并而不是显示差异,而这个问题 则涉及显示单词级别的差异等等。


2
对于Bitbucket用户,有一个提议的解决方案,但它还没有被编码,直到有足够的兴趣为止。您可以前往Bitbucket网站并表示支持。我最初在搜索Bitbucket中的解决方案时找到了当前页面,因此如果还有其他人处于这种情况,请前往此处并投票! - paultamalunas
git difftool + kdiff3 是一种选择。 - Tim Abell
1
我一直在使用difftastic来进行这个操作,并且取得了成功。它通过比较两个输入的AST而不是它们的行数来实现,虽然相对于diff来说速度和内存使用会有所增加,但效果非常好。 - MHebes
3个回答

93

也许还有更好的答案,但我目前找到最好的解决方案是这个。

首先,你必须控制Git当前使用的“空格”定义。

git config core.whitespace '-trailing-space,-indent-with-non-tab,-tab-in-indent'

接下来,您必须控制所使用的单词的定义。不仅仅使用git diff -w,还需要添加--word-diff-regex='[^[:space:]]'

git diff -w --word-diff-regex='[^[:space:]]'

你仍然会看到上下文,但在我的情况下(因为我想确保没有任何差异,除了空格差异),这并不是有帮助的。你可以使用-U0告诉Git给你0行上下文,像这样:

git diff -w -U0 --word-diff-regex='[^[:space:]]'

但是你仍然会得到一个看起来几乎像上下文的输出结果,但它仍然比仔细地手动查看所有更改并确保它们仅是空格更改要好得多。

您还可以在一个命令中执行上述所有操作。 -c 标志仅为一个命令更改git配置。

git -c core.whitespace=-trailing-space,-indent-with-non-tab,-tab-in-indent diff -U0 --word-diff-regex='[^[:space:]]'

6
@Torek - Git又有了新的好处。为什么没有所有空格的差异那么难呢?我在Windows机器上尝试评估Visual Studio项目文件的PR,但不关心CR、LF或CRLF的区别,但这正是Git填充我的终端的内容。 - jww
有没有办法为它创建一个别名? - StR
3
@StR,你可以在.gitconfig中的[alias]部分使用以下内容创建别名: diffw = diff -w -U0 --word-diff-regex=[^[:space:]] - mattwright
当我尝试这个时,出现了错误:“没有找到匹配项:--word-diff-regex=[^[:space:]]”。你有什么想法吗? - NSjonas
1
@NSjonas 我也遇到了同样的错误。你需要添加引号。我已经编辑了答案中的命令。 - cambunctious
2
在更改的行中,是否有可能删除{++}[--]这些字符? - alper

40

如何在 Git 的提交之间忽略所有空格变化

起初,这个问题看起来可能会提供答案,但它只涉及两个特定文件之间的差异,而不是两个特定提交之间的差异。通过搜索找到的其他信息都没有解决问题....

我认为你遇到困难是因为 Git 不是解决这个问题的正确工具。它不会使任务变得容易,迁就工具也是错误的方法。工具应该为你所用,而不是反过来。

执行第二次克隆,然后在问题中检出起始版本。使用当前的修订版本对它们运行常规 diff:diff -bur --ignore-all-space <dir1> <dir2>

这里有一些 diff 选项

-i, --ignore-case
       ignore case differences in file contents

-E, --ignore-tab-expansion
       ignore changes due to tab expansion

-Z, --ignore-trailing-space
        ignore white space at line end

-b, --ignore-space-change
       ignore changes in the amount of white space

-w, --ignore-all-space
       ignore all white space

-B, --ignore-blank-lines
       ignore changes where lines are all blank

4
这些选项都无法解决这个问题:diff 仍将换行符视为有或没有换行的不同。 - Gilles 'SO- stop being evil'
1
使用最新的git(v2.20.1):错误:无效选项:-Z - Morteza
7
@MortezaZiaeemehr 这里提供的选项是针对 diff 命令而不是 git 命令的。本答案建议使用 diff 工具来完成当前的任务,而不是使用 git。 - saraf
2
也遇到了无效选项的问题。--ignore-all-space--ignore-cr-at-eol 对我有用。 - mix3d

1

经典的diff工具描述为"逐行比较文件."

git diff也遵循这个原则,尽管显然具有增强功能。但是,行的概念似乎仍然是该工具的基础。我还没有看到绕过它的方法。通常不值得费力去反对工具的本质。

在问题描述的情况下,需要对文件的预编辑和后编辑修订进行标记化和规范化处理,以便最终获得方便的比较单元以供diff使用,传统上是行,然后在这些规范化版本上运行您选择的diff工具。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接