diff options
author | Junio C Hamano <gitster@pobox.com> | 2022-03-29 12:22:02 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2022-03-29 12:22:03 -0700 |
commit | d62966735d0f2c9a632d34023336bc0387a4bd5a (patch) | |
tree | 4bfe7e02d0ec2173bdf915f161058576b1ccfcff | |
parent | Merge branch 'ab/refs-various-fixes' (diff) | |
parent | Revert "unpack-trees: improve performance of next_cache_entry" (diff) | |
download | tgif-d62966735d0f2c9a632d34023336bc0387a4bd5a.tar.xz |
Merge branch 'vd/cache-bottom-fix'
Correct a bug in unpack-trees introduced earlier.
* vd/cache-bottom-fix:
Revert "unpack-trees: improve performance of next_cache_entry"
unpack-trees: increment cache_bottom for sparse directories
t1092: add sparse directory before cone in test repo
-rwxr-xr-x | t/t1092-sparse-checkout-compatibility.sh | 7 | ||||
-rw-r--r-- | unpack-trees.c | 39 |
2 files changed, 20 insertions, 26 deletions
diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh index dcc0a30d4a..236ab53028 100755 --- a/t/t1092-sparse-checkout-compatibility.sh +++ b/t/t1092-sparse-checkout-compatibility.sh @@ -16,7 +16,9 @@ test_expect_success 'setup' ' echo "after deep" >e && echo "after folder1" >g && echo "after x" >z && - mkdir folder1 folder2 deep x && + mkdir folder1 folder2 deep before x && + echo "before deep" >before/a && + echo "before deep again" >before/b && mkdir deep/deeper1 deep/deeper2 deep/before deep/later && mkdir deep/deeper1/deepest && mkdir deep/deeper1/deepest2 && @@ -254,6 +256,7 @@ test_expect_success 'root directory cannot be sparse' ' # Verify sparse directories still present, root directory is not sparse cat >expect <<-EOF && + before/ folder1/ folder2/ x/ @@ -1444,6 +1447,7 @@ test_expect_success 'ls-files' ' cat >expect <<-\EOF && a + before/ deep/ e folder1- @@ -1491,6 +1495,7 @@ test_expect_success 'ls-files' ' cat >expect <<-\EOF && a + before/ deep/ e folder1- diff --git a/unpack-trees.c b/unpack-trees.c index 2763a029a1..7f528d35cc 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -595,13 +595,6 @@ static void mark_ce_used(struct cache_entry *ce, struct unpack_trees_options *o) { ce->ce_flags |= CE_UNPACKED; - /* - * If this is a sparse directory, don't advance cache_bottom. - * That will be advanced later using the cache-tree data. - */ - if (S_ISSPARSEDIR(ce->ce_mode)) - return; - if (o->cache_bottom < o->src_index->cache_nr && o->src_index->cache[o->cache_bottom] == ce) { int bottom = o->cache_bottom; @@ -651,24 +644,17 @@ static void mark_ce_used_same_name(struct cache_entry *ce, } } -static struct cache_entry *next_cache_entry(struct unpack_trees_options *o, int *hint) +static struct cache_entry *next_cache_entry(struct unpack_trees_options *o) { const struct index_state *index = o->src_index; int pos = o->cache_bottom; - if (*hint > pos) - pos = *hint; - while (pos < index->cache_nr) { struct cache_entry *ce = index->cache[pos]; - if (!(ce->ce_flags & CE_UNPACKED)) { - *hint = pos + 1; + if (!(ce->ce_flags & CE_UNPACKED)) return ce; - } pos++; } - - *hint = pos; return NULL; } @@ -1416,13 +1402,12 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str /* Are we supposed to look at the index too? */ if (o->merge) { - int hint = -1; while (1) { int cmp; struct cache_entry *ce; if (o->diff_index_cached) - ce = next_cache_entry(o, &hint); + ce = next_cache_entry(o); else ce = find_cache_entry(info, p); @@ -1478,7 +1463,14 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str * it does not do any look-ahead, so this is safe. */ if (matches) { - o->cache_bottom += matches; + /* + * Only increment the cache_bottom if the + * directory isn't a sparse directory index + * entry (if it is, it was already incremented) + * in 'mark_ce_used()' + */ + if (!src[0] || !S_ISSPARSEDIR(src[0]->ce_mode)) + o->cache_bottom += matches; return mask; } } @@ -1777,7 +1769,7 @@ static int verify_absent(const struct cache_entry *, int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options *o) { struct repository *repo = the_repository; - int i, hint, ret; + int i, ret; static struct cache_entry *dfc; struct pattern_list pl; int free_pattern_list = 0; @@ -1869,15 +1861,13 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options info.pathspec = o->pathspec; if (o->prefix) { - hint = -1; - /* * Unpack existing index entries that sort before the * prefix the tree is spliced into. Note that o->merge * is always true in this case. */ while (1) { - struct cache_entry *ce = next_cache_entry(o, &hint); + struct cache_entry *ce = next_cache_entry(o); if (!ce) break; if (ce_in_traverse_path(ce, &info)) @@ -1898,9 +1888,8 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options /* Any left-over entries in the index? */ if (o->merge) { - hint = -1; while (1) { - struct cache_entry *ce = next_cache_entry(o, &hint); + struct cache_entry *ce = next_cache_entry(o); if (!ce) break; if (unpack_index_entry(ce, o) < 0) |