Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions builtin/checkout.c
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,15 @@ static int checkout_paths(const struct checkout_opts *opts,
checkout_index = opts->checkout_index;

if (checkout_index) {
if (core_virtualfilesystem) {
/* Some scenarios that checkout the index may update skipworktree bits,
* such as `restore --staged` after `cherry-pick -n` or `reset --soft`,
* so this flag should be set to ensure the correct virtual filesystem
* event is sent.
*/
the_repository->index->updated_skipworktree = 1;
}

if (write_locked_index(the_repository->index, &lock_file, COMMIT_LOCK))
die(_("unable to write new index file"));
} else {
Expand Down
3 changes: 2 additions & 1 deletion read-cache-ll.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@ struct index_state {
drop_cache_tree : 1,
updated_workdir : 1,
updated_skipworktree : 1,
fsmonitor_has_run_once : 1;
fsmonitor_has_run_once : 1,
vfs_check_added_entries_for_clear_skip_worktree : 1;
enum sparse_index_mode sparse_index;
struct hashmap name_hash;
struct hashmap dir_hash;
Expand Down
11 changes: 10 additions & 1 deletion sequencer.c
Original file line number Diff line number Diff line change
Expand Up @@ -787,13 +787,22 @@ static int do_recursive_merge(struct repository *r,
* to be replace with the tree the index matched before we
* started doing any picks.
*/
if (opts->no_commit && core_virtualfilesystem) {
/* When using the virtual file system, staged new files
* should clear SKIP_WORKTREE during this step to ensure the new files
* are properly added to the working tree as well as index - otherwise
* sparse-checkout functionality will prevent them from being added.
*/
o.repo->index->vfs_check_added_entries_for_clear_skip_worktree = 1;
}
merge_switch_to_result(&o, head_tree, &result, 1, show_output);
o.repo->index->vfs_check_added_entries_for_clear_skip_worktree = 0;

clean = result.clean;
if (clean < 0) {
rollback_lock_file(&index_lock);
return clean;
}

if (write_locked_index(r->index, &index_lock,
COMMIT_LOCK | SKIP_IF_UNCHANGED))
/*
Expand Down
2 changes: 2 additions & 0 deletions unpack-trees.c
Original file line number Diff line number Diff line change
Expand Up @@ -2004,6 +2004,8 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
is_sparse_index_allowed(&o->internal.result, 0))
o->internal.result.sparse_index = 1;

o->internal.result.vfs_check_added_entries_for_clear_skip_worktree =
o->src_index->vfs_check_added_entries_for_clear_skip_worktree;
/*
* Sparse checkout loop #1: set NEW_SKIP_WORKTREE on existing entries
*/
Expand Down
26 changes: 26 additions & 0 deletions virtualfilesystem.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,32 @@ static void clear_ce_flags_virtualfilesystem_1(struct index_state *istate, int s
entry += len + 1;
}
}

/*
* If vfs_check_added_entries_for_clear_skip_worktree is set and we are checking
* for added entries, clear the mask from all added entries even if they
* are not in the virtual filesystem.
* This is used in scenarios like cherry-pick -n, where the added entries
* are not added to the virtual file system but still need to be checked out
* in the working tree.
*/
if ((select_mask & CE_ADDED)
&& (clear_mask & CE_SKIP_WORKTREE)
&& istate->vfs_check_added_entries_for_clear_skip_worktree) {
for (i = 0; i < istate->cache_nr; i++) {
struct cache_entry *ce = istate->cache[i];
if (!select_mask || (ce->ce_flags & select_mask)) {
if (ce->ce_flags & clear_mask) {
ce->ce_flags &= ~clear_mask;
/*
* We also signal to VFS that there are updates to skipworktree
* that it needs to react to.
*/
istate->updated_skipworktree = 1;
}
}
}
}
}

/*
Expand Down
Loading