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

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

プロジェクト内のファイルを表示する 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 ファイルには glob パターンを含めることができます (また、ファイルが .gitignore にある場合はパスでは機能しません)。glob を含む可能性のあるパターンに基づいてファイルをフィルターするにはどうすればよいでしょうか?

答え1

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 {} +

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

答え2

チェックアウトにあり、Gitによって追跡されているファイルを表示するには、

$ git ls-files

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

答え3

まさにこれを実行するための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サブモジュールも検索できます。

答え4

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

関連情報