In virtual filesystem (VFS/GVFS) mode, reset --mixed failed to report
hydrated files as modified. A hydrated file is one that has been read
(e.g. via blame or cat-file) and materialized on disk by ProjFS, but
not modified — so it is not in GVFS's ModifiedPaths database and
retains the skip-worktree bit in the index.
The existing VFS-specific code in update_index_from_diff() used
file_exists() to decide whether to clear skip-worktree:
- Files NOT on disk (virtual/placeholder): file_exists() returns
false, skip-worktree is cleared, and the pre-reset content is
written to disk via checkout_entry(). These files correctly
appear as modified. This path remains unchanged.
- Files already on disk (hydrated): file_exists() returns true,
so the code left skip-worktree set. refresh_index() then skipped
the file entirely, hiding the working-tree vs index mismatch.
The file was invisible to both the reset output and subsequent
git status.
Fix this by always clearing skip-worktree (respect_skip_worktree = 0)
for all entries processed by update_index_from_diff() when VFS mode is
active. The file_exists() check now only controls whether pre-reset
content needs to be written to disk — it no longer affects the
skip-worktree decision.
After the reset, GVFS's GitIndexParser detects the cleared
skip-worktree bits via the post-index-change hook and adds the
affected paths to ModifiedPaths, so subsequent git commands also
see them correctly.
Signed-off-by: Tyrie Vella <tyrielv@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This is a companion of #935, porting the changes from vfs-2.54.0 to vfs-2.55.0.
Problem
In virtual filesystem (VFS/GVFS) mode, reset --mixed fails to report hydrated files as modified.
A hydrated file is one that has been read (e.g., via blame or cat-file) and materialized on disk by ProjFS, but not modified — so it is not in GVFS's ModifiedPaths database and retains the skip-worktree bit in the index.
Reproduction
Root cause
The VFS-specific code in update_index_from_diff() uses file_exists() to decide whether to clear skip-worktree:
The original code assumed that if a file exists on disk, it must already be tracked properly. But hydrated-but-not-modified files exist on disk with stale content and are NOT in ModifiedPaths.
Fix
Always clear skip-worktree (respect_skip_worktree = 0) for all entries processed by update_index_from_diff() when VFS mode is active. The file_exists() check now only controls whether pre-reset content needs to be written to disk — it no longer gates the skip-worktree decision.
After the reset, GVFS's GitIndexParser detects the cleared skip-worktree bits via the post-index-change hook and adds affected paths to ModifiedPaths, so subsequent git commands also see them correctly.
Before (buggy)
After (fixed)
Testing