순진한 방법은 이지만 find dir1 dir2 dir3 -type d -name .git | xargs -I {} dirname {}
git 저장소에 깊은 폴더 구조가 많기 때문에 나에게는 너무 느립니다(적어도 그것이 이유라고 생각합니다). prune
뭔가를 찾은 후 find가 디렉토리로 반복되는 것을 방지하기 위해 사용할 수 있는 내용에 대해 읽었 지만 두 가지가 있습니다. 이것이 어떻게 작동하는지 잘 모르겠습니다( prune
맨 페이지를 읽었지만 그것이 무엇인지 이해하지 못합니다). 두 번째는 파일 폴더 find
에 대한 재귀를 차단하기 때문에 제 경우에는 작동하지 않습니다. .git
이지만 모든 폴더의 다른 폴더로 반복되지는 않습니다.
그래서 나에게 정말로 필요한 것은:
모든 하위 디렉터리에 대해 폴더가 포함되어 있는지 확인하고 .git
, 그렇다면 이 파일 시스템 분기에서 검색을 중지하고 결과를 보고합니다. 검색에서 숨겨진 디렉터리도 제외하면 완벽할 것입니다.
답변1
글쎄, 아직 그것이 어떻게 작동하는지 완전히 확신할 수는 없지만, 테스트해 본 결과 작동합니다.
.
├── a
│ ├── .git
│ └── a
│ └── .git
└── b
└── .git
6 directories, 0 files
% find . -type d -exec test -e '{}/.git' ';' -print -prune
./a
./b
나는 이 일을 더 빨리 하기를 고대하고 있다.
답변2
이상적으로는 디렉토리 트리를 크롤링하여 항목이 포함된 디렉토리를 찾고 .git
해당 디렉토리에 대한 추가 검색을 중지하는 것이 좋습니다(git 저장소에 더 이상 git 저장소가 없다고 가정).
문제는 표준을 사용하여 find
이 검사(디렉토리에 항목이 포함되어 있는지 .git
) 를 수행하면 test
조건자 실행 유틸리티를 사용하여 프로세스를 생성하는 작업이 포함된다는 점입니다 -exec
. 이는 여러 디렉터리의 내용을 나열하는 것보다 덜 효율적입니다.
find
한 가지 예외는 쉘 의 내장 기능 bosh
(Bourne 쉘에서 개발된 POSIXified 포크)을 사용하는 경우입니다.@힐리) 여기에는 -call
새로운 sh 인터프리터를 생성하지 않고 셸에서 코드를 평가하는 조건자가 있습니다.
#! /path/to/bosh -
find . -name '.?*' -prune -o \
-type d -call '[ -e "$1/.git" ]' {} \; -prune -print
또는 perl
다음을 사용하십시오 File::Find
.
perl -MFile::Find -le '
sub wanted {
if (/^\../) {$File::Find::prune = 1; return}
if (-d && -e "$_/.git") {
print $File::Find::name; $File::Find::prune = 1
}
}; find \&wanted, @ARGV' .
zsh
GNU printf '%s\n' **/.git(:h)
(숨겨지지 않은 모든 디렉터리에 포함) 또는 GNU find
(숨겨지지 않은 각 디렉터리에 대해 새 프로세스에서 명령 실행 find . -name '.?*' -prune -o -type d -exec test -e '{}/.git' \; -prune -print
)보다 길지만 더 빠릅니다.test
2022년 편집. 최신 버전의 busybox에는 프로세스를 포크하고 내부적으로 다시 실행하지 않고도 해당 애플릿을 find
실행할 수 있는 기능이 있으므로 여전히 bosh 또는 perl 방법만큼 빠르지는 않습니다.[
test
busybox find . -type d -exec [ -e '{}/.git' ] ';' -prune -print
내 테스트에서는 GNU에 상응하는 것보다 훨씬 빠른 속도를 보였습니다 find
(git/cvs/svn 저장소가 혼합되어 있고 총 100,000개가 넘는 디렉터리가 포함된 로컬 샘플에서 bosh의 경우 0.25초, Perl의 경우 0.3초, busybox의 경우 0.7초를 얻었습니다). ) find
, GNU의 경우 36초 find
, GNU의 경우 2초 ( git 저장소의 하위 디렉터리에서도 파일을 찾기 find . -name .git -printf '%h\n'
때문에 다른 결과를 제공합니다 )..git
답변3
찾기를 사용하면 다음 내용이 포함된 디렉터리를 찾을 수 있습니다.
locate .git | grep "/.git$"
결과 목록은 빠르고 추가 처리도 쉽습니다.
답변4
ls -d */.git
사용 후 .git
마지막에 떼어 내셔도 됩니다 .
하위 폴더는 검색되지 않습니다.