과거에 파일이나 파일에서 일부 코드를 삭제했습니다. 커밋 메시지가 아닌 컨텐츠를 grep 할 수 있습니까?
매우 나쁜 해결책은 로그를 grep하는 것입니다.
git log -p | grep <pattern>
그러나 커밋 해시를 즉시 반환하지는 않습니다. 나는 git grep
아무 소용이 없습니다.
과거에 파일이나 파일에서 일부 코드를 삭제했습니다. 커밋 메시지가 아닌 컨텐츠를 grep 할 수 있습니까?
매우 나쁜 해결책은 로그를 grep하는 것입니다.
git log -p | grep <pattern>
그러나 커밋 해시를 즉시 반환하지는 않습니다. 나는 git grep
아무 소용이 없습니다.
답변:
커밋 내용 (즉, 커밋 메시지 등이 아닌 실제 소스 행) 을 검색하려면 다음을 수행해야합니다.
git grep <regexp> $(git rev-list --all)
git rev-list --all | xargs git grep <expression>
"인수 목록이 너무 깁니다"오류가 발생하면 작동합니다.
일부 하위 트리로 검색을 제한하려면 (예를 들어, "lib 디렉토리 / 폴더의 유틸리티"), 당신은 그에게 전달해야합니다 rev-list
하위 명령 및 grep
뿐만 아니라 :
git grep <regexp> $(git rev-list --all -- lib/util) -- lib/util
에 대한 커밋 텍스트가 모두 표시됩니다 regexp
.
두 명령 모두에 경로를 전달하는 이유는 rev-list
모든 변경 사항이 lib/util
발생한 수정본 목록을 반환 하지만 grep
검색 만하 도록 전달해야하기 때문입니다 lib/util
.
다음 시나리오를 상상해보십시오. 반환 된 동일한 개정판에 포함 된 다른 파일 grep
에서도 동일하게 찾을 수 있습니다 (해당 개정판에서 해당 파일에 대한 변경 사항이 없더라도).<regexp>
rev-list
소스를 검색하는 다른 유용한 방법은 다음과 같습니다.
정규식 regexp와 일치하는 텍스트에 대한 작업 트리 검색 :
git grep <regexp>
정규식 regexp1 또는 regexp2와 일치하는 텍스트 행에 대한 작업 트리를 검색하십시오.
git grep -e <regexp1> [--or] -e <regexp2>
정규식 regexp1 및 regexp2와 일치하는 텍스트 행에 대한 작업 트리를 검색하고 파일 경로 만보고하십시오.
git grep -l -e <regexp1> --and -e <regexp2>
정규식 regexp1과 일치하는 텍스트 행과 정규식 regexp2와 일치하는 텍스트 행이있는 파일에 대한 작업 트리를 검색하십시오.
git grep -l --all-match -e <regexp1> -e <regexp2>
변경된 텍스트 일치 패턴 행에 대한 작업 트리 검색 :
git diff --unified=0 | grep <pattern>
정규식 regexp와 일치하는 텍스트에 대한 모든 개정판을 검색하십시오.
git grep <regexp> $(git rev-list --all)
정규식 regexp와 일치하는 텍스트에 대해 rev1과 rev2 사이의 모든 개정판을 검색하십시오.
git grep <regexp> $(git rev-list <rev1>..<rev2>)
sh.exe": /bin/git: Bad file number
. VonC의 답변은 msysgit에서도 작동합니다.
git gc
또는 체크 아웃 : stackoverflow.com/questions/1507463/…
의 pickaxe ( -S
) 옵션을 사용해야합니다 git log
.
검색하려면 Foo
:
git log -SFoo -- path_containing_change
git log -SFoo --since=2009.1.1 --until=2010.1.1 -- path_containing_change
자세한 내용은 Git history (Git 기록)를 참조하십시오 .
Jakub Narębski 는 다음과 같이 언급했습니다.
이것은 의 인스턴스를 소개하거나 제거하는 차이점을 찾습니다<string>
. 일반적으로 " 'Foo'로 라인을 추가하거나 제거한 개정"을 의미합니다.
이 --pickaxe-regex
옵션을 사용하면 문자열을 검색하는 대신 확장 POSIX 정규식을 사용할 수 있습니다. 예 (에서 git log
) :git log -S"frotz\(nitfol" --pickaxe-regex
Rob이 언급 한 것처럼 이 검색은 대소 문자를 구분합니다. 대소 문자를 구분하지 않는 검색 방법에 대한 후속 질문 을 열었 습니다 .
git log
귀하의 질문에 조금 나를 혼동했다)
-p
플래그 와 결합 하여 diff도 출력하십시오.
--branches --all
모든 repo를 검색 하는 옵션 이 필요합니다 .
가장 좋아하는 방법은 git log
의 -G
옵션을 사용하는 것입니다 (버전 1.7.4에 추가됨).
-G<regex>
Look for differences whose added or removed line matches the given <regex>.
커밋과 일치하는지 -G
와 -S
옵션이 결정 하는 방식에는 미묘한 차이가 있습니다.
-S
옵션은 기본적으로 커밋 전후에 파일에서 검색이 일치하는 횟수를 계산합니다. 이전 및 이후 개수가 다른 경우 커밋이 로그에 표시됩니다. 예를 들어, 검색과 일치하는 행이 이동 된 커밋은 표시되지 않습니다.-G
옵션을 사용하면 검색이 추가, 제거 또는 변경된 행과 일치하면 커밋이 로그에 표시됩니다.이 커밋을 예로 들어 보겠습니다.
diff --git a/test b/test
index dddc242..60a8ba6 100644
--- a/test
+++ b/test
@@ -1 +1 @@
-hello hello
+hello goodbye hello
파일에 "hello"가 나타나는 횟수는이 커밋 전후에 동일하기 때문에를 사용하여 일치하지 않습니다 -Shello
. 그러나 일치하는 행이 변경 hello
되었으므로 커밋은을 사용하여 표시됩니다 -Ghello
.
-p
커밋마다 diff를 표시하는 옵션을 추가합니다 . 그런 다음 내 호출기에서 로그가 열리면 원하는 것을 검색합니다. 호출기 인 경우 less
당신은 git log -Ghello -p
, 당신은 입력 할 수 /hello
눌러 Enter
및 사용 n
과 N
"안녕하세요"의 이전 / 다음 항목을 찾을 수 있습니다.
-G
Regex 에서 흥미로운 문제를 발견했습니다 . 명령 줄에 UTF-8이 사용되고보고있는 파일이 ISO-Latin (8 비트) 인코딩을 사용 .*
하면 실패합니다. 예를 들어, 나는 변경 Vierter Entwurf
->을 가지고 있고 일치 Fünfter Entwurf
하는 것을 'V.*ter Entwurf'
생성하지만 'F.*ter Entwurf'
그렇지 않습니다.
git log
일치하는 항목이 많고 가장 최근 (관련) 변경 사항을 먼저보고자하는 경우 모든 브랜치에서보다 효과적인 텍스트 검색 방법이 될 수 있습니다.
git log -p --all -S 'search string'
git log -p --all -G 'match regular expression'
이 로그 명령은 주어진 검색 문자열 / 정규식 (일반적으로)을 먼저 추가하거나 제거하는 커밋을 나열합니다. 이 -p
옵션을 사용하면 패턴이 추가되거나 제거 된 위치에 관련 diff가 표시되므로 컨텍스트에서 볼 수 있습니다.
찾고있는 텍스트를 추가하는 관련 커밋 (예 : 8beeff00d)을 찾았 으면 커밋이 포함 된 분기를 찾습니다.
git branch -a --contains 8beeff00d
'
따옴표가 검색 문자열을 단일 인수로 그룹화하지 않습니다. 대신에 'public
의 주장 -S
이며 나머지는 별도의 주장으로 취급합니다. 어떤 환경에서 실행 중인지 잘 모르겠지만 문제 해결에 도움이되는 컨텍스트가 필요합니다. git 명령이 셸로 전송되는 방법에 대한 모든 컨텍스트와 함께 문제 해결에 도움이 필요한 경우 별도의 StackOverflow 질문을 여는 것이 좋습니다. 다른 명령을 통해 전송되는 것 같습니다. 여기의 의견은 이것을 알아낼 수있는 올바른 장소가 아닙니다.
Jeet의 답변을 가져 와서 Windows에 적용했습니다 ( 이 답변 덕분에 ).
FOR /F %x IN ('"git rev-list --all"') DO @git grep <regex> %x > out.txt
어떤 이유로 든이 정규 표현식을 삭제 한 실제 커밋은 명령의 출력에 나타나지 않고 명령보다 먼저 커밋되었습니다.
--no-pager
>>results.txt
윈도우 파이프에 정통하지 않은 파일을 사용하여 텍스트 파일에 추가 ...
모든 버전의 파일 에서 검색 :
git rev-list --all | xargs git grep <regexp>
주어진 파일 ( 예 : XML 파일) 에서만 검색 하십시오.
git rev-list --all | xargs -I{} git grep <regexp> {} -- "*.xml"
결과 줄은 다음과 같아야합니다. 6988bec26b1503d45eb0b2e8a4364afb87dde7af : bla.xml : 찾은 줄의 텍스트 ...
그런 다음 다음을 사용하여 저자, 날짜 및 diff와 같은 자세한 정보를 얻을 수 있습니다 git show
.
git show 6988bec26b1503d45eb0b2e8a4364afb87dde7af
간단하게하기 위해 GUI를 사용하는 것이 좋습니다 : gitk-The Git repository browser . 꽤 유연합니다
위 / 아래 화살표를 사용하여 결과를 탐색 할 수 있습니다.
소스 트리 에서이 작업을 수행하려는 다른 사람 은 UI에 직접 명령이 없습니다 (버전 1.6.21.0 기준). 그러나 터미널 창 (기본 도구 모음에서 사용 가능한 단추) 을 열고 복사 / 붙여 넣기 하여 허용 된 답변에 지정된 명령 을 사용할 수 있습니다.
참고 : 소스 트리의 검색 보기는 부분적으로 텍스트 검색을 수행 할 수 있습니다. Ctrl+ 3를 눌러 검색보기로 이동하거나 하단에서 사용 가능한 검색 탭을 클릭하십시오. 가장 오른쪽에서 검색 유형을 파일 변경으로 설정 한 다음 검색 할 문자열을 입력하십시오. 이 방법에는 위의 명령과 비교하여 다음과 같은 제한이 있습니다.
내가 당신을 찾을 때마다 다음 명령 줄을 사용합니다.
git log -S "<words/phrases i am trying to find>" --all --oneline --graph
설명:
git log
-내가 더 쓸 필요가 있습니다; 로그를 시간순으로 표시합니다.-S "<words/phrases i am trying to find>"
-파일 (추가 / 수정 / 삭제)에 '<>'기호없이 찾으려고하는 단어 / 문구가있는 Git 커밋을 모두 보여줍니다.--all
-모든 지점에서 시행하고 검색합니다.--oneline
-Git 로그를 한 줄로 압축합니다.--graph
-시간순으로 커밋 된 그래프를 생성합니다.따라서 이전 버전의 코드를 통해 마지막으로 존재하는 곳을 찾으려고 노력하고 있습니까?
내가 이것을하고 있다면 아마도 git bisect을 사용할 것입니다 . bisect를 사용하면 알려진 양호한 버전, 알려진 나쁜 버전 및 버전이 좋은지 확인하는 간단한 스크립트 (이 경우 찾고있는 코드가 있는지 확인하는 grep)를 지정할 수 있습니다. ). 이를 실행하면 코드가 제거 된시기를 찾을 수 있습니다.
git rev-list --all | xargs -n 5 git grep EXPRESSION
는 Jeet의 솔루션에 대한 조정 이므로 검색이 끝나고 끝이 아니라 결과가 표시됩니다 (큰 저장소에서 시간이 오래 걸릴 수 있음).
git log -S
, 비난에 대해) * [ "git log --grep"와 함께 재미] [2] (커밋 메시지 검색) ) * [ "git grep"으로 재미있게] [3] [2] : gitster.livejournal.com/30195.html [3] : gitster.livejournal.com/27674.html