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