Git をだまして変更をパッチとして処理させることで、Git をだまして空白を修正させることができます。「プレコミット フック」ソリューションとは対照的に、これらのソリューションは、空白を修正するコマンドを Git に追加します。
はい、これらはハックです。
堅牢なソリューション
次の Git エイリアスは、
私の~/.gitconfig
.
「堅牢」とは、ツリーまたはインデックスがダーティであるかどうかに関係なく、これらのエイリアスがエラーなく実行され、正しいことを行うことを意味します。ただし、インタラクティブgit rebase -i
が既に進行中の場合は機能しません。最後に説明されているトリックが機能するこのコーナーケースに関心がある場合は、追加のチェックについて私~/.gitconfig
を参照してください。git add -e
Git エイリアスを作成せずにシェルで直接実行したい場合は、二重引用符の間にすべてをコピーして貼り付けます (シェルが 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 fixws
に実行することです。git commit
インデックスとツリーを修正する
次の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
ID エディターでパッチを「編集」するために使用し:
ます。
(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 .
裏技の解説
この回答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=:
する手段がID です。:
: