Subject: [PATCH 00/12] FSMonitor edge cases on case-insensitive file systems

From: "Jeff Hostetler via GitGitGadget" <[email-masked]>
Date: Tue, 13 Feb 2024 20:52:09 +0000

Fix FSMonitor client code to detect case-incorrect FSEvents and map them to
the canonical case expected by the index.

FSEvents are delivered to the FSMonitor daemon using the observed case which
may or may not match the expected case stored in the index for tracked files
and/or directories. This caused index_name_pos() to report a negative index
position (defined as the suggested insertion point). Since the value was
negative, the FSMonitor refresh lookup would not invalidate the
CE_FSMONITOR_VALID bit on the "expected" (case-insensitive-equivalent)
cache-entries. Therefore, git status would not report them as modified.

This was a fairly obscure problem and only happened when the case of a
sub-directory or a file was artificially changed.

This first runs the original lookup using the observed case. If that fails,
it assumes that the observed pathname refers to a file and uses the
case-insensitive name-hash hashmap to find an equivalent path (cache-entry)
in the index. If that fails, it assumes the pathname refers to a directory
and uses the case-insensitive dir-name-hash to find the equivalent directory
and then repeats the index_name_pos() lookup to find a directory or
suggested insertion point with the expected case.

Two new test cases were added to t7527 to demonstrate this.

Since this was rather obscure, I also added some additional tracing under
the GIT_TRACE_FSMONITOR key.

I also did considerable refactoring of the original code before adding the
new lookups.

Finally, I made more explicit the relationship between the FSEvents and the
(new) sparse-index directory cache-entries, since sparse-index was added
slightly after the FSMonitor feature.

Jeff Hostetler (12):
  sparse-index: pass string length to index_file_exists()
  name-hash: add index_dir_exists2()
  t7527: add case-insensitve test for FSMonitor
  fsmonitor: refactor refresh callback on directory events
  fsmonitor: refactor refresh callback for non-directory events
  fsmonitor: clarify handling of directory events in callback
  fsmonitor: refactor untracked-cache invalidation
  fsmonitor: support case-insensitive directory events
  fsmonitor: refactor non-directory callback
  fsmonitor: support case-insensitive non-directory events
  fsmonitor: refactor bit invalidation in refresh callback
  t7527: update case-insenstive fsmonitor test

 fsmonitor.c                  | 338 +++++++++++++++++++++++++++++------
 name-hash.c                  |  16 ++
 name-hash.h                  |   2 +
 sparse-index.c               |   4 +-
 t/t7527-builtin-fsmonitor.sh | 220 +++++++++++++++++++++++
 5 files changed, 522 insertions(+), 58 deletions(-)

base-commit: 3526e67d917bcd03f317a058208fa02737654637
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1662%2Fjeffhostetler%2Ffsmonitor-ignore-case-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1662/jeffhostetler/fsmonitor-ignore-case-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/1662
-- 
gitgitgadget