From 8e1957dae51172ed71f84624340d1140e091327e Mon Sep 17 00:00:00 2001 From: Tyrie Vella Date: Tue, 9 Sep 2025 07:53:06 -0700 Subject: [PATCH 1/2] Set updated_skipworktree on restore --staged --- builtin/checkout.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/builtin/checkout.c b/builtin/checkout.c index c4b4f36a03a022..8384988424c81d 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -641,6 +641,10 @@ static int checkout_paths(const struct checkout_opts *opts, checkout_index = opts->checkout_index; if (checkout_index) { + /* Some scenarios may update skipworktree bits, such as + * `restore --staged` after `cherry-pick -n` or `reset --soft` + */ + 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 { From c54cd1cbd5e5a400da03065cb255814845ec8b2d Mon Sep 17 00:00:00 2001 From: Tyrie Vella Date: Tue, 9 Sep 2025 10:48:32 -0700 Subject: [PATCH 2/2] Fix of skip-worktree for cherry-pick --no-commit --- builtin/checkout.c | 2 +- read-cache-ll.h | 4 +++- read-cache.c | 11 +++++++++++ sequencer.c | 16 +++++++++++++++- unpack-trees.c | 13 +++++++++++++ 5 files changed, 43 insertions(+), 3 deletions(-) diff --git a/builtin/checkout.c b/builtin/checkout.c index 8384988424c81d..48525b7897ca12 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -641,7 +641,7 @@ static int checkout_paths(const struct checkout_opts *opts, checkout_index = opts->checkout_index; if (checkout_index) { - /* Some scenarios may update skipworktree bits, such as + /* Some scenarios may update skipworktree bits, such as * `restore --staged` after `cherry-pick -n` or `reset --soft` */ the_repository->index->updated_skipworktree = 1; diff --git a/read-cache-ll.h b/read-cache-ll.h index 84092540a7830b..257c168425e45b 100644 --- a/read-cache-ll.h +++ b/read-cache-ll.h @@ -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, + added_entries_skip_worktree : 1; enum sparse_index_mode sparse_index; struct hashmap name_hash; struct hashmap dir_hash; @@ -284,6 +285,7 @@ int is_index_unborn(struct index_state *); /* For use with `write_locked_index()`. */ #define COMMIT_LOCK (1 << 0) #define SKIP_IF_UNCHANGED (1 << 1) +#define UPDATE_SKIP_WORKTREE (1 << 2) /* * Write the index while holding an already-taken lock. Close the lock, diff --git a/read-cache.c b/read-cache.c index b29d2eaa912135..7bbe1a8a7e9404 100644 --- a/read-cache.c +++ b/read-cache.c @@ -2959,6 +2959,17 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile, offset = hashfile_total(f); } + if ((flags & UPDATE_SKIP_WORKTREE) + && (ce->ce_flags & (CE_ADDED | CE_UPDATE)) + && (ce->ce_flags & CE_SKIP_WORKTREE)) { + /* + * If caller asked us to, clear skip-worktree bit + * when updating/adding entries. + */ + ce->ce_flags &= ~CE_SKIP_WORKTREE; + istate->updated_skipworktree = 1; + } + if (ce_write_entry(f, ce, previous_name, (struct ondisk_cache_entry *)&ondisk) < 0) err = -1; diff --git a/sequencer.c b/sequencer.c index d47937b3f7b364..d025533a3bdf01 100644 --- a/sequencer.c +++ b/sequencer.c @@ -753,6 +753,7 @@ static int do_recursive_merge(struct repository *r, int clean, show_output; int i; struct lock_file index_lock = LOCK_INIT; + int flags; if (repo_hold_locked_index(r, &index_lock, LOCK_REPORT_ON_ERROR) < 0) return -1; @@ -787,15 +788,28 @@ 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) { + o.repo->index->added_entries_skip_worktree = 0; + } merge_switch_to_result(&o, head_tree, &result, 1, show_output); + o.repo->index->added_entries_skip_worktree = 1; + clean = result.clean; if (clean < 0) { rollback_lock_file(&index_lock); return clean; } + flags = 0; + if (core_virtualfilesystem && opts->no_commit) { + /* When using the virtual file system, staged index changes + * should clear SKIP_WORKTREE + */ + flags |= UPDATE_SKIP_WORKTREE; + } + if (write_locked_index(r->index, &index_lock, - COMMIT_LOCK | SKIP_IF_UNCHANGED)) + COMMIT_LOCK | SKIP_IF_UNCHANGED | flags) < 0) /* * TRANSLATORS: %s will be "revert", "cherry-pick" or * "rebase". diff --git a/unpack-trees.c b/unpack-trees.c index bd63bbc7c6e4b8..49073c6803958c 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -1852,6 +1852,19 @@ static void mark_new_skip_worktree(struct pattern_list *pl, enable_fscache(istate->cache_nr); clear_ce_flags(istate, select_flag, skip_wt_flag, pl, show_progress); disable_fscache(); + + /* + * 3. If added_entries_skip_worktree is cleared and we are checking for + * added entries, clear skip_wt_flag from all added entries. + */ + if ((select_flag & CE_ADDED) && !istate->added_entries_skip_worktree) { + for (i = 0; i < istate->cache_nr; i++) { + struct cache_entry *ce = istate->cache[i]; + if ((ce->ce_flags & (CE_ADDED | skip_wt_flag)) + == (CE_ADDED | skip_wt_flag)) + ce->ce_flags &= ~skip_wt_flag; + } + } } static void populate_from_existing_patterns(struct unpack_trees_options *o,