仅添加非空白更改

时间:2010-08-18 18:51:50

标签: git whitespace

我有我的文本编辑器,可以在保存文件时自动修剪尾随空格,而且我正在为一个开源项目做出贡献,该项目在跟踪空格时存在严重问题。

每当我尝试提交补丁时,我必须首先忽略所有仅限空白的更改,以便仅选择相关信息。不仅如此,当我运行git rebase时,由于它们,我经常遇到几个问题。

因此我希望能够以与git add -p类似的方式添加索引非空白更改,但不必自己选择所有更改。

有谁知道怎么做?

编辑:我无法改变项目的工作方式,他们在邮件列表上讨论之后决定忽略这一点。

9 个答案:

答案 0 :(得分:351)

@Frew解决方案并不是我所需要的,所以这就是我为完全相同的问题所做的别名:

alias.addnw=!sh -c 'git diff -U0 -w --no-color "$@" | git apply --cached --ignore-whitespace --unidiff-zero -'

或者你可以简单地运行:

git diff -U0 -w --no-color | git apply --cached --ignore-whitespace --unidiff-zero -

更新

根据this comment,分别为解决方案上下文匹配问题添加了选项-U0--unidiff-zero

基本上它应用了add应用的补丁,没有空格更改。您会注意到git addnw your/file之后仍会有未分级的更改,这是剩下的空白。

不需要--no-color,但由于我总是设置颜色,所以我必须使用它。无论如何,比抱歉更安全。

答案 1 :(得分:36)

这对我有用:

如果你想保留一下,这可行

git stash && git stash apply && git diff -w > foo.patch && git checkout . && git apply foo.patch && rm foo.patch

我不喜欢这些藏匿处,但我已经遇到了git + cygwin中的一个错误,我在这里丢失了更改,所以为了确保这些内容至少转到了reflog,我设置了以下内容:

git add . && git commit -am 'tmp' && git reset HEAD^ && git diff -w > foo.patch && git checkout . && git apply foo.patch && rm foo.patch

基本上我们创建一个不包含空间变化的差异,还原所有变化,然后应用差异。

答案 2 :(得分:29)

创建一个仅包含实际更改的补丁文件(不包括仅包含空格更改的行),然后清理工作区并应用该补丁文件:

  

git diff>备份
  git diff -w>变化
  git reset --hard
  补丁<变化

查看剩余的差异,然后照常addcommit

Mercurial的等价物是:

  

hg diff>备份
  hg diff -w>变化
  hg revert --all
  hg import --no-commit changes

答案 3 :(得分:9)

由于评论中的用户根据补丁上下文中的空白,所以在所有情况下,最高投票的答案都不起作用。

我按如下方式修改了命令:

$ git diff -U0 -w --no-color | git apply --cached --ignore-whitespace --unidiff-zero

这会生成一个没有上下文的补丁。由于补丁是短暂的,所以不应该成为一个问题。

相应的别名,再次修改其他用户已经提供的内容:

addw = !sh -c 'git diff -U0 -w --no-color "$@" | git apply --cached --ignore-whitespace --unidiff-zero' -

答案 4 :(得分:9)

将以下内容添加到.gitconfig

anw = !git diff -U0 -w --no-color -- \"$@\" | git apply --cached --ignore-whitespace --unidiff-zero "#"

感谢@Colin Herbert's answer的灵感。

语法说明

必须引用最终的#,因此它不会被视为.gitconfig内的注释,而是被传递并被视为shell内的注释 - 它被插入到结尾之间git applygit自动放置在命令行末尾的用户提供的参数。这里不需要这些参数 - 我们不希望git apply使用它们,因此前面的注释字符。您可能希望以GIT_TRACE=1 git anw运行此命令以查看此操作。

--表示参数结束,并允许您拥有名为-w的文件或看起来像git diff的切换。

$@周围的转义双引号是保留任何用户提供的引用参数所必需的。如果"字符未转义,则.gitconfig解析器将使用该字符,而不会到达shell。

注意:.gitconfig别名解析不会将单引号识别为特殊的 - 它的唯一特殊字符是"\\n和{{1 (在; - 引用字符串之外)。这就是"必须始终被转义的原因,即使它看起来像是在单引号字符串中(git完全不可知)。

这很重要,例如。如果你有一个方便的别名来在工作树的根目录中执行"命令。不正确的表述是:

bash

正确的是:

sh = !bash -c '"$@"' -

答案 5 :(得分:6)

以下内容如何:

git add `git diff -w --ignore-submodules |grep "^[+][+][+]" |cut -c7-`

反引号内的命令获取具有非空白更改的文件的名称。

答案 6 :(得分:0)

您应首先考虑尾随空格是否是故意的。许多项目,包括Linux内核,Mozilla,Drupal和Kerberos(仅举几个来自Wikipedia页面的样式)禁止尾随空格。从Linux内核文档:

  

得到一个体面的编辑,不要离开   行尾的空白。

在您的情况下,问题是相反的:先前的提交(可能是当前的提交)不符合本指南。

我敢打赌,没有人真正想要尾随的空白,修复问题可能是一个值得欢迎的变化。其他用户可能也遇到了同样的问题。添加尾随空格的贡献者也可能不知道他们正在这样做。

我不是试图重新配置git来忽略问题,或者在编辑器中禁用其他理想的功能,而是先从项目邮件列表中找到解释问题的帖子。可以配置许多编辑器(和git本身)来处理尾随空格。

答案 7 :(得分:0)

它对我有用:

git config apply.whitespace fix

在每次提交之前使用命令:

git add -up .

答案 8 :(得分:-2)

我找到了一个git pre-commit hook that removes trailing whitespace。但是,如果你不能让其他人使用它,那么它可能不是一个有效的解决方案。

  #!/bin/sh

  if git-rev-parse --verify HEAD >/dev/null 2>&1 ; then
     against=HEAD
  else
     # Initial commit: diff against an empty tree object
     against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
  fi
  # Find files with trailing whitespace
  for FILE in `exec git diff-index --check --cached $against -- | sed '/^[+-]/d' | sed -r 's/:[0-9]+:.*//' | uniq` ; do
     # Fix them!
     sed -i 's/[[:space:]]*$//' "$FILE"
  done
  exit