我有一个脚本,update.py
它下载我的git存储库中跟踪的新版本文件:
$ python update.py
Doing work...
Done
$ git status
On branch my-branch
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: foo.txt
modified: bar.txt
modified: baz.txt
no changes added to commit (use "git add" and/or "git commit -a")
Run Code Online (Sandbox Code Playgroud)
有时,下载的文件与已有的文件相同HEAD
,因此下载后工作目录是干净的:
$ python update.py
Doing work...
Done
$ git status
On branch my-branch
nothing to commit, working directory clean
Run Code Online (Sandbox Code Playgroud)
但是,我发现git diff-files
在替换文件时似乎感到困惑,即使它们的内容相同:
$ python update.py
Doing work...
Done
$ git diff-files
:100644 100644 ffa91f655007c56f209cf15fee13c55991a76e18 0000000000000000000000000000000000000000 M foo.txt
:100644 100644 dc05558729c3c94a088aa63da3bbd8f1213b8cf3 0000000000000000000000000000000000000000 M bar.txt
:100644 100644 002cc3f53dc64b89b1b91adbb6fe61035ba9e832 0000000000000000000000000000000000000000 M baz.txt
$ git status
On branch my-branch
nothing to commit, working directory clean
$ git diff-files
$
Run Code Online (Sandbox Code Playgroud)
在上面的代码段中:
foo.txt
,bar.txt
和baz.txt
与从其他地方下载相同的复制文件.git diff-files
根据git diff手册页中描述的原始输出格式,错误地报告这三个文件已在工作树中就地编辑.git status
正确地报告没有任何改变.git diff-files
,运行之后git status
,现在还报告没有任何变化.运行后update.py
,git diff-files
将继续错误地报告更改,直到我运行git status
,之后它再次表现.
这里发生了什么?git diff-files
当没有报告时,为什么报告会发生变化?
万一你好奇为什么这会给我带来麻烦,这里有更多的背景:
我有另一个脚本,update_and_commit_if_needed.py
执行以下操作:
update.py
.git diff-files
返回零,则工作树是干净的,并且update.py
没有任何改变.出口.我看到一个奇怪的失败update_and_commit_if_needed.py
:我会进入第三步,但随后git commit
会抱怨有nothing to commit, working directory clean
.在追踪那个bug时,我发现了这种奇怪的行为git diff-files
.
我在OS X 10.11.4(15E65)上使用git版本2.5.0.
编辑1:我发现了一种简单的方法来重现这种行为:
$ git diff-files
$ git status
On branch my-branch
nothing to commit, working directory clean
$ cp foo.txt ~
$ mv ~/foo.txt .
$ git diff-files
:100755 100755 20084b5d6da359748f62c259c24f2b9cc2359780 0000000000000000000000000000000000000000 M foo.txt
$ git status
On branch my-branch
nothing to commit, working directory clean
$ git diff-files
$
Run Code Online (Sandbox Code Playgroud)
编辑2:正如评论所说,我已经试过反转core.trustctime
并core.ignoreStat
从它们的默认值.在这种情况下,这似乎不会改变git的行为.
rav*_*ron 12
git diff-index
实际上并没有检查工作树中文件的内容.相反,它使用文件的统计信息并将其与索引进行比较.实际上,该diff-index
手册页注释:
与此类型的其他命令一样,
git diff-index
实际上根本不查看文件的内容.所以也许kernel/sched.c
实际上并没有改变,只是你碰到了它.在任何一种情况下,都需要注意git update-index
它才能使索引同步.
如注释所示,索引的stat条目可以通过git update-index --refresh
之前运行来更新diff-files
.详细说明的手册页update-index
:
--refresh
不会计算新的sha1文件或使模式/内容更改的索引保持最新.但它所做的是将文件的统计信息与索引"重新匹配",以便您可以刷新尚未更改但文件条目过期的文件的索引.例如,您需要在执行此操作后执行此操作
git read-tree
,以将stat索引详细信息与正确的文件链接起来.
跑步update-index --refresh
之前diff-files
擦除我描述的症状,解决问题.