git write-tree and then git diff-index reports thousands of files as `deleted` when core.fsmonitor is true, even though the files are still present on the file system. What did you do before the bug happened? (Steps to reproduce your issue) ``` git config core.fsmonitor true touch new-file.txt git add new-file.txt git diff-index --ignore-submodules --exit-code --no-color --no-ext-diff $(git write-tree) -- ``` What did you expect to happen? (Expected behavior) I expected that no files would be reported as having changes. What happened instead? (Actual behavior) Thousands of unrelated files were reported as `deleted`. ``` git diff-index --ignore-submodules --exit-code --no-color --no-ext-diff $(git write-tree) -- :100644 000000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0000000000000000000000000000000000000000 D src/tests/__init__.py :100644 000000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0000000000000000000000000000000000000000 D src/tests/site/__init__.py :100644 000000 d8edaad92120781998e811277f966551b12fc823 0000000000000000000000000000000000000000 D src/tests/site/test_models.py ... thousands of other files ``` What's different between what you expected and what actually happened? Thousands of unrelated files were reported as having been deleted. Anything else you want to add: Myself and a few co-workers all ran into this issue in the last few days. It presented itself when pre-commit hooks were run (specifically with the pre-commit tool from github pre-commit). When committing changes, the pre-commit tool runs the equivalent of: `git diff-index --ignore-submodules --exit-code --no-color --no-ext-diff $(git write-tree) --` It then stashes and unstashes those changes, causing the files to be removed from the working tree. ``` $ git config core.fsmonitor true $ git checkout -b test-branch Switched to a new branch 'test-branch' $ echo "test 3" >> newfile.txt $ git add . $ git status On branch test-branch Changes to be committed: (use "git restore --staged <file>..." to unstage) new file: newfile.txt $ git commit -a -m "will it fail?" [WARNING] Unstaged files detected. [INFO] Stashing unstaged files to /Users/josh/.cache/pre-commit/patch1677888420-10129. trim trailing whitespace.................................................Passed check python ast.....................................(no files to check)Skipped check for case conflicts.................................................Passed [INFO] Restored changes from /Users/josh/.cache/pre-commit/patch1677888420-10129. [test-branch 7c899582c19] will it fail? 1 file changed, 1 insertion(+) create mode 100644 newfile.txt $ git status On branch test-branch Changes not staged for commit: (use "git add/rm <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) deleted: src/tests/__init__.py deleted: src/tests/site/__init__.py deleted: src/tests/site/test_models.py ... lots more files ... no changes added to commit (use "git add" and/or "git commit -a") $ git status | wc -l 15298 $ git restore . $ git status On branch test-branch nothing to commit, working tree clean ``` It can be reproduced, in our repo, without using pre-commit at all: ``` git diff-index --ignore-submodules --exit-code --no-color --no-ext-diff $(git write-tree) -- :100644 000000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0000000000000000000000000000000000000000 D src/tests/__init__.py :100644 000000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0000000000000000000000000000000000000000 D src/tests/site/__init__.py :100644 000000 d8edaad92120781998e811277f966551b12fc823 0000000000000000000000000000000000000000 D src/tests/site/test_models.py ... thousands of other files ``` Using `update-index` with the `--no-fsmonitor` flag prior to diff-index does the correct thing: ``` $ git update-index --really-refresh --no-fsmonitor warning: core.fsmonitor is set; remove it if you really want to disable fsmonitor $ git diff-index --ignore-submodules --exit-code --no-color --no-ext-diff $(git write-tree) -- > no output ``` The problem persists when running `update-index` without disabling fsmonitor. I have reported this issue to the pre-commit project, but it looks like an issue with fsmonitor + write-tree. See: pre-commit issues on github #2795 [System Info] git version: git version 2.39.2 (others reproduced with 2.39.1) cpu: arm64 no commit associated with this build sizeof-long: 8 sizeof-size_t: 8 shell-path: /bin/sh feature: fsmonitor--daemon uname: Darwin 22.3.0 Darwin Kernel Version 22.3.0: Mon Jan 30 20:38:37 PST 2023; root:xnu-8792.81.3~2/RELEASE_ARM64_T6000 arm64 compiler info: clang: 14.0.0 (clang-1400.0.29.202) libc info: no libc information available $SHELL (typically, interactive shell): /bin/zsh [Enabled Hooks] pre-commit