git 仅添加非空白更改
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3515597/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Add only non-whitespace changes
提问by Edu Felipe
I have my text editor to automatically trim trailing whitespace upon saving a file, and I am contributing to an open source project that has severe problems with trailing whitespace.
我的文本编辑器可以在保存文件时自动修剪尾随空格,并且我正在为一个尾随空格存在严重问题的开源项目做出贡献。
Every time I try to submit a patch I must first ignore all whitespace-only changes by hand, to choose only the relevant information. Not only that, but when I run git rebase
I usually run into several problems because of them.
每次我尝试提交补丁时,我必须首先手动忽略所有仅空白的更改,仅选择相关信息。不仅如此,当我跑步时,git rebase
我通常会因为它们而遇到几个问题。
As such I would like to be able to add to index only non-whitespace changes, in a way similar that git add -p
does, but without having to pick all the changes myself.
因此,我希望能够以类似的方式将非空白更改添加到索引git add -p
中,但不必自己选择所有更改。
Does anyone know how to do this?
有谁知道如何做到这一点?
EDIT: I cannotchange the way the project works, and they have decided, after discussing it on the mailing list, to ignore this.
编辑:我无法改变项目的工作方式,他们在邮件列表上讨论后决定忽略这一点。
回答by Colin Hebert
@Frew solution wasn't quite what I needed, so this is the alias I made for the exact same problem:
@Frew 解决方案并不是我所需要的,所以这是我为完全相同的问题制作的别名:
alias.addnw=!sh -c 'git diff -U0 -w --no-color "$@" | git apply --cached --ignore-whitespace --unidiff-zero -'
Or you can simply run:
或者你可以简单地运行:
git diff -U0 -w --no-color | git apply --cached --ignore-whitespace --unidiff-zero -
Update
更新
Added options -U0
, and --unidiff-zero
respectively to workaround context matching issues, according to this comment.
根据此评论-U0
,--unidiff-zero
分别添加了 options和以解决上下文匹配问题。
Basically it applies the patch which would be applied with add
without whitespace changes. You will notice that after a git addnw your/file
there will still be unstaged changes, it's the whitespaces left.
基本上它应用了将在add
没有空格更改的情况下应用的补丁。您会注意到,在 a 之后git addnw your/file
仍然会有未分阶段的更改,剩下的就是空格。
The --no-color isn't required but as I have colors set to always, I have to use it. Anyway, better safe than sorry.
--no-color 不是必需的,但由于我将颜色设置为始终,我必须使用它。不管怎样,安全总比后悔好。
回答by Frew Schmidt
This works for me:
这对我有用:
If you want to keep a stash around, this works
如果你想藏起来,这行得通
git stash && git stash apply && git diff -w > foo.patch && git checkout . && git apply foo.patch && rm foo.patch
I don't like the stashes, but I haverun into a bug in git + cygwin where I lose changes, so to make sure that stuff went to the reflog at least I set up the following:
我不喜欢的藏匿处,但我已经在混帐+ cygwin的,我失去的变化,所以要确保这些东西去了,至少我设置以下的引用日志碰上了一个错误:
git add . && git commit -am 'tmp' && git reset HEAD^ && git diff -w > foo.patch && git checkout . && git apply foo.patch && rm foo.patch
Basically we create a diff that doesn't include the space changes, revert all of our changes, and then apply the diff.
基本上我们创建一个不包括空间更改的差异,恢复我们所有的更改,然后应用差异。
回答by Steve Pitchers
Create a patch file containing only the real changes (excluding lines with only whitespace changes), then clean your workspace and apply that patch file:
创建一个仅包含实际更改的补丁文件(不包括仅包含空格更改的行),然后清理您的工作区并应用该补丁文件:
git diff > backup
git diff -w > changes
git reset --hard
patch < changes
git diff > 备份
git diff -w > 更改
git reset --hard
patch < 更改
Review the remaining differences, then add
and commit
as normal.
查看剩余的分歧,然后add
和commit
正常。
The equivalent for Mercurial is to do this:
Mercurial 的等价物是这样做:
hg diff > backup
hg diff -w > changes
hg revert --all
hg import --no-commit changes
hg diff > 备份
hg diff -w > 更改
hg revert --all
hg import --no-commit changes
回答by void.pointer
Top-voted answer does not work in all cases, due to whitespace in the patch context according to users in the comments.
根据评论中的用户,由于补丁上下文中的空白,高票答案并非在所有情况下都有效。
I revised the command as follows:
我修改了命令如下:
$ git diff -U0 -w --no-color | git apply --cached --ignore-whitespace --unidiff-zero
This generates a patch with no context. Shouldn't be a problem since the patch is short-lived.
这会生成一个没有上下文的补丁。应该不是问题,因为补丁是短暂的。
Corresponding alias, again a revision of what was already provided by other users:
对应的别名,同样是对其他用户已经提供的内容的修订:
addw = !sh -c 'git diff -U0 -w --no-color "$@" | git apply --cached --ignore-whitespace --unidiff-zero' -
回答by Tom Hale
Add the following to your .gitconfig
:
将以下内容添加到您的.gitconfig
:
anw = !git diff -U0 -w --no-color -- \"$@\" | git apply --cached --ignore-whitespace --unidiff-zero "#"
Thanks to @Colin Herbert's answerfor the inspiration.
感谢@Colin Herbert对灵感的回答。
Syntax Explanation
语法说明
The final #
must be quoted so it's not treated it as a comment inside the .gitconfig
, but instead gets passed through and is treated as a comment inside the shell - it is inserted between the end of the git apply
and the user-supplied arguments that git
automatically places at the end of the command line. These arguments aren't wanted here - we don't want git apply
to consume them, hence the preceding comment character. You may want to run this command as GIT_TRACE=1 git anw
to see this in action.
final#
必须被引用,因此它不会被视为 内的注释.gitconfig
,而是被传递并被视为外壳内的注释 - 它被插入在 的末尾git apply
和用户提供的参数之间,这些参数会git
自动放置在命令行的结尾。这里不需要这些参数——我们不想git apply
使用它们,因此前面的注释字符。您可能希望运行此命令GIT_TRACE=1 git anw
以查看其实际效果。
The --
signals end of arguments and allows for the case that you have a file named -w
or something that would look like a switch to git diff
.
--
参数结束的信号,并允许您有一个名为的文件-w
或看起来像切换到git diff
.
Escaped double-quotes around $@
are required to preserve any user-supplied quoted arguments. If the "
character is not escaped, it will be consumed by the .gitconfig
parser and not reach the shell.
需要使用转义双引号$@
来保留任何用户提供的带引号的参数。如果"
字符没有被转义,它会被.gitconfig
解析器消耗掉并且不会到达 shell。
Note: .gitconfig
alias parsing doesn't recognise single-quotes as anything special - its only special characters are "
, \
, \n
, and ;
(outside of a "
-quoted string). This is why a "
must always be escaped, even if it looks like it's inside a single-quoted string (which git is completely agnostic about).
注:.gitconfig
别名解析不承认单引号的任何特殊-它的唯一的特殊字符"
,\
,\n
,和;
(一个外"
-quoted字符串)。这就是为什么 a"
必须始终转义,即使它看起来像是在单引号字符串中(git 完全不可知)。
This is important, eg. if you have a handy alias to execute a bash
command in the working tree's root. The incorrect formulation is:
这很重要,例如。如果您有一个方便的别名来bash
在工作树的根中执行命令。不正确的公式是:
sh = !bash -c '"$@"' -
While the correct one is:
而正确的是:
sh = !bash -c '\"$@\"' -
回答by karmakaze
How about the following:
以下情况如何:
git add `git diff -w --ignore-submodules |grep "^[+][+][+]" |cut -c7-`
The command inside backquotes gets the names of files which have non-whitespace changes.
反引号内的命令获取具有非空白更改的文件的名称。
回答by Kevin Vermeer
You should first consider if the trailing whitespace is intentional. Many projects, including the Linux kernel, Mozilla, Drupal, and Kerberos (to name a few from the Wikipedia page on style) prohibit trailing whitespace. From the Linux kernel documentation:
您应该首先考虑尾随空格是否是故意的。许多项目,包括 Linux 内核、Mozilla、Drupal 和 Kerberos(仅举几例来自 Wikipedia 样式页面)都禁止尾随空格。来自 Linux 内核文档:
Get a decent editor and don't leave whitespace at the end of lines.
找一个像样的编辑器,不要在行尾留下空格。
In your case, the problem is the other way around: previous commits (and maybe current ones) did not follow this guideline.
在你的情况下,问题是相反的:以前的提交(也许是当前的提交)没有遵循这个准则。
I'd wager that no one really wants the trailing whitespace, and fixing the problem might be a welcome change. Other users might also be experiencing the same problem you are. It's also likely that the contributor(s) who are adding trailing whitespace are unaware that they are doing so.
我敢打赌,没有人真的想要尾随空格,解决这个问题可能是一个受欢迎的改变。其他用户也可能遇到与您相同的问题。添加尾随空格的贡献者也很可能没有意识到他们正在这样做。
Rather than trying to reconfigure git to ignore the problem, or disabling the otherwise desirable functionality in your editor, I'd start off with a post to the project mailing list explaining the problem. Many editors (and git itself) can be configured to deal with trailing whitespace.
与其尝试重新配置 git 以忽略该问题,或在编辑器中禁用其他所需的功能,不如先在项目邮件列表中发帖解释问题。许多编辑器(和 git 本身)可以配置为处理尾随空格。
回答by cmcginty
I found a git pre-commit hook that removes trailing whitespace. However, if you can't get others to use this, then it might not be a valid solution.
我发现了一个 git pre-commit 钩子,它删除了尾随的空白。但是,如果您不能让其他人使用它,那么它可能不是一个有效的解决方案。
#!/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