追加の違いは何ですかbin
、bin/
、bin/*
そしてbin/**
私の.gitignoreファイルで?私はこれまで使用してきましたがbin/
、他の .gitignoreファイルを見ると(日食ファイルでは、二重星と単一星が次のように一緒に使用さtmp/**/*
れています:どうしたのですか?)最初の2つのパターンも広く使用されていることがわかります。誰かが3つの違いを説明できますか?
追加の違いは何ですかbin
、bin/
、bin/*
そしてbin/**
私の.gitignoreファイルで?私はこれまで使用してきましたがbin/
、他の .gitignoreファイルを見ると(日食ファイルでは、二重星と単一星が次のように一緒に使用さtmp/**/*
れています:どうしたのですか?)最初の2つのパターンも広く使用されていることがわかります。誰かが3つの違いを説明できますか?
回答:
bin
'bin'という名前のファイルまたはディレクトリに一致します。
bin/
'bin'という名前のディレクトリと一致します。これは、Gitがディレクトリだけを追跡しないため、事実上すべてのコンテンツを意味します。
bin/*
任意の内のすべてのファイルとディレクトリに直接一致しますbin/
。これにより、Gitがサブディレクトリ内のファイルを自動的に検出するのを防ぎますが、たとえばbin/foo
サブディレクトリが作成された場合、このルールはの内容と一致しませんfoo
。
bin/**
任意のbin/
ディレクトリとそのすべてのサブディレクトリ内のすべてのファイルとディレクトリに一致します。
ルールはリポジトリルートに関連しておらず、ファイルシステムツリーのどこにでも適用されるため、ここでは「any」という単語が重要です。ルールは/
(または!/
意図したものだけに一致させるには、システムのルートではなく、リポジトリのルートを意味する無視しない)で。
警告:あなたがすべき決してようなルールを使用しないdir/*
、/dir/**
などだけでは、あなたもそのディレクトリ内に存在する何かをアン無視しない限り。アスタリスクを省略してください。そうしないとgit gc
、git stash
などの特定の呼び出しから大量のデータが永久に失われる可能性があります。
どういうtmp/**/*
意味なのかよくわかりません。私は当初tmp/
、tmp/
それ自体に直接存在するファイルではなく、のサブディレクトリ内のファイルを照合するために使用できると考えていました。しかし、簡単なテストでは、これが内のすべてのファイルを無視することを示唆しているようですtmp/
。
bin/
とはbin/**
?
bin/
binディレクトリは無視されると思いbin/**
ますが、binディレクトリは含まれますが、その内容は含まれません
bin/
引き出すと、ディレクトリ自体(すべてのサブディレクトリとファイルを含む)bin/**
が無視されますが、binディレクトリとそのサブディレクトリ内のすべてのファイルは無視されますが、binディレクトリ自体は無視されません。それが正確かどうかはわかりません。
bin/** \n !bin/*
ミニ
bin
一致した両方の名前のファイルbin
との内容bin
のフォルダを。第三に、そのサブディレクトリ内のすべてのファイルとbin/*
一致します。あなたたちはこれをテストしましたか?
bin
そしてbin/
後者の意志が唯一のディレクトリと一致していることだけが異なります。
bin/**/*
と同じですbin/**
(@VonCの回答によると、明らかに1.8.2以降)。
トリッキーなのは、私が1時間ほどかけて髪を引き裂いたことですが、bin/
それbin/**
はまったく同じではありません。前者はディレクトリ全体を無視し、後者はその中の各ファイルを無視し、ほとんどの場合gitはディレクトリを気にしないため、通常は違いはありません。ただし、を使用!
してサブパスを無視しないようにしようとすると、親ディレクトリを無視するとgit(ahem)がサブパスを無視することがわかります。(ここでも、ディレクトリの内容ではなく)
これは例で最も明確なので、新しく初期化されたリポジトリの場合は次のように設定します。
$ cat .gitignore
ignored-file
or-dir
dir-only/
!dir-only/cant-reinclude
dir-contents/**
!dir-contents/can-reinclude
$ mkdir or-dir dir-only dir-contents
$ touch file ignored-file or-dir/ignored-file dir-only/cant-reinclude dir-contents/can-reinclude
次の追跡されていないファイルが存在します。
$ git ls-files --other
.gitignore
dir-contents/can-reinclude
dir-only/cant-reinclude
file
ignored-file
or-dir/ignored-file
ただし、次のファイルが無視されていないことがわかります。
$ git ls-files --other --exclude-standard
.gitignore
dir-contents/can-reinclude
file
そして、追加しようとすると、次のようになります。
$ git add dir-only/cant-reinclude
The following paths are ignored by one of your .gitignore files:
dir-only/cant-reinclude
Use -f if you really want to add them.
fatal: no files added
この動作はバグだと思います。(これはすべてオンですgit version 1.8.4.msysgit.0
)
dir/
とdir/**
reの異なる動作。!
「ファイルの親ディレクトリが除外されている場合、ファイルを再インクルードすることはできません」[ソース]が原因で、無視しないことが発生します。紛らわしいですが、パフォーマンス上の理由で行われます。関連するSOの質問を参照してください。
厳密に言えば、gitはディレクトリを追跡せず、ファイルのみを追跡することに注意してください。したがって、ディレクトリを追加することはできず、その内容のみを追加できます。
.gitignore
ただし、このコンテキストでは、gitは、次の唯一の理由でディレクトリを理解するふりをします。
そのファイルの親ディレクトリが除外されている場合、そのファイルを再度含めることはできません。
https://git-scm.com/docs/gitignore#_pattern_format
これは除外パターンにとってどういう意味ですか?それらを詳しく見ていきましょう:
bin
これは無視します
bin
。。bin
bin
後続の!
エントリを追加することで、無視されたファイルとフォルダをホワイトリストに登録できますが、名前の付いたフォルダの内容をホワイトリストに登録することはできませんbin
bin
!bin/file_in_bin # has no effect, since bin/ is blacklisted!
!bin/* # has no effect, since bin/ is blacklisted!
!file_in_bin # has no effect, since bin/ is blacklisted!
!bin # this works
bin/
。という名前のファイルと一致しないことを除いて、上記と同じですbin
。末尾を追加する/
と、gitはディレクトリのみに一致するようになります。
bin/*
これは無視します
bin
bin
bin/* # blacklists bin/file_in_bin and bin/subfolder/
!bin/subfolder/file_in_sub # has no effect, since bin/subfolder is blacklisted!
!bin # whitelists files named bin/bin, since bin/ itself is not blacklisted
!bin/ # has no effect, since bin/ itself is not blacklisted
!bin/file_in_bin # works since bin/ itself is not blacklisted
!file_in_bin # works too
!bin/subfolder # works (so implicitly whitelists bin/subfolder/file_in_sub)
!bin/subfolder/ # works just as well
!bin/* # works for file_in_bin and subfolder/
bin/**
これは無視します
bin
bin
bin/** # blacklists bin/file_in_bin and
# bin/subfolder/ and bin/subfolder/file_in_sub and
# bin/subfolder/2/ and bin/subfolder/2/file_in_sub_2
!bin/subfolder/file_in_sub # has no effect, since bin/subfolder is blacklisted
!bin/subfolder/2/ # has no effect, since bin/subfolder is blacklisted
!bin/subfolder/2/file_in_sub_2 # has no effect, since bin/subfolder is blacklisted
!bin/subfolder # works only in combinations with other whitelist entries,
# since all contents of subfolder are blacklisted (1)
!bin/file_in_bin # works since bin itself is not blacklisted
!bin/* # works for file_in_bin and subfolder; see (1)
新しいリポジトリを作成して、いくつか試してみました。これが私の結果です:
gitバージョン2.10.1.windows.1
bin
深いディレクトリいくつかの層を
bin.txt
Test.txt
bin/a/b/bin.txt
bin/a/b/Test.txt
bin/a/bin/bin.txt
bin/a/bin/Test.txt
bin/a/bin.txt
bin/a/Test.txt
bin/bin.txt
bin/Test.txt
bin
gitignoreに追加:結果
bin
ディレクトリの下(およびそれより深い)はすべて無視されるようになりましたbin
にbin/
gitignoreで:結果
bin/
するbin/*
bin/*
するbin/**
bin/**
するbin/**/
bin/bin.txt
そしてbin/Test.txt
、もはや無視されていませんbin/**/
するbin/**/*
bin/bin.txt
そして、bin/Test.txt
、無視されることに戻っていますgitバージョン:2.7.0.windows.1
bin
深いディレクトリいくつかの層を
bin/a/b/Test.txt
bin/a/bin/Test.txt
bin/a/Test.txt
bin/Test.txt
bin
gitignoreに追加:結果
bin
ディレクトリの下(およびそれより深い)はすべて無視されるようになりましたbin
にbin/
gitignoreで:結果
bin
ディレクトリの下(およびそれより深い)はすべて無視されます(変更なし)bin/
するbin/*
bin
ディレクトリの下(およびそれより深い)はすべて無視されます(変更なし)bin/*
するbin/**
bin
ディレクトリの下(およびそれより深い)はすべて無視されます(変更なし)bin/**
するbin/**/
bin/Test.txt
無視されなくなりましたbin/**/
するbin/**/*
bin
ディレクトリの下(およびそれ以上)のすべてが再び無視されますなお、「**
」、サブディレクトリと組み合わせたときに(**/bar
)するので、そのデフォルトの動作から変更されている必要がありますgit1.8.2のリリースノートは今言及:
.gitignore
および.gitattributes
ファイルのパターンは、**/
サブディレクトリの0以上のレベルに一致するパターンとして持つことができます。たとえば、「
foo/**/bar
」bar
は「foo
」自体または「foo
」のサブディレクトリ内の「」と一致します。
覚えておくべきルール(そしてそれらの構文の背後にある意図の違いを理解するのに役立つ)は次のとおりです。
そのファイルの親ディレクトリが除外されている場合、そのファイルを再度含めることはできません。
通常、無視フォルダーfのサブフォルダーからファイルを除外する場合は、次のようにします。
f/**
!f/**/
!f/a/sub/folder/someFile.txt
あれは:
f/
場合、フォルダf/
は無視され、以下のルールf
は重要ではありません。f/**
同じを達成f/
ますが、すべてのサブ要素を無視する(ファイルやサブフォルダを)。!f/**/
。f
サブフォルダーが無視されるわけではないため、ファイルを除外するルールを追加できます(!f/a/sub/folder/someFile.txt
)との間には別の違いがbin/*
ありbin/
ます。
bin/
一致しますがfoo/bin/test.txt
(予想どおり)、一致bin/*
しません。これは奇妙に思えますが、文書化されています:https://git-scm.com/docs/gitignore
「Documentation / *。html」は「Documentation / git.html」と一致しますが、「Documentation / ppc /ppc.html」または「tools / perf / Documentation /perf.html」とは一致しません。
この理由は、次のルールのようです。
パターンがスラッシュで終わっている場合は、以下の説明のために削除されています…
パターンにスラッシュ/が含まれていない場合、Gitはそれをシェルグロブパターンとして扱い、.gitignoreファイルの場所に関連するパス名との一致をチェックします…
それ以外の場合、Gitはパターンをfnmatch(3)によるFNM_PATHNAMEフラグ付きの消費に適したシェルグロブとして扱います…
したがって、パターンがスラッシュで終わる場合、スラッシュは削除され、シェルグロブパターンとして扱われます。この場合、はにbin
一致しfoo/bin/test.txt
ます。で終わる場合/*
、スラッシュは削除されず、サブディレクトリで一致しないfnmatchに渡されます。
しかし、同じことが当てはまりないfoo/bin/
とfoo/bin/*
さえから最後のスラッシュを削除した後ので、foo/bin/
それはのfnmatchパターンではなく、グロブとして扱われますので、それはまだ、スラッシュが含まれています。つまり、一致しませんbar/foo/bin/test.txt