특정 단어에 대해 Git 커밋 차이 또는 내용을 grep하는 방법은 무엇입니까?


622

Git 코드 저장소에서 특정 단어가 포함 된 모든 커밋을 나열하려고합니다. 나는 이것을 시도했다

git log -p | grep --context=4 "word"

그러나 필자가 검색 한 단어에서 5 줄 이상 떨어지지 않는 한 반드시 파일 이름을 돌려 줄 필요는 없습니다.

git grep "word"

그러나 그것은 나에게 파일이 아니라 역사 만 제시합니다.

특정 단어의 변화를 추적 할 수 있도록 전체 기록을 어떻게 검색합니까? 변경 사항을 추적하기 위해 코드베이스에서 단어 발생을 검색하려고합니다 (파일 기록에서 검색).


답변:


904

커밋 메시지 에 주어진 단어 포함 된 모든 커밋을 찾으려면

$ git log --grep=word

파일 내용 에서 "word"가 추가 또는 제거 된 모든 커밋을 찾으려면 (보다 정확하게 : "word"의 발생 횟수가 변경된 위치) 커밋 내용 검색과 함께 소위 'pickaxe'검색을 사용하십시오.

$ git log -Sword

현대 자식에는 또한

$ git log -Gword

추가 또는 제거 된 행이 "word"와 일치하는 차이점 ( commit contents ) 을 찾습니다 .

참고 -G기본적으로하면서, 정규식을 받아 -S문자열을 허용하지만,를 사용하여 정규 표현식에 동의 수정할 수 있습니다 --pickaxe-regex.

의 차이를 설명하기 위해 -S<regex> --pickaxe-regex하고 -G<regex>, A는 같은 파일에 다음 DIFF와 커밋 고려 :

+    return !regexec(regexp, two->ptr, 1, &regmatch, 0);
...
-    hit = !regexec(regexp, mf2.ptr, 1, &regmatch, 0);

git log -G"regexec\(regexp"이 커밋을 표시 하지만 git log -S"regexec\(regexp" --pickaxe-regex해당 문자열의 발생 횟수가 변경되지 않았기 때문에 그렇지 않습니다.


Git 2.25.1 (2020 년 2 월)을 사용하면 해당 정규 표현식에 대한 설명서가 명확 해집니다.

Martin Ågren의 커밋 9299f84 (2020 년 2 월 6 일)를 참조하십시오 . ( Junio ​​C Hamano의해 합병 -- 커밋 0d11410 , 2020 년 2 월 12 일)
gitster

diff-options.txt: 예에서 "정규식"과부하를 피하십시오

보고 : Adam Dinwoodie
서명 : Martin Ågren
검토 자 : Taylor Blau

-G-S(사용 --pickaxe-regex) 의 차이점을 예시 할 때 git diff"regexec", "regexp", "regmatch"등의 diff 및 호출 예제를 사용하여 수행합니다 .

예제는 정확하지만 실제로 "regex. *"를 쓰지 않으면 서 쉽게 풀 수 있습니다.

대신 정규식이 아닌 단어를 사용하십시오.

git diff문서는 이제 포함 :

의 차이를 설명하기 위해 -S<regex> --pickaxe-regex하고 -G<regex>, A는 같은 파일에 다음 DIFF와 커밋 고려 :

+    return frotz(nitfol, two->ptr, 1, 0);
...
-    hit = frotz(nitfol, mf2.ptr, 1, 0);

git log -G"frotz\(nitfol"이 커밋을 표시 하지만 git log -S"frotz\(nitfol" --pickaxe-regex해당 문자열의 발생 횟수가 변경되지 않았기 때문에 그렇지 않습니다.


3
@TankorSmash -S<string><string> 인스턴스를 도입하거나 제거하는 차이점을 찾으십시오. -G<string>주어진 <regex>와 일치하거나 추가 된 행이있는 차이점을 찾으십시오.
m-ric

1
@ m-ric 오, 하나의 문자열 인스턴스와 전체 행을 비교합니다! 감사합니다
TankorSmash

3
@ m-ric, @TankorSmash : 차이점은 변경 -S<string>발생 횟수 만 확인하기 때문에 모든 커밋 차이마다 검색이 추가되고 제거되는 것입니다. <string>-G<string>
Jakub Narębski

3
사이에 공백이있는 단어를 검색해야하는 경우 git log --grep="my words".
MEM

4
@MEM, --grep다른 -S-G. 이러한 각 인수에 문자열을 인용 할 수 있습니다.
Acumenus

