我有显示项目中文件的 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