모든 분기에서 문자열을 도입 한 Git 커밋을 찾는 방법은 무엇입니까?


396

어떤 분기에서 커밋에 도입 된 특정 문자열을 찾고 싶습니다. 어떻게 할 수 있습니까? 나는 (Win32 용으로 수정 한) 것을 찾았지만 git whatchanged다른 가지를 조사하지 않는 것 같습니다 (py3k 덩어리를 무시하고 msys / win 줄 바꿈 수정)

git whatchanged -- <file> | \
grep "^commit " | \
python -c "exec(\"import sys,msvcrt,os\nmsvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)\nfor l in sys.stdin: print(l.split()[1])\")" | \
xargs -i% git show origin % -- <file>

솔루션이 느리더라도 실제로 중요하지 않습니다.


답변:


685

넌 할 수있어:

git log -S <whatever> --source --all

추가 또는 제거하는 모든 커밋 찾으려면 고정 문자열을 whatever . 이 --all매개 변수는 모든 브랜치에서 시작하는 --source것을 의미하며 해당 브랜치 중 어느 것이 해당 커밋을 찾게했는지 보여줍니다. -p각 커밋이 소개 할 패치를 보여주기 위해 추가 하는 것이 종종 유용합니다 .

1.7.4 이후의 git 버전에도 비슷한 -G옵션이 있으며 정규 표현식이 필요합니다 . Junio ​​Hamano의이 블로그 게시물에서 설명했듯이 실제로는 의미가 다릅니다 (더 명백한) .

thameera 가 주석에서 지적한 것처럼 공백이나 다른 특수 문자가 포함 된 경우 검색어를 따옴표로 묶어야합니다.

git log -S 'hello world' --source --all
git log -S "dude, where's my car?" --source --all

다음은 -G발생을 찾기 위해 사용하는 예 입니다 function foo() {.

git log -G "^(\s)*function foo[(][)](\s)*{$" --source --all

19
우수성 +1 -S를 가리키는 것은 일을 더 잘 설명하는 것입니다. 또한, 나는 --decorate를 사용하여 어떤 가지가 나오는지 봅니다
sehe

7
@sehe : 좋은 의견 감사합니다. --decorate각 분기의 끝에 커밋에 분기 이름 만 추가 한다는 점은 주목할 가치가 있다고 생각합니다 . 실제로 정말 사용하지 않는 --source--decorate, 대신 사용 git branch -a --contains <commit-hash>지점은 내가 관심 커밋 포함하는 찾을 수 있습니다.
마크 Longair을

3
인라인 차이도 보려면 -p를 추가하십시오. FWIW
rogerdpack

1
@MarkLongair는 병합에서 변경된 사항을 표시하지 않습니다. 그것들을 보여줄 제안이 있습니까?
Pahlevi Fikri Auliya

2
나에게 이것은 -S와 검색어 사이의 공백을 제거하는 경우에만 작동합니다 git log -S"dude, where's my car?" --source --all. @ribamar는 또한 아래 답변에 썼지 만이 상위 답변 옆에 쉽게 간과 될 수 있습니다.
bug313


20

Mark Longair의 답변 은 훌륭하지만이 간단한 버전이 저에게 효과적이라는 것을 알았습니다.

git log -S whatever

24
명확히하기 위해 찾고있는 커밋이에있는 경우 제대로 작동 HEAD하지만이 특정 질문은 저장소의 모든 분기를 살펴 보는 것에 대해 구체적으로 질문했습니다.
Mark Longair

18

같은 대답으로 혼란스러워 :

$ git config --global alias.find '!git log --color -p -S '
  • ! 다른 방법으로, git은 인수를 -S에 올바르게 전달하지 않기 때문에 필요합니다. 참조 이 응답을
  • --color-p 는 정확히 "변경된"내용을 표시하는 데 도움이됩니다.

이제 할 수 있습니다

$ git find <whatever>

또는

$ git find <whatever> --all
$ git find <whatever> master develop

6
git log -S"string_to_search" # options like --source --reverse --all etc

S와 "string_to_search"사이에 공백을 사용하지 않도록주의하십시오. 일부 설정 (git 1.7.1)에서는 다음과 같은 오류가 발생합니다.

fatal: ambiguous argument 'string_to_search': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions

2

이것이 귀하의 질문에 직접 대답하지는 않지만 앞으로 귀하에게 좋은 해결책이라고 생각합니다. 내 코드의 일부를 보았습니다. 누가 언제 글을 썼는지 몰랐습니다. 파일의 모든 변경 사항을 볼 수 있지만 코드가 다른 파일에서이 파일로 이동 한 것이 분명했습니다. 누가 처음에 실제로 추가했는지 알고 싶었습니다.

이를 위해 Git bisect를 사용 하여 죄인을 빨리 찾을 수있었습니다.

체크 아웃 된 개정판에 문제가 있었기 때문에 실행 git bisect start한 다음 git bisect bad. 문제가 언제 발생했는지 알지 못했기 때문에 "good"에 대한 첫 번째 커밋을 목표로 삼았습니다 git bisect good <initial sha>.

그런 다음 방금 불량 코드에 대한 저장소를 계속 검색했습니다. 내가 그것을 발견했을 때, 나는 실행 git bisect bad하고, 때 거기이었다 git bisect good.

~ 11 단계에서 ~ 1000 커밋을 다루고 문제가 소개 된 정확한 커밋을 발견했습니다. 꽤 좋아요


2

수락 된 답변이 왜 내 환경에서 작동하지 않는지 확실하지 않은 경우 마지막으로 필요한 것을 얻기 위해 아래 명령을 실행합니다.

git log --pretty=format:"%h - %an, %ar : %s"|grep "STRING"
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.