Skip to content

checkout: preserve skip-worktree for virtual filesystem paths (forward-port of #915)#921

Draft
dscho wants to merge 1 commit into
vfs-2.54.0from
forward-port-checkout-skip-worktree-vfs
Draft

checkout: preserve skip-worktree for virtual filesystem paths (forward-port of #915)#921
dscho wants to merge 1 commit into
vfs-2.54.0from
forward-port-checkout-skip-worktree-vfs

Conversation

@dscho
Copy link
Copy Markdown
Member

@dscho dscho commented May 17, 2026

Forward-port of #915 ("checkout: preserve skip-worktree for virtual filesystem paths", merged into vfs-2.53.0 as ea3eb21) to vfs-2.54.0.

Cherry-picked from the underlying PR-branch commit d40f13b (so the original
well-crafted commit message and Tyrie Vella's authorship are preserved). One auto-merge in builtin/checkout.c resolved cleanly without conflicts.

When 'git checkout <tree> -- <pathspec>' updates the index with entries
from the source tree, update_some() creates a new cache entry that
unconditionally clears skip-worktree.  In a virtual filesystem repo
(core.virtualfilesystem is set), this causes checkout_entry() to
attempt unlink() on files that exist only as virtual projections with
no physical NTFS entry.  The unlink fails with ENOENT, producing
'error: unable to unlink old' messages and exit code 255.

Fix this in three places:

1. update_some(): Propagate CE_SKIP_WORKTREE from the existing index
   entry to the replacement entry when core_virtualfilesystem is set.

2. mark_ce_for_checkout_overlay(): Allow skip-worktree entries that
   have CE_UPDATE (set by update_some for tree entries) to still
   match the pathspec, so report_path_error() does not reject them.

3. checkout_worktree(): Skip checkout_entry() for entries that have
   both CE_MATCHED and CE_SKIP_WORKTREE, since the virtual filesystem
   provider will serve the correct content from the updated projection.

The index is updated to the new tree entry's OID while the working
tree write is skipped entirely.  The virtual filesystem provider
re-reads the updated index and serves the correct content on next
access.  Same approach as the CE_NEW_SKIP_WORKTREE propagation in
deleted_entry() (unpack-trees.c, PR #865) which avoids unnecessary
lstats on virtualized paths during branch switches.

Assisted-by: Claude Opus 4.6
Signed-off-by: Tyrie Vella <tyrielv@gmail.com>
(cherry picked from commit d40f13b)
Assisted-by: Claude Opus 4.7
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
@dscho dscho self-assigned this May 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants