특정 폴더에서 모든 git 저장소를 (빠르게) 찾는 방법

특정 폴더에서 모든 git 저장소를 (빠르게) 찾는 방법

순진한 방법은 이지만 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' .

zshGNU 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마지막에 떼어 내셔도 됩니다 .

하위 폴더는 검색되지 않습니다.

관련 정보