Найти файлы, которых нет в .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

Связанный контент