The idea that filters only work during checkin / checkout is something like white lie . This means that the filters are more explicable.
In fact, however, filters are triggered when moving files between the index and the tree (as well as in fairly modern versions of Git, when requested with the --path= parameters in git show and git cat-file and git hash-object : some of them are jumps directly from the repository to stdout or stdin to the repository). This is basically equivalent to check / check time. But git status also has a special dispensation due to the aspect of the index cache.
For performance reasons, Git wants to know if any file in the tree tree can be dirty relative to the version in the index. Git suggests that for this purpose, you can use the stat st_mtime , which usually has a resolution of one second, 1 : if the st_mtime file โ tree entry โ is older than the st_mtime stored in the index record, then the index record is updated and is โcleanโ ": which in the index corresponds to what is in the tree tree, after applying clean filters, etc.
If the timestamp of the working tree record is newer than the saved index record, then the file has definitely been changed: the index record may be out of date. It did not guarantee obsolescence, since the work tree file could be changed in a way that ultimately did not change. But itโs clearly necessary to run a clean filter (and any hacking CR / LF line).
If the two timestamps are the same, the working tree record is undefined. (Git calls it "racily clean," although "racily dirty" will be equally accurate.)
In all of these cases, git status will trigger a clean filter (and any CR / LF modifications for Git I / O) across the file tree to calculate the new hash. If the new hash matches the hash index, Git can and will update the index entry to mark the file as "virtually clean." Now, the next time you do something, Git will not need to run a clean filter.
If you do not do all this in the resolution of the stat field st_mtime . In this case, the entry into the index ends with "racily clean" and Git should try again. This is what you are observing here.
(Note, by the way, that git status launches two diffs: one from HEAD to the index and one from the index to the work tree. This is the second diff, which is very beneficial from the aspect of the index cache. Now the index can also store information about files and directories, not in the cache!)
1 Some stat calls give secondary accuracy, but for various reasons, writing an index / cache in any case retains a 1 second resolution time stamp.
For more information, see the racy-git.txt in the technical documentation .