我有我的文本编辑器,可以在保存文件时自动修剪尾随空格,而且我正在为一个开源项目做出贡献,该项目在跟踪空格时存在严重问题。
每当我尝试提交补丁时,我必须首先忽略所有仅限空白的更改,以便仅选择相关信息。不仅如此,当我运行git rebase
时,由于它们,我经常遇到几个问题。
因此我希望能够以与git add -p
类似的方式添加索引非空白更改,但不必自己选择所有更改。
有谁知道怎么做?
编辑:我无法改变项目的工作方式,他们在邮件列表上讨论之后决定忽略这一点。
答案 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
补丁<变化
查看剩余的差异,然后照常add
和commit
。
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 apply
和git
自动放置在命令行末尾的用户提供的参数。这里不需要这些参数 - 我们不希望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