只添加非空白的变化
我有我的文本编辑器来保存文件时自动修剪尾随的空白,我正在贡献一个OpenSource项目,具有严重的尾随空白问题。
每次我尝试提交一个补丁时,我必须首先忽略所有只有空白的变化,只select相关的信息。 不仅如此,当我运行git rebase
我通常会因为这些问题而遇到几个问题。
因此,我希望能够添加仅索引非空白更改,类似于git add -p
,但不必自己select所有更改。
有谁知道如何做到这一点?
编辑:我不能改变项目的方式,他们已经决定,在邮件列表讨论它,忽略这一点。
@Frew解决scheme不是我所需要的,所以这是我为同样的问题所做的别名:
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 -
更新
根据此评论 ,分别添加了选项-U0
和--unidiff-zero
来解决上下文匹配问题。
基本上它应用补丁应用与add
没有空白的变化。 你会注意到,在git addnw your/file
仍然是未分离的变化,这是剩下的空白。
– 无颜色不是必需的,但因为我的颜色设置为始终,我必须使用它。 无论如何,比对不起更安全。
这适用于我:
如果你想保持藏身,这是有效的
git stash && git stash apply && git diff -w > foo.patch && git checkout . && git apply foo.patch && rm foo.patch
我不喜欢这些内存,但是我遇到了一个git + cygwin中的一个bug,在这里我失去了一些改变,所以为了确保这些东西进入了reflog,至less我设置了如下内容:
git add . && git commit -am 'tmp' && git reset HEAD^ && git diff -w > foo.patch && git checkout . && git apply foo.patch && rm foo.patch
基本上我们创build一个不包含空间变化的diff,还原所有的变化,然后应用diff。
创build一个只包含实际更改的补丁文件(不包括只有空白更改的行),然后清理工作空间并应用该补丁文件:
git diff>备份
git diff -w>更改
git reset –hard
补丁<更改
检查剩余的差异,然后add
和commit
。
Mercurial的等价物是这样做的:
hg diff>备份
hg diff -w>改变
hg恢复 – 所有
hg import – 不提交更改
将以下内容添加到.gitconfig
:
anw = !git diff -U0 -w --no-color -- \"$@\" | git apply --cached --ignore-whitespace --unidiff-zero "#"
感谢@Colin Herbert的灵感答案 。
语法解释
最后的#
必须被引用,所以它不会被视为在.gitconfig
里面的.gitconfig
,而是被传递,并被当做shell里的注释 – 它被插入在git apply
的结尾和用户提供的参数之间该git
自动放置在命令行的末尾。 这些参数不是在这里想要的 – 我们不希望git apply
来消耗它们,因此前面的注释字符。 你可能想要运行这个命令作为GIT_TRACE=1 git anw
来看到这个在行动。
--
信号结束的参数,并允许的情况下,你有一个文件名为-w
或东西,看起来像一个开关git diff
。
围绕$@
转义的双引号需要保留用户提供的引用参数。 如果"
字符没有被转义,它将被.gitconfig
parsing器使用,而不能到达shell。
注意: .gitconfig
别名parsing不会将单引号识别为任何特殊的字符 – 它唯一的特殊字符是"
, \
, \n
和;
(在引号string之外)。 这就是为什么一个"
必须永远逃脱,即使它看起来像是在一个单引号string(哪个git是完全不可知的)。
这很重要,例如。 如果你有一个方便的别名在工作树的根目录下执行一个bash
命令。 错误的表述是:
sh = !bash -c '"$@"' -
正确的是:
sh = !bash -c '\"$@\"' -
以下情况如何:
git add `git diff -w --ignore-submodules |grep "^[+][+][+]" |cut -c7-`
反引号内部的命令获取非空白变化的文件名称。
顶级答案在所有情况下都不起作用,这是由于补丁上下文中的空白符合注释中的用户。
我修改了命令如下:
$ 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' -
您应该首先考虑是否有意识的尾随空格。 许多项目,包括Linux内核,Mozilla,Drupal和Kerberos(仅仅从维基百科页面的样式中可以看出)都禁止尾随的空格。 从Linux内核文档:
得到一个体面的编辑器,不要留下行尾的空白。
在你的情况下,这个问题是相反的:以前的提交(也可能是当前的提交)没有遵循这个准则。
我敢打赌,没有人真的想要最后的空白,解决这个问题可能是一个可喜的变化。 其他用户也可能遇到同样的问题。 添加尾随空白的贡献者也可能不知道他们正在这样做。
而不是尝试重新configurationgit来忽略问题,或者在编辑器中禁用其他合意的function,我会先在项目邮件列表中发布解释问题的文章。 许多编辑器(和git本身)可以configuration为处理尾随空格。
我发现了一个git pre-commit钩子去除了尾随的空白 。 但是,如果你不能让别人使用它,那么它可能不是一个有效的解决scheme。
#!/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