특정 문자열에 대해 저장소의 모든 Git 및 Mercurial 커밋을 검색하는 방법은 무엇입니까?


287

분기가 적고 매달려있는 커밋이있는 Git 저장소가 있습니다. 저장소에서 이러한 모든 커밋을 검색하여 특정 문자열을 찾고 싶습니다.

나는 역사에서 모든 커밋에 대한 로그를 얻는 방법을 알고 있지만, HEAD의 역사 인 분기 또는 매달려있는 얼룩은 포함하지 않습니다. 잘못 배치 된 특정 커밋을 찾기 위해 모든 것을 얻고 싶습니다.

스위치를 고려할 때 Mercurial에서이 작업을 수행하는 방법도 알고 싶습니다.


답변:


331

당신은 매달려 커밋을 볼 수 있습니다 git log -g.

-g, --walk-reflogs
 Instead of walking the commit ancestry chain, walk reflog entries from
 the most recent one to older ones. 

따라서 매달려있는 커밋 메시지에서 특정 문자열을 찾기 위해이 작업을 수행 할 수 있습니다.

git log -g --grep=search_for_this

또는 특정 문자열의 변경 사항을 검색하려면 pickaxe 검색 옵션 인 "-S"를 사용할 수 있습니다.

git log -g -Ssearch_for_this
# this also works but may be slower, it only shows text-added results
git grep search_for_this $(git log -g --pretty=format:%h)

Git 1.7.4는 -G 옵션추가하여 -G <regexp>를 전달하여 <regexp>를 포함하는 행이 이동 한시기를 찾아 -S는 할 수 없습니다. -S는 문자열을 포함하는 총 줄 수가 변경된 경우에만 알려줍니다 (예 : 문자열 추가 / 제거).

마지막으로 gitk를 사용하여 댕글 링 커밋을 시각화 할 수 있습니다 :

gitk --all $(git log -g --pretty=format:%h)

그런 다음 검색 기능을 사용하여 잘못 배치 된 파일을 찾으십시오. 누락 된 커밋이 "만료"되지 않고 가비지 수집되었다고 가정하는 이러한 모든 작업은 30 일 동안 매달려 있고 참조 로그를 만료하거나 만료 된 명령을 실행할 경우 발생할 수 있습니다.


4
어쩌면 프로젝트의 어딘가에 'search_for_this'가있는 모든 커밋을 찾을 수있는 커밋 수만큼 커밋에서 "git grep"을 실행하는 대신 소위 "pickaxe"검색, 즉 git log에 대한 '-S'옵션을 사용합니다. 는 주어진 문자열을 도입하거나 제거한 커밋을 찾거나 주어진 문자열의 발생 횟수가 변경된 위치를보다 정확하게 찾습니다.
Jakub Narębski

5
여러 가지를 지정하거나 사용 '--all'옵션, 예를 들어 '자식은 = --all "A의 문자열이 커밋 메시지를"--grep 로그인'
야쿱 Narębski에게

이것은 단지 2 일의 일 동안 잃어버린 커밋을 찾을 수있게했습니다. 내 엉덩이를 완전히 구해줘 서 고마워!
Mike Chamberlain

2
내 데이터베이스에는 커밋했지만 내 레퍼런스에는없는 일부 상황을 겪었습니다. 이것이 얼마나 흔한 지 모르겠습니다. 다른 hg / git 브릿지를 시도하고있었습니다. 나는 그것이 줄어든 스테이크에서 발생할 수 있다고 생각합니다. 어쨌든,이 별명은 이러한 경우를 포착하기 위해 훌륭하게 작동합니다.!git fsck --unreachable | sed -ne 's/^unreachable commit //p' | xargs git log --no-walk
dubiousjim

메모 개체 검색은 포함되지 않습니다. 아직 구현되지 않았습니다 : git.661346.n2.nabble.com/…
Antony Stubbs

54

Mercurial에서는 hg log --keyword커밋 메시지에서 키워드 hg log --user를 검색하고 특정 사용자를 검색하는 데 사용합니다. hg help log로그를 제한하는 다른 방법을 참조하십시오 .


36
Josip은 자신이 Mercurial로 전환하는 것을 고려하고 있으며 그것이 어떻게 진행되고 있는지 듣고 싶다고 썼다.
Martin Geisler

1
hg log -k검색은 변경 세트에서도 사용자 이름과 파일 이름을 커밋합니다 (commands.py:log에서 볼 수 있음). 이것은 hg에서 이해하지 못하는 몇 가지 중 하나입니다. 커밋 메시지와 파일 이름을 검색하는 별도의 옵션이 있어야합니다. hg log --template '{desc}\n'|grep확실한 방법 인 것 같습니다 .
Geoffrey Zheng

