8

私は git のサンプル命令をいくつか試していましたが、最初の試行でファイルをgit rm *削除しないという奇妙なケースに遭遇しました。.*なぜそうなのですか?

mkdir -p test_repo1/folder && cd test_repo1
touch .testfile1 .testfile2 testfile3 folder/testfile4 folder/.testfile5
git init && git add . && git commit -m "test commit"

次のようにするgit rmと、すべてのファイルを削除するためにもう一度実行する必要があります

$ git rm -r *
rm 'folder/.testfile5'
rm 'folder/testfile4'
rm 'testfile3'

$ git rm -r *
rm '.testfile1'
rm '.testfile2'

git が最初の試行ですべてのファイルを削除しないのはなぜですか? また、リポジトリ ルート内のファイルのみでこれが発生するのはなぜですか?

興味深いことに、私が持っているのがそれらだけの場合.testfiles、git は最初の試行自体でそれらを削除します。

私はgitバージョンを使用しています1.7.9.5

4

4 に答える 4

25

ワイルドカードはシェルによって展開され、ほとんどのシェルではデフォルトで展開にドット ファイルは含まれません。

したがって、git実行するまでに、最初のコマンドは

git rm -r folder testfile3

2番目はおそらくリテラル

git rm -r *

その後、それgit自体が拡張します。

キースが指摘したように、一度にすべてを削除するには、シェルがワイルドカードを展開しgitないようにして、最初に展開するようにします。これは、二重引用符または単一引用符、またはアスタリスクの前にバックスラッシュを使用して行うことができます。私は一重引用符を好む傾向があります:

git rm -r '*'
于 2013-10-14T15:37:55.063 に答える
6

シェルグロビング

実行git rm *すると、実際にはシェルのグロビング規則を使用して引数をgit-rm(1)に渡します。デフォルトでは、多くのシェルには隠しファイル (先頭にドットがあるファイルなど) が含まれていません。Bash では、dotglobGLOBIGNOREを使用してグロビング ルールを変更できます。例えば:

  • 組み込みのshoptを使用する:

    # set dotglob
    shopt -s dotglob
    
    git rm *
    
    # unset dotglob
    shopt -u dotglob
    
  • GLOBIGNORE変数を使用( dotglobも設定):

    # Run git within a modified environment that includes GLOBIGNORE.
    GLOBIGNORE='.git' git rm *
    
于 2013-10-14T17:00:14.683 に答える
4

user1281385 がコメントで指摘したように、シェルは*初めて展開されます。

2回目にドットファイルを削除する理由は、一致するファイルがなくなると、シェルはリテラルのアスタリスクを引数として残し(シェルによっては、代わりに少なくとも1つのバリアントがエラーになります)、gitが独自の処理を行うためです。マッチング。

于 2013-10-14T15:39:28.727 に答える
0

git rm -r .正しい構文は('dot')にする必要があることに注意してください。

さらに心配git rm -rなのは、Git 2.11 まで同じことを行う (空のパススペック文字列) です!

Emily Xie ( )によるコミット d426430 (2016 年 6 月 22 日)を参照してください。( 2016 年 10 月 26 日コミット 3b1e135Junio C Hamanoによってマージされました)emilyxxie
gitster

pathspec: pathspec として空の文字列を警告する

pathspec 要素としての空の文字列は、すべてのパスに一致します。
ただし、バグのあるスクリプトは、誤って空の文字列を変数に割り当て、Git コマンドの呼び出しに渡される可能性があります。次に例を示します。

path=... compute a path to be removed in $path ...
git rm -r "$paht"

これにより、現在のディレクトリ内のすべてのパスが意図せず削除されます。

この問題の修正には、2 段階のアプローチが必要です。

  • このように空の文字列を故意に使用する既存のスクリプトが存在する可能性があるため、最初のステップでは、(1) 空の文字列は無効な pathspec 要素になることを伝え、(2) ユーザーに " ."を使用するように求める警告を表示するだけです。すべてに一致することを意味します。

  • ステップ 2 では、数リリース サイクル後のフォローアップ パッチで警告が削除され、代わりにエラーがスローされます。


Git 2.15.x/2.16 (2018 年第 1 四半期) の更新:

「今後のリリースでは無効になります」というメッセージが消え、次のようになります。

empty string is not a valid pathspec.
please use . instead if you meant to match all paths

Emily Xie ( )によるcommit 9e4e8a6 (2017 年 6 月 7 日)を参照してください。Junio C Hamano ( )によるcommit 229a95a (2017 年 6 月 23 日) を参照してください。( 2017 年 11 月 6 日コミット 728c573Junio C Hamanoによってマージされました)emilyxxie
gitster
gitster

pathspec 要素としての空の文字列は、すべてのパスに一致します。
ただし、バグのあるスクリプトは、誤って空の文字列を変数に割り当て、Git コマンドの呼び出しに渡される可能性があります。次に例を示します。

path=... compute a path to be removed in $path ...
git rm -r "$path"

これにより、現在のディレクトリ内のすべてのパスが意図せず削除されます。

于 2016-10-28T21:07:00.500 に答える