Git 브랜치를 검색하여 파일이나 디렉토리를 찾으려면 어떻게해야합니까?


323

Git에서 여러 브랜치에서 경로로 파일이나 디렉토리를 어떻게 검색 할 수 있습니까?

지점에 무언가를 썼는데 어느 것을 기억하지 못합니다. 이제 찾아야합니다.

설명 : 나는 내 지점 중 하나에서 만든 파일을 찾고 있습니다. 내용이 무엇인지 기억하지 못하기 때문에 내용이 아닌 경로별로 찾고 싶습니다.


질문이 확실하지 않습니다. 이 파일이 현재 삭제 된 지점에 있었습니까? 파일이 삭제 되었습니까?
— Abizern

답변:


444

git log+ git branch당신을 위해 그것을 찾을 것입니다 :

% git log --all -- somefile

commit 55d2069a092e07c56a6b4d321509ba7620664c63
Author: Dustin Sallings <dustin@spy.net>
Date:   Tue Dec 16 14:16:22 2008 -0800

    added somefile


% git branch -a --contains 55d2069
  otherbranch

globbing도 지원합니다 :

% git log --all -- '**/my_file.png'

작은 따옴표는 (적어도 Bash 쉘을 사용하는 경우) 필요하므로 쉘은 glob 패턴을 변경하지 않고 git에 전달합니다 (Unix와 마찬가지로 find).


2
이 작품은 당신의 정확한 경로를 알고있는 경우 somefile: 당신은 예를 들어, 경로 / 파일 이름을 통해 검색 정규식 필요하다면, 당신은 ididak의 답변을 사용할 수 있습니다.
— ShreevatsaR

70
globbing도 지원합니다 :git log --all -- **/my_file.png
— webmat

3
나는 이것을 약간 다른 문제로 사용했다. 특정 지점에 커밋 한 모든 * .sql 파일을 찾으려고했습니다. 그래서 나는 사용했다 git log --grep='branch' --author='me' -- *.sql. 매력처럼 일했다. 자식 버전 1.7.11.1
— thepriebe

1
주 gitk지원은 물론 글 로빙. @webmat에 대한 훌륭한 답변입니다! 어디에서 삭제 / 생성 된 / etc git log --all --stat -- **/my_file.png가 있는지 확인하려면을 사용하면 삭제 한 커밋에서 체크 아웃하는지 추측 할 필요가 없습니다.
— eacousineau

1
@webmat : 글 러빙에 대한 정보를 자유롭게 추가 할 수있었습니다. 언급 해 주셔서 감사합니다!
— sleske

65

git ls-tree가 도움이 될 수 있습니다. 기존의 모든 지점을 검색하려면

for branch in `git for-each-ref --format="%(refname)" refs/heads`; do
  echo $branch :; git ls-tree -r --name-only $branch | grep '<foo>'
done

이것의 장점은 파일 이름을 정규식으로 검색 할 수도 있다는 것입니다.


3
(a) "git ls-tree"에 "-r"을 추가하여 파일이 서브 디렉토리에 있더라도 찾을 수 있도록합니다. (b) 첫 번째 줄에 대한 가장 좋은 대안은 "git for-each ref"를 사용하는 것입니다 git for-each-ref --format="%(refname)" refs/heads. (d)에 당신이 정확하게 파일 이름을 알 필요가 없습니다 즉 것을, 가치 이것의 장점은 더스틴의 솔루션을 통해이 있다고 답변에서 지적 될 수있다 - 당신이 경로의 일부와 일치하는 정규 표현식으로 검색 할 수 있습니다
— 마크 Longair

9
"gitfind.sh <regex>"를 실행할 수 있도록 스크립트로 묶었습니다. 요점은 gist.github.com/62d981890eccb48a99dc
— Handyman5

3
이것은 로컬 지점 에서만 검색 합니다. 원격 추적 분기를 검색하려면 refs/remotes대신을 사용하십시오 refs/heads. 모든 항목 (로컬 브랜치, 원격 추적 브랜치 및 태그)을 검색하려면을 사용하십시오 refs/.
— sleske

19

