reset --mixed: clear skip-worktree for all changed entries in VFS mode#935
Draft
tyrielv wants to merge 1 commit into
Draft
reset --mixed: clear skip-worktree for all changed entries in VFS mode#935tyrielv wants to merge 1 commit into
tyrielv wants to merge 1 commit into
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
In virtual filesystem (VFS/GVFS) mode,
reset --mixedfails to report hydrated files as modified.A hydrated file is one that has been read (e.g., via
blameorcat-file) and materialized on disk by ProjFS, but not modified — so it is not in GVFS's ModifiedPaths database and retains theskip-worktreebit in the index.Reproduction
gvfs clonea repogit blame Readme.md— hydrates the file (ProjFS materializes content on disk)git reset --mixed HEAD~1(whereReadme.mddiffers between HEAD and HEAD~1)Readme.mdappears in reset output andgit statusshows it as modifiedReadme.mdis missing from output;git statusreports cleanRoot cause
The VFS-specific code in
update_index_from_diff()usesfile_exists()to decide whether to clearskip-worktree:file_exists()returns false →skip-worktreecleared, pre-reset content written to disk viacheckout_entry()→ correctly reported as modified ✓file_exists()returns true →skip-worktreeleft set →refresh_index()skips the entry → invisible to status ✗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 byupdate_index_from_diff()when VFS mode is active. Thefile_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
GitIndexParserdetects the cleared skip-worktree bits via thepost-index-changehook and adds affected paths to ModifiedPaths, so subsequent git commands also see them correctly.Before (buggy)
After (fixed)
Testing
t1093-virtualfilesystem.sh:Readme.md)t1093tests pass