`git status`를 실행하면 후속 `git diff-index`의 결과가 변경되는 이유는 무엇입니까?

`git status`를 실행하면 후속 `git diff-index`의 결과가 변경되는 이유는 무엇입니까?

고려하다:

$ git --version
git version 2.20.1 (Apple Git-117)
$ git diff-index --quiet HEAD ; echo $?
1
$ git status > /dev/null
$ git diff-index --quiet HEAD ; echo $?
0

대소문자를 구분하지 않는 파일 시스템을 사용하는 Macos의 경우입니다. (관련이 있는지는 모르겠습니다.) 이 문제가 발생하는 호스트에는 동일한 디렉터리가 마운트된 debian을 실행하는 도커 이미지가 있고, 도커 이미지에서는 반대 동작이 발생합니다.

$ git diff-index --quiet HEAD ; echo $?
0
# At this point, `git status` was invoked outside the docker image
$ git --version
git version 2.20.1
$ git diff-index --quiet HEAD ; echo $?
1

명확하게 말하면 여기서 실행되는 명령의 순서는 git diff-indexdocker 이미지(0 반환), git diff-index호스트(1 반환), git status호스트, git diff-index호스트(0 반환), git diff-indexdocker 이미지(1 반환)입니다.

git-status기본적으로 한 환경에서 실행 하면 git diff-index해당 환경에서는 성공(0을 반환)하고 다른 환경에서는 실패합니다. 무슨 일이 일어나고 있는지에 대한 생각이 있나요? 큰 문제는 아닙니다. 파일 시스템의 대소문자 구분이 없는 것이 원인인 것으로 의심되지만 확실한 설명이 있기를 바랍니다.

답변1

저도 비슷한 문제를 겪었 git diff-files는데 원인은 같은 것 같아요. Docker 또는 대소문자를 구분하지 않는 파일 시스템을 포함할 필요는 없지만 이로 인해 문제가 악화될 수 있습니다.

Git은 파일 내용에 대한 정보 캐시를 유지 관리합니다. 일반적으로 이는 필요에 따라 캐시를 업데이트하는 git status및 와 같은 투명하고 높은 수준의 명령입니다 .git diff

git diff-index및 같은 하위 수준 명령은 git diff-files빠르지만 대략적인 결과를 반환하도록 설계되었습니다. 캐시를 업데이트하지 않습니다. 비교되는 항목이 동일하다고 확신하면 0을 반환하지만 1을 반환하면 "이것이 동일한지 모르겠습니다"라는 의미입니다. 캐시 항목이 오래된 경우 내용은 동일하지만 git diff-xxx알려지지 않았을 가능성이 있습니다.

캐싱이 어떻게 작동하는지 정확히 모르겠습니다. 첫 번째 실험에서는 첫 번째 호출에서 캐시 항목이 오래되었음을 알아차린 것 같으 git diff-index므로 "모름"을 의미하는 1을 반환합니다. 그런 다음 캐시가 git status업데이트되고 두 번째 호출에서 git diff-index유효한 캐시 항목을 살펴보고 파일이 동일하다는 결론을 내립니다. 두 번째 실험에서는 git statusDocker 컨테이너 외부에서 실행하면 git diff-index컨테이너 내부에 오래된 것으로 간주되는 캐시 항목이 생성되는 것으로 보이므로 두 번째 호출은 git diff-index"모름"을 의미하는 1을 반환합니다.

내 해결책은 낮은 수준의 명령을 잊어버리고 그 명령을 고수하는 것이었습니다 git diff --quiet.

관련 정보