変更をパッチとして処理するようにGitをだまして、Gitにだまして空白を修正させることができます。「pre-commitフック」ソリューションとは対照的に、これらのソリューションは空白修正コマンドをGitに追加します。
はい、これらはハックです。
堅牢なソリューション
次のGitエイリアスはmy~/.gitconfig
から取得され
ます。
「堅牢」とは、ツリーまたはインデックスがダーティかどうかに関係なく、これらのエイリアスがエラーなしで実行され、正しいことを実行することを意味します。ただし、インタラクティブgit rebase -i
がすでに進行中の場合は機能しません。このコーナーケースについて気になる場合は、最後に説明したトリックが機能するはずの追加のチェックについて、my~/.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
して、アイデンティティエディタでパッチを「編集」します:
。
(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=:
手段が使用する:
エディタとして、コマンドとして
:
のアイデンティティです。