考虑:
$ 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 status
和git diff
根据需要更新缓存。较低级别的命令(如
git diff-index
和git 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
.