빌드노트
문자열이 있는 줄을 바꿨는데 git log -S에는 안 나온다
문자열이 있는 줄을 수정해도 파일 전후의 출현 횟수가 같으면 git log -S에는 나오지 않는다. 같은 횟수의 값 변경·문맥 줄·커밋 메시지를 실제 패치와 비교해 -S, -G, --grep을 선택한다.
RETRY_LIMIT=2를 RETRY_LIMIT=5로 바꾼 커밋이 git log -S'RETRY_LIMIT'에 나오지 않을 수 있다. -S는 파일의 변경 전후에서 찾는 문자열의 출현 횟수가 달라졌는지 검사한다. 값만 바꾸면 RETRY_LIMIT는 양쪽에 한 번씩 남는다. 이 줄을 수정한 커밋을 찾으려면 추가·삭제된 줄에 정규식이 맞는지 보는 -G를 사용한다.
Git이 설치되어 있고, 찾는 수정이 이미 커밋되어 있다는 조건이다. 저장소 최상위 폴더에서 아래 두 명령으로 같은 문자열을 검색해 본다. settings.conf는 자기 파일 경로로, RETRY_LIMIT는 찾는 문자열로 바꾼다. --format='%s'는 결과를 커밋 제목만으로 보여 주며, -- 뒤는 파일 경로다.
git log --format='%s' -S'RETRY_LIMIT' -- settings.conf
git log --format='%s' -G'RETRY_LIMIT' -- settings.conf
-G에만 나오는 커밋이 있다면 바로 횟수 문제로 단정하지 말고 그 패치를 읽는다. -S의 기본 입력은 일반 문자열이고 -G의 입력은 정규식이다. 여기의 RETRY_LIMIT는 두 검색에서 같은 글자를 찾지만, 점이나 괄호가 들어간 검색어라면 -G에서 정규식 특수 문자를 이스케이프해야 의도한 글자를 찾는다. git-log의 -S·-G 설명 (새 탭에서 열림)
한 번 있던 문자열이 여전히 한 번 있었다
실제 업무 이력 대신 새 합성 저장소의 텍스트 파일 하나로 차이를 확인했다. 처음에는 MODE=standard와 WORKERS=1만 두었다. 이후 다음 네 변경을 각각 커밋했다. 아래 영문은 실제 커밋 제목이다.
add limit:RETRY_LIMIT=2줄 추가. 문자열 횟수는 0 → 1.raise limit: 그 줄을RETRY_LIMIT=5로 수정. 횟수는 1 → 1.RETRY_LIMIT: adjust workers: 해당 줄은 그대로 두고WORKERS=1을WORKERS=2로 수정. 횟수는 1 → 1.remove limit:RETRY_LIMIT=5줄 삭제. 횟수는 1 → 0.
앞의 두 검색 결과는 다음과 같았다. 각 결과는 최신 커밋부터 나온 순서이며, 검색 명령을 구분하기 위한 이름만 붙였다.
-S 결과
remove limit
add limit
-G 결과
remove limit
raise limit
add limit
값을 바꾼 커밋이 왜 두 번째 결과에만 있는지 확인하려면 -p로 패치도 출력한다.
git log -p --format='%s' -G'RETRY_LIMIT' -- settings.conf
출력 중 raise limit의 변경 본문은 다음과 같았다. 파일명과 index 헤더는 생략했다. 줄 앞의 -는 삭제, +는 추가, 공백은 바뀌지 않은 문맥 줄이다.
@@ -1,3 +1,3 @@
MODE=standard
-RETRY_LIMIT=2
+RETRY_LIMIT=5
WORKERS=1
패치에는 찾는 문자열이 두 줄에 보이지만, 변경 전 파일에는 한 번, 변경 후 파일에도 한 번이다. -S는 패치 화면에서 문자열이 몇 번 보이는지를 세지 않는다. 이 커밋은 -S'RETRY_LIMIT'의 조건을 충족하지 않고, 삭제·추가 줄이 모두 RETRY_LIMIT에 맞으므로 -G에는 잡힌다. 파일 전후를 비교한다는 기준은 공식 diffcore-pickaxe 설명 (새 탭에서 열림)에도 명시되어 있다.
검색 문자열을 더 좁히면 같은 커밋에 대한 -S 결과도 달라진다. 같은 저장소에서 -S'RETRY_LIMIT=2'로 찾았을 때는 raise limit와 add limit가 나왔다. raise limit에서는 이 구체적인 문자열이 1회에서 0회로 줄었기 때문이다. 값 변경을 무조건 제외하는 옵션이 아니라, 어떤 문자열의 횟수를 비교하느냐가 기준이다.
--grep에 나오는 커밋은 다른 이유로 선택됐다
커밋 메시지에서 단어를 찾고 싶을 때는 --grep을 쓴다. 파일 내용 검색의 대체 명령으로 사용하면 찾는 커밋이 달라진다. 같은 파일 이력에 다음 명령을 실행했다.
git log --format='%s' --grep='RETRY_LIMIT' -- settings.conf
결과는 다음 한 줄이었다.
RETRY_LIMIT: adjust workers
이 커밋의 메시지에는 RETRY_LIMIT가 있지만, 실제로 수정한 것은 다른 설정이다. 해당 패치의 변경 본문은 다음과 같았다.
@@ -1,3 +1,3 @@
MODE=standard
RETRY_LIMIT=5
-WORKERS=1
+WORKERS=2
RETRY_LIMIT=5는 앞에 공백이 있는 문맥 줄이다. 추가·삭제된 줄에는 검색어가 없어서 이 커밋은 -G'RETRY_LIMIT'에도 나오지 않았다. 반대로 문자열을 실제로 추가·삭제한 커밋들은 메시지에 그 단어를 넣지 않아 --grep 결과에서 빠졌다. git-log의 --grep 설명 (새 탭에서 열림)은 검색 대상을 커밋 메시지로 정의한다. 패치 주변에 단어가 보이는 것, 바뀐 줄에 단어가 있는 것, 메시지에 단어가 있는 것은 서로 다른 조건이다.
--pickaxe-regex를 붙여도 횟수 비교는 남는다
-S에 --pickaxe-regex를 붙이면 입력을 확장 POSIX 정규식으로 해석한다. 횟수 변화 대신 변경 줄을 찾도록 바뀌는 옵션은 아니다. 숫자가 붙은 설정을 정규식으로 찾아도 같은 차이가 남는지 두 명령으로 확인했다.
git log --format='%s' -S'RETRY_LIMIT=[0-9]+' --pickaxe-regex -- settings.conf
git log --format='%s' -G'RETRY_LIMIT=[0-9]+' -- settings.conf
첫 명령에는 remove limit, add limit만 나왔다. 두 번째에는 그 사이에 raise limit도 나왔다. RETRY_LIMIT=2와 RETRY_LIMIT=5는 각각 이 정규식에 한 번씩 맞으므로 -S 쪽의 횟수가 그대로다. 정규식 입력과 횟수 비교의 관계는 공식 --pickaxe-regex 설명 (새 탭에서 열림)과 일치했다.
따라서 문자열이 생기거나 사라지는 지점을 추적할 때는 -S, 그 문자열에 맞는 줄을 고친 커밋을 찾을 때는 -G, 변경 의도를 적은 메시지를 찾을 때는 --grep을 고른다. -G에서도 결과가 비어 있다면 검색어의 정규식 해석과 파일 경로, 조회하는 브랜치·커밋 범위를 먼저 확인한다. 위 명령들은 별도 범위를 지정하지 않아 현재 HEAD에서 이어지는 이력을 조회한다. 결과가 없다는 사실만으로 다른 브랜치에도 수정이 없었다고 판단할 수는 없다.
실행 환경은 Windows 11, Git 2.45.1.windows.1, PowerShell 7.6.6이었다. Git 2.45 계열 공식 문서와 현재 문서를 확인하고, 전역·시스템 설정의 영향을 배제한 새 저장소에서 위 명령을 실행했다. 검증 범위는 병합과 이름 변경이 없는 텍스트 파일의 추가·수정·삭제다. 병합 커밋의 diff 방식, 바이너리 파일과 textconv 필터, 다른 Git 버전의 실행 결과는 확인하지 않았다.