I have a script, update.py, that downloads new versions of files tracked in my git repository:
$ 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")
Sometimes, the files that are downloaded are identical to the files already in HEAD, so after the download the working directory is clean:
$ python update.py
Doing work...
Done
$ git status
On branch my-branch
nothing to commit, working directory clean
However, I've found that git diff-files appears to get confused when the files are replaced, even though their contents are identical:
$ 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
$
In the snippet above:
- I run update.py, which replaces the
foo.txt,bar.txt, andbaz.txtfiles with identical copies downloaded from elsewhere. git diff-filesincorrectly reports that those three files have been edited in-place in the work tree, according to the raw output format described on the git diff man page.git statuscorrectly reports that nothing has changed.git diff-files, run aftergit status, now also reports that nothing has changed.
After running update.py, git diff-files will continue to incorrectly report changes until I run git status, after which point it behaves again.
What is going on here? Why is git diff-files reporting changes when there are none?
In case you're curious why this is causing me trouble, here's some more context:
I have another script, update_and_commit_if_needed.py that does the following:
- Run
update.py. - If
git diff-filesreturns zero, the working tree is clean, andupdate.pydidn't change anything. Exit. - Otherwise, the working tree is dirty. Commit the changes.
I was seeing a weird failure in update_and_commit_if_needed.py: I'd get to step three, but then git commit would complain that there was nothing to commit, working directory clean. In tracking down that bug, I discovered this odd behavior of git diff-files.
I am using git version 2.5.0 on OS X 10.11.4 (15E65).
EDIT 1: I've found an easy way to reproduce this behavior:
$ 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
$
EDIT 2: As suggested in a comment, I've tried inverting core.trustctime and core.ignoreStat from their defaults. This does not appear to change git's behavior in this case.
statresults for cache purposes, your OS may be relevant. See also thecore.trustctimeandcore.ignoreStatsettings ingit config.gitkwhich essentially suffers from this bug: sometimes it demonstrates that there're changes but can't demonstrate them, and afterF5(reload) the change flag disappears. I'm sure that the quick check involves some kind ofstatwithout actual content comparison, but these are only speculations, not real investigations.