如何在 Git add 中使用 patch 模式,但忽略空格变更。
这种情况适用于当您重新格式化文件并对其进行更改时。我希望先单独提交真正的代码更改(如 git diff -w path 所示),然后再提交格式化更改。
如何在 Git add 中使用 patch 模式,但忽略空格变更。
这种情况适用于当您重新格式化文件并对其进行更改时。我希望先单独提交真正的代码更改(如 git diff -w path 所示),然后再提交格式化更改。
以下内容是对相关问题的改编。
git diff -w --no-color | git apply --cached --ignore-whitespace
它的好处在于您不需要使用stash
、临时文件或对工作目录执行reset --hard
。
补充说明
上述解决方案仅适用于除空格之外的更改。这没有解决补丁问题,尽管在此情况下使用--patch
进行分段并不直观。
补丁选项1:在文本编辑器中编辑差异
有许多方法可以使用文本编辑器实现此操作。 Vim 特别适合此操作。
在您的存储库根目录中启动 Vim。
在正常模式下,通过以下方式将差异加载到空缓冲区中...
:r !git diff -w --no-color
:set ft=diff # if you want syntax highlighting
修改差异并删除您不想暂存的部分。
要将vim缓冲区的内容暂存,运行vim ex命令...
:w !git apply --cached --ignore-whitespace
如果你是 Vim 爱好者,你也可以使用可视模式进行暂存!
:<',>'w !git apply --cached --ignore-whitespace
:!git commit -m "message"
# or
:!git commit
:bd! | set ft=diff | r !git diff -w --no-color
最终,你只剩下空格改动需要提交。
如果你不使用Vim,你也可以将git diff
导出到文件中,编辑该文件并保存,然后再将该文件导入到git apply
中。反复提交和重复此过程,虽然有点繁琐,但却是可行的。
选项 2:补丁重置
这与git add --patch
相反,但一旦你使用了它来暂存了非空格改动...
git diff -w --no-color | git apply --cached --ignore-whitespace
git reset --patch .
git diff -w --no-color | git apply --cached --ignore-whitespace && git checkout -- . && git reset && git add -p
git diff -w --no-color
命令会创建一个差异(diff)
git apply --cached --ignore-whitespace
命令则应用该差异,并忽略空格,然后将其加入索引(index)
git checkout -- .
命令会移除未加入索引的 "空格" 更改
git reset
命令将索引重置为仅包含非空格更改
git add -p
命令以打补丁(patch)模式添加非空格更改
可以将以上命令封装到别名(alias)中:
alias gwap=“git diff -U0 -w --no-color | git apply --cached --ignore-whitespace --unidiff-zero && git checkout -- . && git reset && git add -p”
如果你使用像我一样基于Unix的系统:
gwap= !git diff -U0 -w --no-color | git apply --cached --ignore-whitespace --unidiff-zero && git checkout -- . && git reset && git add -p
-U0
和--unidiff-zero
,以解决上下文匹配问题,根据此评论。)gofmt
或 rustfmt
)引起的,则此解决方案非常有效。提交后,我只需重新运行格式化工具即可恢复空格更改。 - Justin Cgit diff | git apply
之后,也许可以使用 git stash --keep-index
来保存空格更改。它会存储所有更改,但保留索引不变。执行 git reset && git add -p
,直到完成提交,然后使用 git stash pop
恢复空格更改。灵感来自于 这个答案。 - Justin Cgit checkout -- .
之前,运行git diff -U0 --no-color > some-temp-file
,最后,使用<some-temp-file git apply --cached --unidiff-zero && rm some-temp-file
进行操作。 - Justin Cgit apply --cached
我建议简单地往返一个差异。git diff --ignore-all-space | (git reset --hard && git apply)
警告:由于git reset
的存在,这样做非常危险(它不会保留二进制文件的更改)。也许您想要一个类似于bash函数的东西。
function cleanup_patch()
{
if [ $# -lt 1 ]; then
echo 'Must provide explicit paths (wildcards allowed)';
else
git diff --ignore-all-space -- "$@" |
(git checkout HEAD -- "$@" &&
git apply)
fi
}
据我所知,diff命令中看似有用的--binary
选项并不遵守忽略空格标志。
cleanup_patch
函数所做的事情,只不过增加了一些繁琐的步骤。也许我漏掉了什么。 - sehecheckout
。如果你想的话,可以使用临时文件。如果我怀疑它,我的偏好是commit
/reset HEAD^
或使用git stash
。然而,我通常手动清理补丁。 - sehe一个更强大且多才多艺的版本是 @"Justin C" 的答案:
anw = !git diff -U0 -w --no-color -- \"$@\" | git apply --cached --ignore-whitespace --unidiff-zero "#"
有关更多信息,请参见this answer。