Git工具:如果暂存的行只包含空格更改,则删除这些行

12

去除行末空白的关键在于,如果每个人都始终这样做,那么您最终得到的差异将是最小的,即它仅包含代码更改而不是空格更改。

然而,当与不遵循此做法的其他人一起工作时,使用编辑器或预提交钩子删除所有行尾空白会导致一个更糟糕的差异。你的意图是相反的。

因此,我想问是否有可以在提交之前手动运行的工具,以使只包含空格更改的行处于未暂存状态。

另外,奖励是将有代码更改的已暂存行更改为去除行末空格的形式。

还可以不要应用到Markdown文件上(因为空格结尾在Markdown中具有特殊含义)。

我在这里询问,因为我完全打算编写此工具(如果它不存在)。


有趣的问题。如果还不存在,听起来像是一个有用的工具。这不是一个非常棘手的解析问题,但请告诉我们你最终会做什么。 - Paul McMillan
只是提供信息,升级您的git版本可能会使空格问题更加易于管理。这对我有用。请参见我的问题:https://dev59.com/MHM_5IYBdhLWcg3wlEPO 微笑 - Kzqai
@Max 我在回答中描述的行为是在v1.7.0版本中发布的:http://www.kernel.org/pub/software/scm/git/docs/RelNotes-1.7.0.txt - Greg Bacon
3个回答

9
以下操作可以让你实现大部分需求:
$ clean=`git diff --cached -b`; \
  git apply --cached <(git diff --cached -R); \
  echo "$clean" | git apply --cached -; \
  clean=
对于早期版本的git(1.7.0之前),如果一个或多个文件发生了全空格更改,此方法将无法成功。例如:
$ git diff --cached -b
diff --git a/file1 b/file1
index b2bd1a5..3b18e51 100644
diff --git a/file2 b/file2
new file mode 100644
index 0000000..092bfb9
--- /dev/null
+++ b/file2
[...]
上面的示例中,file1的空差异(实际上应该被忽略)会使git-apply产生错误:
fatal: patch with only garbage at line 3
更新:git 1.7.0版本已修复此问题
假设我们的代码库处于以下状态:
$ git diff --cached
diff --git a/foo b/foo
index 3b18e51..a75018e 100644
--- a/foo
+++ b/foo
@@ -1 +1,2 @@
-hello world
+hello  world
+howdy also
我们可以运行以上命令来分叉索引和工作树:
$ git diff --cached
diff --git a/foo b/foo
index 3b18e51..1715a9b 100644
--- a/foo
+++ b/foo
@@ -1 +1,2 @@
 hello world
+howdy also

$ git diff 
diff --git a/foo b/foo
index 1715a9b..a75018e 100644
--- a/foo
+++ b/foo
@@ -1,2 +1,2 @@
-hello world
+hello  world
 howdy also
如果所有更改都是只包含空格,则会看到以下内容:
error: No changes
我怀疑修复索引并在工作树中保留不需要的更改将使大多数用户感到惊讶或甚至不满,但这正是问题所要求的行为。

更新是说现在不会因为空格的改变而失败了吗? - rjmunro

4

我在 git 1.7.2.5 上的解决方案如下(开始时没有任何已暂存的更改):

git diff -w > temp.patch
git stash
git apply --ignore-space-change --ignore-whitespace temp.patch
# tidy up:
rm temp.patch
git stash drop

这将使您的 repo 回到起始状态,并删除任何仅包含空格的更改。
然后,您可以像往常一样暂存您的更改。

当您进行了两个更改,并且这些更改应该由"git add -p"分离,并且您还进行了空格更改时,使用此功能特别有用。 - MKaras

2

多年来,我一直在使用基于@GregBacon的答案的脚本,但是在某个时刻,git改变了git diff -b的输出,使得未显示为更改的空格更改包含在补丁上下文行中的后状态而不是前状态。

我发现如果我反转清理差异和相应的应用,脚本就可以再次工作。

所以我的完整脚本看起来像这样:

#!/bin/bash

clean=`git diff --cached -b`
git apply --cached <(git diff --cached -R)
echo "$clean" | git apply --cached -
clean=

现在看起来像这样:

#!/bin/bash

clean=`git diff --cached -b -R`
git apply --cached <(git diff --cached -R)
echo "$clean" | git apply --cached -R -
clean=

我还有一个脚本可以只保留提交中的空白更改。如果您在修复某些内容时发现文件中其他地方需要进行一些空格修正,并且您想在单独的提交中先提交这些空格修正,那么这将非常有用。只需使用以下命令即可:
git apply --cached -R <(git diff --cached -w)

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