web-dev-qa-db-ja.com

gitignoreパターンマッチングの説明

次のディレクトリツリーがあります。

> #pwd is the repo   
> tree -a
.
├── .git
│   |.....
├── .gitignore
├── README.md
├── f1.html
├── f2.html ... and some more html
├── images
│   └── river.jpg
>

また、.gitignore

> cat .gitignore
*
!*.html
!images/*.*
>

Imagesディレクトリ内のすべてのファイルをレポジトリに含めるようにします。しかし、それは起きていません。 gitignoreで以下を使用して動作するようにしました:

*
!*.html
!images*
!*.jp*g

ここで何が起きてるの? gitignoreをテストする確実な方法はありますか。 documentation を確認しました。理解できない点を次に示します(これはpattern format見出しの下にあります):

それ以外の場合、Gitはパターンをfnmatch(3)がFNM_PATHNAMEフラグで使用するのに適したシェルグロブとして扱います。パターンのワイルドカードはパス名の/に一致しません。たとえば、「Documentation/*。html」は「Documentation/git.html」と一致しますが、「Documentation/ppc/ppc.html」または「tools/perf/Documentation/perf.html」とは一致しません。

19
kmad1729

まず、あなたの質問の難しい部分は、.gitignoreファイルの最初の行です:

*  // Says exclude each and every file in the repository,
   // unless I specify with ! pattern explicitly to consider it

最初に、.gitignoreの最初のバージョンを検討します。

  1. *は、リポジトリ内のすべてのファイルを除外します。
  2. !*.htmlはすべてのhtmlファイルを許可します。
  3. !images/*.* imagesフォルダー内のすべてのタイプのファイルを考慮します。

すべてのJPG/JPEGを含めるには、3行目に!*.jp*gを追加するだけで済みます。これにより、gitは、そのファイルが存在するフォルダーに関係なく、すべてのjpgおよびjpegを考慮します。しかし、jpgだけでなく、imagesフォルダー内の任意のタイプのファイルのみが必要でした。それに関連するいくつかのドキュメントを読んでみましょう。第3セクションではソリューションの部分に進みます。


フォルダーの考慮事項に関するGitの無視パターン:

  1. スラッシュのみで終わるパターン:パターンが<dir-name>/で終わる場合、gitはそのディレクトリおよび他のすべてのサブディレクトリに含まれるファイルを無視します。ドキュメントで与えられた例として

    foo/は、ディレクトリfooおよびその下のパスと一致しますが、通常のファイルまたはシンボリックリンクfooとは一致しません

    ただし、除外されたディレクトリ内のファイルに一致するパターンがある場合、gitはそれを考慮しません。

  2. パターンにスラッシュはありません:スラッシュで終わらない無視リストにディレクトリ名を指定している場合、gitはそれを単なるパターンとみなします。そのパス名を持つファイル。

    パターンにスラッシュ/が含まれていない場合、Gitはそれを Shell glob pattern として扱い、場所に関連するパス名との一致をチェックします

  3. スラッシュと特殊文字を含むパターン(* /?):パターンが指定した最初の例のように終了する場合、images/*.*文書で指定されたとおりに動作します

    例:「Documentation/*。html」は「Documentation/git.html」と一致しますが、「Documentation/ppc/ppc.html」または「tools/perf/Documentation/perf.html」とは一致しません。


解決

3番目の点を考慮するgitは、!images/*.*パターンの画像ディレクトリ内のすべてのファイルを考慮する必要があります。しかし、ドキュメントにはもう1つの重要なポイントがあると言われているので、そうではありません。

Gitは除外されたディレクトリをリストしません

最初の行*のため、「images」ディレクトリ自体は無視されます。そのため、最初にgitにimagesディレクトリを考慮し、後で必要に応じて他のタイプを考慮するように追加の行を明示的に指定する必要があります。

*
!*.html
!images/                 // <- consider images folder
!images/*.*

Note:最後の行は、すべてのタイプのファイルを、そのサブディレクトリからではなく、imagesディレクトリからのみ考慮します。 (セクション2の3番目のポイント)

28
rajuGT