ididak의 응답 은 꽤 멋지 지만 Handyman5 는 그것을 사용하는 스크립트를 제공하지만 그 접근 방식을 사용하는 것이 약간 제한적이라는 것을 알았습니다.

때때로 시간이 지남에 따라 표시되거나 사라질 수있는 것을 검색해야하므로 모든 커밋에 대해 검색하지 않는 이유는 무엇입니까? 그 외에도 때로는 자세한 응답이 필요하고 다른 경우에는 일치하는 커밋 만 있습니다. 해당 옵션의 두 가지 버전이 있습니다. 다음 스크립트를 경로에 넣으십시오.

자식 찾기 파일

for branch in $(git rev-list --all)
do
  if (git ls-tree -r --name-only $branch | grep --quiet "$1")
  then
     echo $branch
  fi
done

자식 찾기 파일 상세

for branch in $(git rev-list --all)
do
  git ls-tree -r --name-only $branch | grep "$1" | sed 's/^/'$branch': /'
done

이제 할 수 있습니다

$ git find-file <regex>
sha1
sha2

$ git find-file-verbose <regex>
sha1: path/to/<regex>/searched
sha1: path/to/another/<regex>/in/same/sha
sha2: path/to/other/<regex>/in/other/sha

getopt 를 사용 하면 모든 커밋, 참조, 참조 / 헤드, 상세 정보 등을 번갈아 검색하도록 해당 스크립트를 수정할 수 있습니다.

$ git find-file <regex>
$ git find-file --verbose <regex>
$ git find-file --verbose --decorated --color <regex>

체크 아웃 https://github.com/albfan/git-find-file 가능한 구현합니다.


"이제 git-find-file <regex>을 할 수 있습니다"라는 의미입니까? 나는 그것을 작동 시켰습니다, 감사합니다!
— Elijah Lynn

1
개인적으로 $ (git rev-list --all) 대신 $ (git branch | cut -c 3-)를 사용하는 것이 훨씬 더 유용하다는 것을 알았습니다. 나는 커밋을 찾는 것에 신경 쓰지 않고 명명 된 지점에 관심이 있습니다.
— Campadrenalin

또한 모든 커밋에 대한 루프가 너무 느리기 때문에 $ (git branch | cut -c 3-)를 사용하도록 스크립트를 변경했습니다.
— i4h

내가 가진 소란을 보았을 때 이것에 대한 저장소를 만들 가치가 있습니다. github.com/albfan/git-find-file . 몇 가지 문제를 열었습니다. 더 제안하거나 PR을 보내십시오.
— albfan

1
경로에 @lumbric 설치 스크립트가 기본적으로 작동합니다.
— agitfan

10

gitk --all커밋 "터칭 경로"와 관심있는 경로 이름을 사용 하고 검색 할 수 있습니다 .


3
명시된 바와 같이 gitk --all을 사용하고 View | 새로운보기, 모든 지점을 활성화하십시오. 그런 다음 두 번째 필드에 검색 기준 : 파일 이름 (와일드 카드 포함)을 설정하십시오. 마지막으로 OK.
— MikeW

8

이것을 사용하여 복사하여 붙여 넣기 git find-file SEARCHPATTERN

검색된 모든 분기 인쇄 :

git config --global alias.find-file '!for branch in `git for-each-ref --format="%(refname)" refs/heads`; do echo "${branch}:"; git ls-tree -r --name-only $branch | nl -bn -w3 | grep "$1"; done; :'

결과가있는 가지만 인쇄하십시오.

git config --global alias.find-file '!for branch in $(git for-each-ref --format="%(refname)" refs/heads); do if git ls-tree -r --name-only $branch | grep "$1" > /dev/null; then  echo "${branch}:"; git ls-tree -r --name-only $branch | nl -bn -w3 | grep "$1"; fi; done; :'

이 명령은 최소한의 쉘 스크립트 ~/.gitconfig를 전역 git 별명 으로 직접 추가합니다 .


그것은 마스터 지점에서만 검색하고 있습니다
— Nasif Imtiaz Ohi

모든 지역 지점에서 검색
— Leonardo Herrera

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.