gitがファイル名をrmに渡すように印刷する方法を制御しますか?

gitがファイル名をrmに渡すように印刷する方法を制御しますか?

次のコマンドを使用してgitからファイルを印刷すると、極端な場合があります。

git diff --no-renames --name-only

エッジケース1:スペース

--diff-filter=D説明のために追加)

# format 1: unquoted

$: touch 'foo bar.txt'
$: git add 'foo bar.txt'
$: git commit -m 'test'
$: rm 'foo bar.txt'

$: git diff --no-renames --name-only --diff-filter=D
foo bar.txt

エッジケース2:特殊文字

# format 2: quoted

$: touch 'foo
bar.txt'
$: git add 'foo$\nbar.txt'
$: git commit -m "test"
$: rm foo$'\n'bar.txt

$: git diff --no-renames --name-only --diff-filter=D
'foo\nbar.txt'

また、foo bar.txt現在の状態で削除のために送信することはできません'foo\nbar.txt'rmさらに、彼らは一貫性がありません。

ファイル名をそのまま削除できるgitようにファイル名の形式を制御する方法はありますか?rm

答え1

awkの使い方をご存知ですか?引用符内にスペースを含む名前を含めるには、$0 の前後の引用符をエスケープします。 rmはこの形式でうまく機能します。

git diff --no-renames --name-only | awk '{system("rm \""$0"\"")}'

2番目の極端なケースでは、例で使用されている改行文字を除くすべての特殊文字に対して次のことが機能します。

git diff --no-renames --name-only | awk '{system("rm "$0)}'

名前にスペースを含めることはすでに悪い習慣であり、これらの正確な問題のために避けるべきです。名前に改行制御文字を含めると複雑さだけが追加されますが、利点はありません。名前に改行を使用するケースは何ですか?

答え2

git diff --no-renames --name-only -z | xargs -0 -I {} sh -c 'rm -- "{}"'私は彼と一緒に行きました。

関連情報