考虑:
$ 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),而在另一个环境中失败。对正在发生的事情有什么想法吗?这没什么大不了的,我怀疑文件系统不区分大小写是罪魁祸首,但我希望有一个可靠的解释。
答案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 status
在 Docker 容器外部运行似乎创建了git diff-index
容器内部被视为过时的缓存条目,因此第二次调用git diff-index
返回 1 表示“我不知道”。
我的解决方案是忘记低级命令并坚持使用git diff --quiet
.