@ GeoffreyZheng : 그렇게하는 방법이 있습니다. "hg help revsets"를 참조하십시오 (예 : desc (), user () 및 file () 함수). 이 동작의 대부분에 대한 hg 로그 스위치도 있습니다. 내 경험상 -k / keyword ()는 일반적으로 물건을 검색하는 가장 유용한 방법입니다.
Kevin Horn

실제로 커밋 된 파일 내용 ... diff를 어떻게 검색합니까? 검색 속도가 느리다는 것을 알고 있지만 누락 된 기능 이름에 대한 심층 검색을 원합니다.
Jonathan

오 여기 있습니다 :hg grep --all <term>
Jonathan

24

또는 사용에 대한 richq 답변 외에도 현재 git 관리자 인 Junio ​​C Hamano 의 다음 블로그 게시물을 살펴보십시오.git log -g --grep=<regexp>git grep -e <regexp> $(git log -g --pretty=format:%h)


요약

git grepgit log --grep 는 모두 지정된 패턴과 일치하는 행을 찾기 때문에 행 지향적 입니다.

패턴 중 하나 (내재적 OR 의미) 와 일치 하는 커밋을 찾기 위해 git log --grep=<foo> --grep=<bar>(또는 git log --author=<foo> --grep=<bar>내부적으로 2로 변환되는 --grep) 사용할 수 있습니다 .

라인 지향되는 때문에 유용 AND 의미를 사용하는 것이 git log --all-match --grep=<foo> --grep=<bar>발견 커밋 즉 갖는 제 광고 매칭 라인 초 대체로 일치.

으로 git grep여러 패턴 (이용해야하는 모든 결합 할 수 있습니다 -e <regexp>와 함께 양식) --or(기본값), --and, --not, (). grep --all-match파일에 각 대안과 일치하는 행이 있어야 함을 의미합니다 .


야 쿠브, 여기 블로그 게시물의 인용문 / 요약을 통합 할 생각이 있습니까? 빈티지 링크 전용 답변 중 하나처럼 보입니다.
Nathan Tuggy

11

rq의 답변을 바탕 으로이 줄이 내가 원하는 것을한다는 것을 알았습니다.

git grep "search for something" $(git log -g --pretty=format:%h -S"search for something")

커밋 ID, 파일 이름을보고하고 다음과 같이 일치하는 줄을 표시합니다.

91ba969:testFile:this is a test

... 누구든지 이것이 표준 git grep 명령에 포함되기에 좋은 옵션이라는 데 동의합니까?


5

인수로 참조를받는 모든 명령 은 다음과 같이 --all매뉴얼 페이지에 문서화 된 옵션 을 허용합니다 git rev-list.

   --all
       Pretend as if all the refs in $GIT_DIR/refs/ are listed on the
       command line as <commit>.

따라서 예를 들어 git log -Sstring --all언급 string하고 분기 또는 태그에서 액세스 할 수있는 모든 커밋을 표시합니다 (댕글 링 커밋은 적어도 태그로 이름이 지정된 것으로 가정합니다).


3
이것은의 경우로 표시되지 않습니다 git grep, --all사용에 / 번역 얻을 것으로 보인다 --all-match. 이것은 나에게 버그처럼 보인다. Git 1.7.2.3 사용 ( $(git rev-list --all)작품 사용 ).
blueyed

5

Mercurial을 사용하면

$ hg grep "search for this" [file...]

검색되는 개정 범위를 좁히는 다른 옵션이 있습니다.


1
나는 또한 깃발을 좋아합니다hg grep --all
Jonathan

2

git에 대해 모르지만 Mercurial에서는 hg 로그 출력을 sed / perl / whatever 스크립트에 파이프하여 원하는 것을 검색합니다. 원하는 경우 템플릿이나 스타일을 사용하여 hg 로그의 출력을 사용자 정의하여보다 쉽게 ​​검색 할 수 있습니다.

여기에는 리포지토리의 모든 명명 된 분기가 포함됩니다. 머큐리얼에는 매달린 얼룩 모양이 없습니다.


1
이 답변이 지정된 문제와 어떤 관련이 있는지 이해할 수 없습니다.
jribeiro

3
그것은 머큐리얼의 질문에 대한 답변이며, 마지막 질문에서 원래의 질문에 대해 묻습니다.
Kurt Schelfthout


1

아직 언급되지 않은 솔루션을 하나 더 추가하려면 gitg의 그래픽 검색 상자를 사용하는 것이 가장 간단한 해결책이라고 말해야했습니다. 첫 번째 항목을 선택하고 Ctrl-G를 사용하여 다음 항목을 찾을 수 있습니다.


1

git의 한 명령은 문자열을 찾는 것이 훨씬 쉽다고 생각합니다.

git log --pretty=oneline --grep "string to search"

힘내 2.0.4에서 작동

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