web-dev-qa-db-ja.com

.gitignore除外ルールは実際にどのように機能しますか?

大規模なディレクトリ構造でのgitignoreの問題を解決しようとしていますが、質問を簡単にするために次のように減らしました。

私は、新しいgitリポジトリに2つのファイル(foo、bar)の次のディレクトリ構造を持っています(これまでのところコミットはありません):

a/b/c/foo
a/b/c/bar

明らかに、「git status -u」は次を示します。

# Untracked files:
...
#       a/b/c/bar
#       a/b/c/foo

私がやりたいのは、a/b/c内のすべてを無視するが、ファイル「foo」を無視しない.gitignoreファイルを作成することです。

このように.gitignoreを作成すると:

c/

次に、「git status -u」は、fooとbarの両方が無視されたと表示します。

# Untracked files:
...
#       .gitignore

予想通りです。

Fooの除外ルールを追加すると、次のようになります。

c/
!foo

Gitignoreのマンページによると、これが機能すると期待しています。しかし、そうではありません-それはまだfooを無視します:

# Untracked files:
...
#       .gitignore

これも機能しません:

c/
!a/b/c/foo

これも行いません:

c/*
!foo

与える:

# Untracked files:
...
#       .gitignore
#       a/b/c/bar
#       a/b/c/foo

その場合、fooは無視されなくなりますが、barも無視されません。

.gitignoreのルールの順序も重要ではないようです。

これも私が期待することをしません:

a/b/c/
!a/b/c/foo

その1つはfooとbarの両方を無視します。

動作する1つの状況は、ファイルa/b/c/.gitignoreを作成してそこに配置した場合です。

*
!foo

しかし、これに関する問題は、最終的にa/b/cの下に他のサブディレクトリがあり、すべての個別の.gitignoreを配置する必要がないことです-私は「プロジェクトベース」の.gitignoreを作成したいと考えていました各プロジェクトの最上位ディレクトリにあり、すべての「標準」サブディレクトリ構造をカバーできるファイル。

これも同等のようです:

a/b/c/*
!a/b/c/foo

これは私が達成できる「作業」に最も近いかもしれませんが、完全な相対パスと明示的な例外を指定する必要があります。異なるレベルに「foo」という名前のファイルがたくさんある場合は苦痛になりますサブディレクトリツリーの。

とにかく、除外ルールがどのように機能するのかよくわからないか、ディレクトリが(ワイルドカードではなく)無視されると、/で終わるルールによってまったく機能しません。

誰もこれにいくらか光を当てることができますか?

このぎこちないシェルベースの構文の代わりに、gitignoreに正規表現のような賢明なものを使用させる方法はありますか?

Cygwin/bash3ではgit-1.6.6.1を使用し、Ubuntu/bash3ではgit-1.7.1を使用しています。

139
davidA
/a/b/c/*
!foo

私にはうまくいくようです(Linuxではgit 1.7.0.4)。 *は、ディレクトリ内のファイル(除外を許可する)ではなく、ディレクトリ自体を無視しているため(gitは内部を見ません)、重要です。

除外は、「これを含める」ではなく「これを含める」ではなく、「このディレクトリを無視する(/a/b/c/)これではなく(foo) "はあまり意味がありません;"このディレクトリ内のすべてのファイルを無視します(/a/b/c/*)これはありません(foo) "はしません。manページを引用するには:

オプションのプレフィックス!パターンを無効にします。以前のパターンで除外された一致するファイルは再び含まれます。

つまり、fileは、再び含まれるように既に除外されている必要があります。光を放つことを願っています。

141
Chris

私は同じような状況にあります、私の解決策は次のものを使用することでした:

/a/**/*
!/a/**/foo

**正しく。

24
medge799

別のオプションを次に示します。

*
!/a*
!/a/*
!/a/*/*
!/a/*/*/*

Aの3レベル下のファイル/ディレクトリを除く、すべてのファイルとディレクトリを無視します。

6
Peter Petrik

より一般的な注意事項として、git1.8.2には patch (または v4スタックオーバーフローの質問が表示されます )from Adam Spiers どのgitignoreルールが実際にファイルを無視するかを決定します。

git1.8.2リリースノート およびSO質問 " どのgitignoreルールが私のファイルを無視している :を参照してください。
それはコマンドになります git check-ignore

4
VonC

これは、.gitignoreのマニュアルページからは明らかに明確ではありません。これは動作します:

*
!/a
!/a/b
!/a/b/c
!/a/b/c/foo

# don't forget this one
!.gitignore

Chrisが述べたように、除外されたディレクトリは開かれません。そのため、一部のファイルを*だけ無視できるようにするには、上記のようにそれらのファイルへのパスを作成する必要があります。私にとってこれは便利です。なぜなら、ライブラリの1つのファイルに対してコードレビューを実行したいのですが、後で別のファイルを実行したい場合は追加するだけで、他のすべては無視されます。

4
user1115652