255

git log의 곡괭이는 "word"를 포함한 변경 사항이있는 커밋을 찾습니다. git log -Sword


60
이것은 완전히 정확한 것은 아닙니다. -S <string> <string> 인스턴스를 도입하거나 제거하는 차이점을 찾으십시오. 이것은 단순히 diff 출력에 나타나는 문자열과 다릅니다.
tymtam

4
이것이 일반적으로 정답이지만 다른 사람들에게 3 가지 방법이 있으며 그 미묘함을 설명하는 이 답변 ( stackoverflow.com/a/1340245/586983 ) 을 읽도록 권장합니다 .
jakeonrails

18
어이! 나는 그것이 정답을 공감해야 할 좋은 이유라고 생각하지 않습니다 ... 당신은 의견에 링크를 포함시키는 것이 충분한 격려가 될 것이라고 확신하지 못했습니까?
Deborah

@jakeonrails, 그 답변은이 (이전) 답변을 수정 했으므로 성가신 복제본이 없습니다. 그러나 사람들은 깨끗한 답변 페이지 대신 평판 만 원합니다.
Iulian Onofrei

22

많은 실험을 한 후 주어진 정규 표현식을 포함하는 줄을 소개하거나 제거하는 커밋을 표시하고 각 단어의 텍스트 변경 내용을 단어가 추가 및 제거되는 색상으로 표시하는 커밋을 보여주는 다음을 추천 할 수 있습니다.

git log --pickaxe-regex -p --color-words -S "<regexp to search for>"

그래도 실행하는 데 시간이 걸립니다 ... ;-)


2
이것은 지금까지 최고의 감사 중 하나입니다. 힌트 : 페이징없이 모든 결과를 나열하려면 명령 앞에 GIT_PAGER=cat추가하거나 추가하십시오.| cat
Zack Morris

경로를 지정하거나 파일이 훨씬 빠른 것git log --pickaxe-regex -p --color-words -S "<regexp to search for>" <file or fiepath>
fangxing

10

다음 명령을 시도 할 수 있습니다.

git log --patch --color=always | less +/searching_string

또는 grep다음과 같은 방식으로 사용하십시오.

git rev-list --all | GIT_PAGER=cat xargs git grep 'search_string'

검색하려는 상위 디렉토리에서이 명령을 실행하십시오.


2
내가보고있는 커밋은 관련이없는 수백 줄의 변경 사항이 있기 때문에이 방법을 좋아합니다. 검색하려는 단어가 포함 된 실제 패치에만 관심이 있습니다. 색상을 사용하려면 git log --patch --color=always | less +/searching_string.
Radon Rosborough

9

그것을하는 또 다른 방법 / 구문은 다음 git log -S "word"
과 같습니다 .git log -S "with whitespaces and stuff @/#ü !"


1

vim-fugitiveVim 에서 그러한 종류의 검사를 위해 다목적입니다.

:Ggrep그렇게하는 데 사용하십시오 . 자세한 내용은 vim-fugitive를 설치하고을 통해 turorial을 찾아보십시오 :help Grep. 그리고이 에피소드 : 깃 리포지토리탐색 하면 모든 작업을 수행 할 수 있습니다.


1

정규식에서 부울 커넥터를 사용하려면 다음을 수행하십시오.

git log --grep '[0-9]*\|[a-z]*'

이 정규식은 커밋 메시지에서 정규식 [0-9] * 또는 [az] *를 검색합니다.


-1

git history에서 민감한 데이터를 검색하려면 (내가 여기에 도착한 이유), 그 도구가 있습니다. 해당 문제에 대한 전용 도움말 페이지 인 Github .

다음은 기사의 요지입니다.

BFG 리포-클리너는 원치 않는 데이터를 제거하는 자식 필터 지점에 빠르고 간단한 대안입니다. 예를 들어 민감한 데이터가 포함 된 파일을 제거하고 최신 커밋을 그대로 유지하려면 다음을 실행하십시오.

bfg --delete-files YOUR-FILE-WITH-SENSITIVE-DATA

passwords.txt에 나열된 모든 텍스트를 저장소 히스토리에서 찾을 수있는 위치로 바꾸려면 다음을 실행하십시오.

bfg --replace-text passwords.txt

전체 사용법 및 다운로드 지침 은 BFG Repo-Cleaner 설명서 를 참조하십시오 .


여기 대신 stackoverflow.com/questions/872565/… 에이 답변을 추가하고 싶을 수도 있습니다.
lacostenycoder
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.