.gitignoreにないファイルを検索する


11

プロジェクト内のファイルを表示するfindコマンドがあります。

find . -type f -not -path './node_modules*' -a -not -path '*.git*' \
       -a -not -path './coverage*' -a -not -path './bower_components*' \
       -a -not -name '*~'

.gitignoreにあるファイルを表示しないようにファイルをフィルタリングするにはどうすればよいですか?

私は私が使うと思った:

while read file; do
    grep $file .gitignore > /dev/null && echo $file;
done

しかし、.gitignoreファイルはグロブパターンを持つことができます(ファイルが.gitignoreにある場合、パスでも機能しません)。グロブを持つ可能性のあるパターンに基づいてファイルをフィルタリングするにはどうすればよいですか?

回答:


11

git提供してgit-check-ignore、ファイルがで除外されているかどうかをチェックします.gitignore

だからあなたは使うことができます:

find . -type f -not -path './node_modules*' \
       -a -not -path '*.git*'               \
       -a -not -path './coverage*'          \
       -a -not -path './bower_components*'  \
       -a -not -name '*~'                   \
       -exec sh -c '
         for f do
           git check-ignore -q "$f" ||
           printf '%s\n' "$f"
         done
       ' find-sh {} +

チェックはファイルごとに実行されるため、これには大きなコストがかかることに注意してください。


find-sh {} +最後に何がありますか?
jcubic 2017

@jcubic unix.stackexchange.com/q/12902/38906を参照
cuonglm

わかりました、そして何find-shですか?
jcubic 2017

@jcubicこれは、inline-shスクリプトに付けた名前なので、エラーが発生した場合は、意味のあるエラーメッセージが表示されます
cuonglm

@jcubicトライfind /tmp -exec sh -c ': "${non_existed_var:?foo}"' find-sh {} +例えば
cuonglm

9

これを正確に行うためのgitコマンドがあります:例

my_git_repo % git grep --line-number TODO                                                                                         
desktop/includes/controllers/user_applications.sh:126:  # TODO try running this without sudo
desktop/includes/controllers/web_tools.sh:52:   TODO: detail the actual steps here:
desktop/includes/controllers/web_tools.sh:57:   TODO: check if, at this point, the menurc file exists. i.e. it  was created

あなたが述べたように、それは基本的なgrepを行い、通常のgrepオプションのほとんどを行い.gitますが、.gitignoreファイル内のファイルやフォルダーを検索したり、ファイルを検索したりしません。
詳細については、man git-grep

サブモジュール:

このgitリポジトリ内に他のgitリポジトリがある場合(それらはサブモジュールにあるはずです)、フラグ--recurse-submodulesを使用してサブモジュールも検索できます


すばらしいです。現在のディレクトリ内に他のgitリポジトリがあるため、ほとんど機能します。そのため、「*。git」を使用しています。
jcubic 2017

8

チェックアウト中にあり、Gitによって追跡されているファイルを表示するには、次のコマンドを使用します。

$ git ls-files

このコマンドには、キャッシュファイル、追跡されていないファイル、変更されたファイル、無視されたファイルなどを表示するためのいくつかのオプションがあります。を参照してくださいgit ls-files --help


私も考えてgit ls-filesいますが、追跡されていないファイルを表示するオプションはありませんか?
cuonglm 2017

1
@cuonglm -o(その他)。例:git ls-files -o -X .gitignore
Kusalananda

ああ、そうですが、ファイルが以前に追跡された場合は処理できませんが、に含めます.gitignore
cuonglm

マイナーな注意:これは、システムからの実際のファイルではなく、git履歴に含まれているファイルの一覧です。これは、大文字と小文字を区別しないシステム(Windows共有など)では微妙な違いになる可能性があります。たとえば、。/ foo.txtをコミットしたが、名前を./Foo.txtに変更したとします。いくつかのgitのクライアントはこの変更を認識せず、git ls-files出力は一方で./foo.txt findう出力./Foo.txt
Griddo

2

bash globが実行される配列を使用できます。

このようなファイルがあります:

touch file1 file2 file3 some more file here

そして、ignoreこのようなファイルを持っている

cat <<EOF >ignore
file*
here
EOF

使用する

arr=($(cat ignore));declare -p arr

この結果になります:

declare -a arr='([0]="file" [1]="file1" [2]="file2" [3]="file3" [4]="here")'

その後、任意の手法を使用してこれらのデータを操作できます。

私は個人的に次のようなものを好みます:

awk 'NR==FNR{a[$1];next}(!($1 in a))'  <(printf '%s\n' "${arr[@]}") <(find . -type f -printf %f\\n)
#Output
some
more
ignore

gitignorebashグロブのスーパーセットです、あなたは次のようなものを見逃します!file*
cuonglm '11

@cuonglmどういう意味!file*ですか?無視ファイルのグロブパターンとして、またはファイル名として?
George Vasiliou 2017

gitignore!file*始まるファイルを除外するようなファイルパターンを受け入れます。fileまた、二重スター**
cuonglm '11

.gitignoreにはたくさんの機能がありますが、Bashに直接実装するのはそれほど簡単ではないかもしれません:git-scm.com/docs/gitignore。単純なグロブのみで構成される無視は、awkなどなしでプレーンバッシュで実行できるはずです
ilkkachu

@cuonglmの翻訳で!はないのですか?たぶん拡張されたグロビングがこの状況を処理することができます。doublestarについては、bashで処理できshopt -s globstarます。
George Vasiliou 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.