web-dev-qa-db-ja.com

空白以外の変更のみを追加します

ファイルの保存時に末尾の空白を自動的にトリムするテキストエディターがあり、末尾の空白に重大な問題があるオープンソースプロジェクトに貢献しています。

パッチを送信しようとするたびに、最初にすべての空白のみの変更を手動で無視して、関連情報のみを選択する必要があります。それだけでなく、git rebaseを実行すると、通常、いくつかの問題が発生します。

そのため、git add -pと同様の方法で、ホワイトスペース以外の変更のみをインデックスに追加できますが、すべての変更を自分で選択する必要はありません。

誰もこれを行う方法を知っていますか?

編集:I できませんプロジェクトの動作を変更し、メーリングリストで議論した後、これを無視することにしました。

313
Edu Felipe

@Frewソリューションは私が必要とするものではなかったので、これはまったく同じ問題に対して作成したエイリアスです。

alias.addnw=!sh -c 'git diff -U0 -w --no-color "$@" | git apply --cached --ignore-whitespace --unidiff-zero -'

または、単に実行することができます:

git diff -U0 -w --no-color | git apply --cached --ignore-whitespace --unidiff-zero -

更新

このコメント に従って、コンテキスト一致の問題を回避するために、オプション-U0および--unidiff-zeroをそれぞれ追加しました。

基本的に、空白を変更せずにaddで適用されるパッチを適用します。 git addnw your/fileの後、ステージングされていない変更が残っていることに気付くでしょう、それは空白です。

--no-colorは必須ではありませんが、色を常に設定しているため、使用する必要があります。とにかく、ごめんなさいよりも安全です。

355
Colin Hebert

これは私のために働く:

隠しておく必要がある場合、これは動作します

git stash && git stash apply && git diff -w > foo.patch && git checkout . && git apply foo.patch && rm foo.patch

私は隠し場所が好きではありませんが、私はhave git + cygwinのバグに遭遇し、そこで変更が失われるので、少なくとも次のものをreflogに送りました。

git add . && git commit -am 'tmp' && git reset HEAD^ && git diff -w > foo.patch && git checkout . && git apply foo.patch && rm foo.patch

基本的に、スペースの変更を含まない差分を作成し、すべての変更を元に戻し、差分を適用します。

36
Frew Schmidt

実際の変更のみを含むパッチファイルを作成し(空白の変更のみを含む行を除く)、ワークスペースをクリーンアップし、そのパッチファイルを適用します。

git diff>バックアップ
git diff -w>変更
git reset --hard
パッチ<変更

残りの違いを確認してから、通常どおりaddおよびcommitを確認します。

Mercurialに相当するのは、これを行うことです。

hg diff>バックアップ
hg diff -w>変更
hg revert --all
hg import --no-commit changes

29
Steve Pitchers

以下を.gitconfigに追加します。

anw = !git diff -U0 -w --no-color -- \"$@\" | git apply --cached --ignore-whitespace --unidiff-zero "#"

@ Colin Herbert's answer に感謝します。

構文の説明

最後の#は、.gitconfig内のコメントとして扱われないように引用符で囲む必要がありますが、代わりに渡され、シェル内のコメントとして扱われます-git applyの最後とgitのユーザー指定の引数の間に挿入されますコマンドラインの最後に自動的に配置されます。これらの引数はここでは不要です-git applyがそれらを消費するのは望ましくありません。したがって、先行するコメント文字です。この動作を確認するには、このコマンドをGIT_TRACE=1 git anwとして実行することをお勧めします。

--は、引数の終わりを通知し、-wという名前のファイル、またはgit diffへのスイッチのように見えるものがある場合に対応します。

$@を囲む二重引用符は、ユーザーが指定した引用符付き引数を保持するためにエスケープする必要があります。 "文字がエスケープされない場合、.gitconfigパーサーによって消費され、シェルに到達しません。

注:.gitconfigエイリアス解析は、単一引用符を特別なものとして認識しません。その特殊文字は"\\n、および;"で囲まれた文字列の外側)のみです。これが、単一引用符で囲まれた文字列内にあるように見える場合でも、"を常にエスケープする必要がある理由です(gitは完全に不可知です)。

これは重要です、例えば。作業ツリーのルートでbashコマンドを実行するための便利なエイリアスがある場合。誤った定式化は次のとおりです。

sh = !bash -c '"$@"' -

正しいものは:

sh = !bash -c '\"$@\"' -
9
Tom Hale

コメントのユーザーによると、パッチコンテキスト内の空白のため、トップ投票の回答はすべての場合に機能しません。

コマンドを次のように修正しました。

$ git diff -U0 -w --no-color | git apply --cached --ignore-whitespace --unidiff-zero

これにより、コンテキストのないパッチが生成されます。パッチの寿命は短いので問題にはなりません。

対応するエイリアス、他のユーザーによって既に提供されたものの改訂:

addw = !sh -c 'git diff -U0 -w --no-color "$@" | git apply --cached --ignore-whitespace --unidiff-zero' -
9
void.pointer

以下はどうですか:

git add `git diff -w --ignore-submodules |grep "^[+][+][+]" |cut -c7-`

バッククォート内のコマンドは、空白以外の変更があるファイルの名前を取得します。

6
karmakaze

最初に、末尾の空白が意図的なものかどうかを検討する必要があります。 Linuxカーネル、Mozilla、Drupal、およびKerberos(ウィキペディアのスタイルに関するいくつかの例を挙げると)を含む多くのプロジェクトは、末尾の空白を禁止しています。 Linuxカーネルのドキュメントから:

適切なエディターを入手し、行末に空白を残さないでください。

あなたの場合、問題は別の方法です:以前のコミット(そしておそらく現在のコミット)はこのガイドラインに従っていませんでした。

末尾の空白を本当に必要としている人はいないと思いますが、問題を修正することは歓迎すべき変更かもしれません。他のユーザーにも同じ問題が発生している可能性があります。また、末尾の空白を追加している貢献者は、そうしていることに気づいていない可能性があります。

問題を無視するようにgitを再構成しようとしたり、エディターのその他の望ましい機能を無効にしたりするのではなく、問題を説明するプロジェクトメーリングリストへの投稿から始めます。多くのエディター(およびgit自体)は、末尾の空白を処理するように構成できます。

0
Kevin Vermeer