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.