我已经设置了文本编辑器,在保存文件时自动删除末尾空格。我正在为一个开源项目做贡献,该项目在末尾空格方面存在严重问题。
每次我尝试提交补丁之前,都必须手动忽略所有的仅包含空格的更改,只选择相关信息。不仅如此,当我运行git rebase
时,由于这些空格问题,通常会遇到几个问题。
因此,我希望能够以类似git add -p
的方式将只有非空格变化添加到索引中,但不必自己选择所有变化。
是否有人知道如何做到这一点?
编辑:我不能更改项目的工作方式,并且他们经过邮件列表讨论后决定忽略此问题。
我已经设置了文本编辑器,在保存文件时自动删除末尾空格。我正在为一个开源项目做贡献,该项目在末尾空格方面存在严重问题。
每次我尝试提交补丁之前,都必须手动忽略所有的仅包含空格的更改,只选择相关信息。不仅如此,当我运行git rebase
时,由于这些空格问题,通常会遇到几个问题。
因此,我希望能够以类似git add -p
的方式将只有非空格变化添加到索引中,但不必自己选择所有变化。
是否有人知道如何做到这一点?
编辑:我不能更改项目的工作方式,并且他们经过邮件列表讨论后决定忽略此问题。
@Frew的解决方案并不完全符合我的需求,所以我为这个完全相同的问题创建了这个别名:
alias.addnw=!sh -c 'git diff -U0 -w --no-color --src-prefix=a/ --dst-prefix=b/ "$@" | git apply --cached --ignore-whitespace --unidiff-zero -'
或者你可以直接运行:
git diff -U0 -w --no-color --src-prefix=a/ --dst-prefix=b/ | git apply --cached --ignore-whitespace --unidiff-zero -
根据this comment,添加了选项-U0
和--unidiff-zero
以解决上下文匹配问题。
基本上它应用了补丁,而没有空格改变的情况下将会被应用。您会发现,在使用 git addnw 您的/文件名
后,仍然会有未暂存的更改,这是留下的空格。
虽然不需要--no-color选项,但由于我始终设置颜色,因此必须使用它。无论如何,谨慎总比后悔强。
虽然这个技巧可以直接使用,但如果您尝试使用它来删除带有--ignore-blank-lines
选项的空白行更改,则事情会变得复杂。使用这个选项时,git diff
将会删除一些块,使得结果的补丁是错误的,因为目标文件中的行号将会偏移。
检查剩余的差异,然后像平常一样添加和提交。git diff > backup
git diff -w > changes
git reset --hard
patch < changes
hg diff > backup
hg diff -w > changes
hg revert --all
hg import --no-commit changes
这对我有效:
如果你想保留一个stash,这个方法可行。
git stash && git stash apply && git diff -w > foo.patch && git checkout . && git apply foo.patch && rm foo.patch
我不喜欢暂存,但是在git + cygwin中我遇到了一个bug,导致我丢失了一些修改。为了确保这些修改被记录在reflog中,我设置了以下操作:
git add . && git commit -am 'tmp' && git reset HEAD^ && git diff -w > foo.patch && git checkout . && git apply foo.patch && rm foo.patch
我们基本上创建了一个不包括空格更改的差异(diff),撤销我们所有的更改,然后应用该差异。
git stash
而不是 checkout,以备份你的更改,至少在测试之前这样做。 - Paŭlo Ebermann根据评论中的用户所说,最受欢迎的答案在某些情况下不起作用,这是由于修补上下文中存在空白。
我将命令修改如下:
$ 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' -
--ignore-space-change
而不是-w
。 git diff -U0 --ignore-space-change --no-color | git apply --cached --unidiff-zero
- Andrew--ignore-blank-lines
的这个巧妙无上下文的技巧,否则如果您要忽略的一些"空格"变化是删除或添加空行,则会发现补丁块在错误的偏移处进行修补。 - elbeardmorez将以下内容添加到您的 .gitconfig
文件中:
anw = !git diff -U0 -w --no-color -- \"$@\" | git apply --cached --ignore-whitespace --unidiff-zero "#"
感谢@Colin Herbert的回答启发了我。
语法解释
最后一个#
必须被引用,以便它不会在.gitconfig
内被视为注释字符,而是被传递并在shell内被视为注释字符——它插入在git apply
结束和由git
自动放置在命令行末尾的用户提供的参数之间。这些参数在这里是不需要的——我们不希望git apply
使用它们,因此前面有注释字符。您可能希望将此命令作为GIT_TRACE=1 git anw
运行,以查看它的运行情况。
--
表示参数的结束,允许存在文件名为-w
或类似于git diff
开关的情况。
$@
周围的转义双引号是必需的,以保留任何用户提供的引用参数。如果未转义"
字符,则它将被.gitconfig
解析器所消耗,而不能到达shell。
注意:.gitconfig
别名解析不将单引号视为任何特殊字符——它的特殊字符仅为"
、\
、\n
和;
(在"
引用字符串之外)。这就是为什么"
必须始终被转义,即使它看起来在一个单引号的字符串中(git对此完全无动于衷)。
这很重要,例如,如果您有一个方便的别名来在工作树的根目录中执行bash
命令。错误的表达式是:
sh = !bash -c '"$@"' -
虽然正确的是:
sh = !bash -c '\"$@\"' -
如下:
git add `git diff -w --ignore-submodules |grep "^[+][+][+]" |cut -c7-`
git add \
git diff -w |grep '^+++' |cut -c7-``。 - karmakazegit reset --mixed HEAD^
git diff -U0 -w --no-color | git apply --cached --ignore-whitespace --unidiff-zero -
这是我的黑客。
git diff -w | grep "diff --git a/*" | sed -r 's#diff --git a/(.*) b(.*)#\1#g' | xargs git add
git diff -w 只显示有非空格更改的文件。
对我来说它有效:
git config apply.whitespace fix
每次提交之前使用以下命令:
git add -up .
git add -w
来执行此操作。 - Jarlgit diff -U0 -w --no-color | git apply --cached --ignore-whitespace --unidiff-zero
。这不会有风险,因为索引已经是最新的,所以它是一个可靠的基准补丁。 - void.pointer