您可以欺骗 Git 为您修复空白,方法是欺骗 Git 将您的更改视为一个补丁。与“预提交挂钩”解决方案相比,这些解决方案向 Git 添加了空白修复命令。
是的,这些都是黑客攻击。
稳健的解决方案
以下 Git 别名取自
my ~/.gitconfig.
“健壮”是指这些别名运行时不会出错,
正确的事情,无论树或索引是否脏。但是,如果交互式 git rebase -i 已经在进行中,它们将不起作用;如果您关心这种极端情况,请参阅my ~/.gitconfig 进行额外检查,最后描述的git add -e 技巧应该可以工作。
如果你想直接在 shell 中运行它们,而不需要创建 Git
别名,只需复制并粘贴双引号之间的所有内容
(假设你的 shell 类似于 Bash)。
修复索引而不是树
以下fixws Git 别名修复了索引中的所有空白错误,
如果有,但不要碰树:
# Logic:
#
# The 'git stash save' fails if the tree is clean (instead of
# creating an empty stash :P). So, we only 'stash' and 'pop' if
# the tree is dirty.
#
# The 'git rebase --whitespace=fix HEAD~' throws away the commit
# if it's empty, and adding '--keep-empty' prevents the whitespace
# from being fixed. So, we first check that the index is dirty.
#
# Also:
# - '(! git diff-index --quiet --cached HEAD)' is true (zero) if
# the index is dirty
# - '(! git diff-files --quiet .)' is true if the tree is dirty
#
# The 'rebase --whitespace=fix' trick is from here:
# https://stackoverflow.com/a/19156679/470844
fixws = !"\
if (! git diff-files --quiet .) && \
(! git diff-index --quiet --cached HEAD) ; then \
git commit -m FIXWS_SAVE_INDEX && \
git stash save FIXWS_SAVE_TREE && \
git rebase --whitespace=fix HEAD~ && \
git stash pop && \
git reset --soft HEAD~ ; \
elif (! git diff-index --quiet --cached HEAD) ; then \
git commit -m FIXWS_SAVE_INDEX && \
git rebase --whitespace=fix HEAD~ && \
git reset --soft HEAD~ ; \
fi"
这个想法是在 git commit 之前运行 git fixws 如果你有
索引中的空白错误。
修复索引和树
以下fixws-global-tree-and-index Git 别名修复了所有空格
索引和树中的错误(如果有):
# The different cases are:
# - dirty tree and dirty index
# - dirty tree and clean index
# - clean tree and dirty index
#
# We have to consider separate cases because the 'git rebase
# --whitespace=fix' is not compatible with empty commits (adding
# '--keep-empty' makes Git not fix the whitespace :P).
fixws-global-tree-and-index = !"\
if (! git diff-files --quiet .) && \
(! git diff-index --quiet --cached HEAD) ; then \
git commit -m FIXWS_SAVE_INDEX && \
git add -u :/ && \
git commit -m FIXWS_SAVE_TREE && \
git rebase --whitespace=fix HEAD~2 && \
git reset HEAD~ && \
git reset --soft HEAD~ ; \
elif (! git diff-files --quiet .) ; then \
git add -u :/ && \
git commit -m FIXWS_SAVE_TREE && \
git rebase --whitespace=fix HEAD~ && \
git reset HEAD~ ; \
elif (! git diff-index --quiet --cached HEAD) ; then \
git commit -m FIXWS_SAVE_INDEX && \
git rebase --whitespace=fix HEAD~ && \
git reset --soft HEAD~ ; \
fi"
要修复未版本化文件中的空白,请执行
git add --intent-to-add <unversioned files> && git fixws-global-tree-and-index
简单但不可靠的解决方案
这些版本更容易复制和粘贴,但它们不具备
如果不满足他们的附带条件,那就对了。
修复以当前目录为根的子树(如果不为空则重置索引)
使用git add -e 使用身份编辑器:“编辑”补丁:
(export GIT_EDITOR=: && git -c apply.whitespace=fix add -ue .) && git checkout . && git reset
修复并保留索引(但如果树脏或索引为空则失败)
git commit -m TEMP && git rebase --whitespace=fix HEAD~ && git reset --soft HEAD~
修复树和索引(但如果它不为空则重置索引)
git add -u :/ && git commit -m TEMP && git rebase --whitespace=fix HEAD~ && git reset HEAD~
export GIT_EDITOR=: && git -c apply.whitespace=fix add -ue . 技巧的解释
在我从this answer 了解git rebase --whitespace=fix 技巧之前,我一直在使用更复杂的git add 技巧。
如果我们手动操作:
-
将apply.whitespace 设置为fix(您只需执行一次):
git config apply.whitespace fix
这告诉 Git 修复补丁中的空白。
-
说服 Git 将您的更改视为补丁:
git add -up .
点击 a+enter 以选择每个文件的所有更改。您将收到有关 Git 修复空白错误的警告。
(此时git -c color.ui=auto diff 表明您的非索引更改正是空白错误)。
-
从工作副本中删除空白错误:
git checkout .
-
带回您的更改(如果您还没有准备好提交):
git reset
GIT_EDITOR=: 表示将: 用作编辑器,并用作命令
: 是身份。