git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] cache: add fake_lstat()

From
Junio C Hamano <gitster@pobox.com>
Date
Sep 14, 2023, 22:00 UTC
Message-ID
<xmqqr0n0h0tw.fsf@gitster.g>
In-Reply-To
<xmqqcyykig1l.fsf@gitster.g>

And your diff-lib change may look like this on top. This one unfortunately is completely untested, as I do not use macOS.

Reviewing, testing, and improving it is highly appreciated.
----- >8 ---------- >8 ---------- >8 -----
Subject: diff-lib: fix check_removed() when fsmonitor is active

`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                   | 9 ++++++++-
 t/t7527-builtin-fsmonitor.sh | 5 +++++
 2 files changed, 13 insertions(+), 1 deletion(-)
diff --git c/diff-lib.c w/diff-lib.c
index d8aa777a73..7799747a97 100644
--- c/diff-lib.c
+++ w/diff-lib.c
@@ -38,8 +38,15 @@
  */
 static int check_removed(const struct index_state *istate, const struct cache_entry *ce, struct stat *st)
 {
+	int stat_err;
+
 	assert(is_fsmonitor_refreshed(istate));
-	if (!(ce->ce_flags & CE_FSMONITOR_VALID) && lstat(ce->name, st) < 0) {
+
+	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;
diff --git c/t/t7527-builtin-fsmonitor.sh w/t/t7527-builtin-fsmonitor.sh
index 0c241d6c14..78503158fd 100755
--- c/t/t7527-builtin-fsmonitor.sh
+++ w/t/t7527-builtin-fsmonitor.sh
@@ -809,6 +809,11 @@ my_match_and_clean () {
 		status --porcelain=v2 >actual.without &&
 	test_cmp actual.with actual.without &&
 
+	git -C super --no-optional-locks diff-index --name-status HEAD >actual.with &&
+	git -C super --no-optional-locks -c core.fsmonitor=false \
+		diff-index --name-status HEAD >actual.without &&
+	test_cmp actual.with actual.without &&
+
 	git -C super/dir_1/dir_2/sub reset --hard &&
 	git -C super/dir_1/dir_2/sub clean -d -f
 }
Previous: Junio C HamanoNext: Josip Sokcevic
Message 2 of 3 in “cache: add fake_lstat()”
  1. cache: add fake_lstat()Junio C Hamano, Sep 14, 2023
  2. Junio C HamanoSep 14, 2023
  3. Josip SokcevicSep 15, 2023

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.