]> git.ipfire.org Git - thirdparty/git.git/commitdiff
reset: stop assuming that the caller passes in a clean index
authorPatrick Steinhardt <ps@pks.im>
Wed, 3 Jun 2026 16:14:06 +0000 (18:14 +0200)
committerJunio C Hamano <gitster@pobox.com>
Thu, 4 Jun 2026 00:04:26 +0000 (09:04 +0900)
In 652bd0211d (rebase: use 'skip_cache_tree_update' option, 2022-11-10),
we updated `reset_head()` to stop updating the index tree cache. This
was done as a performance optimization: the function is only called by
"sequencer.c" and "rebase.c", both of which assume a clean index before
they perform their operation, so we know that the end result will be a
clean index, too. Consequently, we can skip recomputing the cache as we
can instead use `prime_cache_tree()` directly.

In a subsequent commit we're about to add a new caller though where the
assumption doesn't hold anymore: the index may be dirty before calling
`reset_head()`, and consequently we cannot prime the cache with a given
tree anymore as the index and tree will mismatch.

Adapt the logic so that we only skip the cache tree update in case we're
doing a hard reset. While we could introduce logic that only skips the
update in case the incoming index was dirty already, that doesn't really
feel worth it: after all, the mentioned commit says itself that the
performance improvement was negligible anyway.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
reset.c

diff --git a/reset.c b/reset.c
index 7ff72de5d24475106139dd12040d36a172924dcc..05eb80216cecf141da9849cb8f852a214e1247e4 100644 (file)
--- a/reset.c
+++ b/reset.c
@@ -166,10 +166,11 @@ int reset_head(struct repository *r, const struct reset_head_opts *opts)
        unpack_tree_opts.dry_run = dry_run;
        unpack_tree_opts.merge = 1;
        unpack_tree_opts.preserve_ignored = 0; /* FIXME: !overwrite_ignore */
-       unpack_tree_opts.skip_cache_tree_update = 1;
        init_checkout_metadata(&unpack_tree_opts.meta, switch_to_branch, oid, NULL);
-       if (reset_hard)
+       if (reset_hard) {
+               unpack_tree_opts.skip_cache_tree_update = 1;
                unpack_tree_opts.reset = UNPACK_RESET_PROTECT_UNTRACKED;
+       }
 
        if (!reset_hard && !fill_tree_descriptor(r, &desc[nr++], &head_oid)) {
                ret = error(_("failed to find tree of %s"),
@@ -196,7 +197,8 @@ int reset_head(struct repository *r, const struct reset_head_opts *opts)
                goto leave_reset_head;
        }
 
-       prime_cache_tree(r, r->index, tree);
+       if (reset_hard)
+               prime_cache_tree(r, r->index, tree);
 
        if (write_locked_index(r->index, &lock, COMMIT_LOCK) < 0) {
                ret = error(_("could not write index"));