Docker

為什麼執行git status會改變後續git diff-index的結果?

  • May 16, 2019

考慮:

$ 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 的 docker 鏡像,安裝了相同的目錄,並且在 docker 鏡像中,發生了相反的行為:

$ 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-index在 docker 鏡像上(返回 0),git diff-index在主機上(返回 1),git status在主機上,git diff-index在主機上(返回 0),git diff-index在 docker 鏡像上(返回 1)。

基本上,如果我git-status在一個環境中執行,git diff-index將在該環境中成功(返回 0)而在另一個環境中失敗。關於發生了什麼的任何想法?這沒什麼大不了的,我懷疑文件系統不區分大小寫是罪魁禍首,但我希望得到一個可靠的解釋。

我也遇到過類似的問題,git diff-files我認為原因是一樣的。這不需要涉及 Docker 或不區分大小寫的文件系統,儘管這些可能會加劇問題。

Git 維護有關文件內容的資訊記憶體。通常,這是透明的,高級命令如git statusgit diff根據需要更新記憶體。

較低級別的命令(如git diff-indexgit diff-files)旨在返回快速但近似的結果。他們不更新記憶體。如果他們確定他們正在比較的東西是相同的,他們會返回 0,但是當他們返回 1 時,這意味著“我不知道這些東西是相同的”。如果記憶體條目是陳舊的,那麼事情可能是相同的但git diff-xxx不知道。

我不知道記憶體是如何工作的。在您的第一個實驗中,似乎第一次呼叫git diff-index注意到記憶體條目已過時,因此返回 1 表示“我不知道”。然後git status更新了記憶體,第二次呼叫查看git diff-index了有效的記憶體條目,並能夠得出文件相同的結論。在您的第二個實驗中,git status在 Docker 容器外執行似乎創建了git diff-index在容器內被認為是陳舊的記憶體條目,因此第二次呼叫git diff-index返回 1 表示“我不知道”。

我的解決方案是忘記低級命令並堅持使用git diff --quiet.

引用自:https://unix.stackexchange.com/questions/519371