Find
如何在給定文件夾中查找所有 git 儲存庫(快速)
天真的方法是
find dir1 dir2 dir3 -type d -name .git | xargs -I {} dirname {}
,但對我來說太慢了,因為我在 git 儲存庫中有很多深層文件夾結構(至少我認為這是原因)。我已經讀過關於我可以prune
用來防止 find 一旦找到某些東西就遞歸到目錄中的內容,但是有兩件事。我不確定這是如何工作的(我的意思是我不明白prune
雖然我已經閱讀了手冊頁),第二個它在我的情況下不起作用,因為它會阻止find
遞歸到.git
文件夾但不能遞歸到所有其他文件夾。所以我真正需要的是:
對於所有子目錄,檢查它們是否包含
.git
文件夾,如果是則停止在此文件系統分支中搜尋並報告結果。如果這也能從搜尋中排除任何隱藏目錄,那將是完美的。
好的,我仍然不完全確定它是如何工作的,但是我已經對其進行了測試並且它可以工作。
. ├── a │ ├── .git │ └── a │ └── .git └── b └── .git 6 directories, 0 files % find . -type d -exec test -e '{}/.git' ';' -print -prune ./a ./b
我期待著更快地做出同樣的事情。
可能的解決方案
對於 GNU
find
和其他支持的實現-execdir
:find dir1 dir2 dir3 -type d -execdir test -d '.git' \; -print -prune
(見評論)
之前討論過的東西
如果在下面修剪
.git
就足夠了,則解決方案find dir1 dir2 dir3 -type d -path '*/.git' -print -prune | xargs -I {} dirname {}
如果
-printf '%h'
支持(如 GNU’s 的情況find
),我們不需要dirname
:find dir1 dir2 dir3 -type d -path '*/.git' -printf '%h\n' -prune
一旦遇到
.git
目前路徑中的文件夾,它將輸出它,然後停止進一步向下查找子樹。
.git
找到a 後是否應修剪整個文件夾樹的解決方案
-quit
如果您find
支持, 請使用:for d in dir1 dir2 dir3; do find "$d" -type d -name .git -print -quit done | xargs -I {} dirname {}
(根據Stéphane Chazelas
-quit
的這篇詳細文章,GNU 和 FreeBSDfind
以及 NetBSD支持-exit
.)再次
-printf '%h'
如果支持:for d in dir1 dir2 dir3; do find "$d" -type d -name .git -printf '%h\n' -quit done
.git
與文件夾所在級別相同的修剪解決方案有關此特定問題的目前解決方案,請參閱**“可能的解決方案”**部分。
(哦,顯然使用的解決方案
xargs
假設路徑中沒有換行符,否則您將需要空字節魔術。)