Skip to content

Commit 9a65b6a

Browse files
committed
sparse-index: make non-mixed reset sparse-aware
This change allows non-mixed resets to no longer require that the full index is expanded. This is accomplished by updating the `prime_cache_tree_rec` function to have it reconstruct the cache tree "aware" of whether a directory is sparse in the index or not. This check must be done by verifying the contents of the cache itself (rather than checking whether a directory is inside of the sparse checkout cone) as entries may have been added to the sparse index outside of the checkout cone. Signed-off-by: Victoria Dye <[email protected]>
1 parent 33e9a20 commit 9a65b6a

File tree

2 files changed

+46
-6
lines changed

2 files changed

+46
-6
lines changed

cache-tree.c

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -777,13 +777,31 @@ int write_index_as_tree(struct object_id *oid, struct index_state *index_state,
777777

778778
static void prime_cache_tree_rec(struct repository *r,
779779
struct cache_tree *it,
780-
struct tree *tree)
780+
struct tree *tree,
781+
struct strbuf *tree_path)
781782
{
783+
struct strbuf subtree_path = STRBUF_INIT;
782784
struct tree_desc desc;
783785
struct name_entry entry;
784786
int cnt;
785787

786788
oidcpy(&it->oid, &tree->object.oid);
789+
790+
/*
791+
* If this entry is outside the sparse-checkout cone, then it might be
792+
* a sparse directory entry. Check the index to ensure it is by looking
793+
* for an entry with the exact same name as the tree. If no matching sparse
794+
* entry is found, a staged or conflicted entry is preventing this
795+
* directory from collapsing to a sparse directory entry, so the cache
796+
* tree expansion should continue.
797+
*/
798+
if (r->index->sparse_index &&
799+
!path_in_cone_modesparse_checkout(tree_path->buf, r->index) &&
800+
index_name_pos(r->index, tree_path->buf, tree_path->len) >= 0) {
801+
it->entry_count = 1;
802+
return;
803+
}
804+
787805
init_tree_desc(&desc, tree->buffer, tree->size);
788806
cnt = 0;
789807
while (tree_entry(&desc, &entry)) {
@@ -792,27 +810,38 @@ static void prime_cache_tree_rec(struct repository *r,
792810
else {
793811
struct cache_tree_sub *sub;
794812
struct tree *subtree = lookup_tree(r, &entry.oid);
813+
795814
if (!subtree->object.parsed)
796815
parse_tree(subtree);
797816
sub = cache_tree_sub(it, entry.path);
798817
sub->cache_tree = cache_tree();
799-
prime_cache_tree_rec(r, sub->cache_tree, subtree);
818+
strbuf_reset(&subtree_path);
819+
strbuf_grow(&subtree_path, tree_path->len + entry.pathlen + 1);
820+
strbuf_addbuf(&subtree_path, tree_path);
821+
strbuf_add(&subtree_path, entry.path, entry.pathlen);
822+
strbuf_addch(&subtree_path, '/');
823+
824+
prime_cache_tree_rec(r, sub->cache_tree, subtree, &subtree_path);
800825
cnt += sub->cache_tree->entry_count;
801826
}
802827
}
803828
it->entry_count = cnt;
829+
830+
strbuf_release(&subtree_path);
804831
}
805832

806833
void prime_cache_tree(struct repository *r,
807834
struct index_state *istate,
808835
struct tree *tree)
809836
{
837+
struct strbuf tree_path = STRBUF_INIT;
838+
810839
trace2_region_enter("cache-tree", "prime_cache_tree", r);
811840
cache_tree_free(&istate->cache_tree);
812841
istate->cache_tree = cache_tree();
813842

814-
ensure_full_index(istate);
815-
prime_cache_tree_rec(r, istate->cache_tree, tree);
843+
prime_cache_tree_rec(r, istate->cache_tree, tree, &tree_path);
844+
strbuf_release(&tree_path);
816845
istate->cache_changed |= CACHE_TREE_CHANGED;
817846
trace2_region_leave("cache-tree", "prime_cache_tree", r);
818847
}

t/t1092-sparse-checkout-compatibility.sh

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -787,9 +787,9 @@ test_expect_success 'sparse-index is not expanded' '
787787
ensure_not_expanded checkout - &&
788788
ensure_not_expanded switch rename-out-to-out &&
789789
ensure_not_expanded switch - &&
790-
git -C sparse-index reset --hard &&
790+
ensure_not_expanded reset --hard &&
791791
ensure_not_expanded checkout rename-out-to-out -- deep/deeper1 &&
792-
git -C sparse-index reset --hard &&
792+
ensure_not_expanded reset --hard &&
793793
ensure_not_expanded restore -s rename-out-to-out -- deep/deeper1 &&
794794
795795
echo >>sparse-index/README.md &&
@@ -799,6 +799,17 @@ test_expect_success 'sparse-index is not expanded' '
799799
echo >>sparse-index/untracked.txt &&
800800
ensure_not_expanded add . &&
801801
802+
for ref in update-deep update-folder1 update-folder2 update-deep
803+
do
804+
echo >>sparse-index/README.md &&
805+
ensure_not_expanded reset --hard $ref
806+
done &&
807+
808+
ensure_not_expanded reset --hard update-deep &&
809+
ensure_not_expanded reset --keep base &&
810+
ensure_not_expanded reset --merge update-deep &&
811+
ensure_not_expanded reset --hard &&
812+
802813
ensure_not_expanded checkout -f update-deep &&
803814
(
804815
sane_unset GIT_TEST_MERGE_ALGORITHM &&

0 commit comments

Comments
 (0)