]> git.ipfire.org Git - thirdparty/git.git/commitdiff
diff-lib: fix check_removed() when fsmonitor is active
authorJunio C Hamano <gitster@pobox.com>
Thu, 14 Sep 2023 22:00:43 +0000 (15:00 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sat, 16 Sep 2023 00:13:14 +0000 (17:13 -0700)
`git diff-index` may return incorrect deleted entries when fsmonitor
is used in a repository with git submodules. This can be observed on
Mac machines, but it can affect all other supported platforms too.

If fsmonitor is used, `stat *st` is left uninitialied if cache_entry
has CE_FSMONITOR_VALID bit set.  But, there are three call sites
that rely on stat afterwards, which can result in incorrect results.

We can fill members of "struct stat" that matters well enough using
the information we have in "struct cache_entry" that fsmonitor told
us is up-to-date to solve this.

Helped-by: Josip Sokcevic <sokcevic@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
diff-lib.c

index e533b436afb8541288131dbf27edc9da1f2e60a9..a834e5bad65876990ac62dd8e0a6c40a144b87dd 100644 (file)
  */
 static int check_removed(const struct cache_entry *ce, struct stat *st)
 {
-       if (lstat(ce->name, st) < 0) {
+       int stat_err;
+
+       if (!(ce->ce_flags & CE_FSMONITOR_VALID))
+               stat_err = lstat(ce->name, st);
+       else
+               stat_err = fake_lstat(ce, st);
+       if (stat_err < 0) {
                if (!is_missing_file_error(errno))
                        return -1;
                return 1;