Skip to content

Commit

Permalink
Merge pull request microsoft#433 from vdye/remove-index-expansions
Browse files Browse the repository at this point in the history
Remove sparse index expansions from untracked file stashes
  • Loading branch information
vdye authored and ldennington committed Jan 12, 2022
2 parents 0297428 + c8821ab commit 4246d0a
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 25 deletions.
13 changes: 10 additions & 3 deletions builtin/checkout-index.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,18 @@ static int checkout_all(const char *prefix, int prefix_length, int include_spars
int i, errs = 0;
struct cache_entry *last_ce = NULL;

if (include_sparse)
ensure_full_index(&the_index);

for (i = 0; i < active_nr ; i++) {
struct cache_entry *ce = active_cache[i];
if (include_sparse && S_ISSPARSEDIR(ce->ce_mode)) {
/*
* If the current entry is a sparse directory (and entries outside the
* sparse checkout definition are included), expand the index and
* continue the loop on the current index position (now pointing to the
* first entry inside the expanded sparse directory).
*/
ensure_full_index(&the_index);
ce = active_cache[i];
}
if (!include_sparse && !path_in_sparse_checkout(ce->name, &the_index))
continue;
if (ce_stage(ce) != checkout_stage
Expand Down
25 changes: 3 additions & 22 deletions t/t1092-sparse-checkout-compatibility.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1354,6 +1354,9 @@ test_expect_success 'sparse-index is not expanded' '
ensure_not_expanded stash apply stash@{0} &&
ensure_not_expanded stash drop stash@{0} &&
ensure_not_expanded stash -u &&
ensure_not_expanded stash pop &&
ensure_not_expanded stash create &&
oid=$(git -C sparse-index stash create) &&
ensure_not_expanded stash store -m "test" $oid &&
Expand Down Expand Up @@ -1622,28 +1625,6 @@ test_expect_success 'sparse index is not expanded: read-tree' '
ensure_not_expanded read-tree --prefix=deep/deeper2 -u deepest
'

# NEEDSWORK: although the full repository's index is _not_ expanded as part of
# stash, a temporary index, which is _not_ sparse, is created when stashing and
# applying a stash of untracked files. As a result, the test reports that it
# finds an instance of `ensure_full_index`, but it does not carry with it the
# performance implications of expanding the full repository index.
test_expect_success 'sparse index is not expanded: stash -u' '
init_repos &&
mkdir -p sparse-index/folder1 &&
echo >>sparse-index/README.md &&
echo >>sparse-index/a &&
echo >>sparse-index/folder1/new &&
GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
git -C sparse-index stash -u &&
test_region index ensure_full_index trace2.txt &&
GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
git -C sparse-index stash pop &&
test_region index ensure_full_index trace2.txt
'

# NEEDSWORK: similar to `git add`, untracked files outside of the sparse
# checkout definition are successfully stashed and unstashed.
test_expect_success 'stash -u outside sparse checkout definition' '
Expand Down
24 changes: 24 additions & 0 deletions unpack-trees.c
Original file line number Diff line number Diff line change
Expand Up @@ -1969,6 +1969,30 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
}
}

/*
* After unpacking trees, the index will be marked "sparse" if any sparse
* directories have been encountered. However, the index may still be
* sparse if there are no sparse directories. To make sure the index is
* marked "sparse" as often as possible, the index is marked sparse if
* all of the following are true:
* - the command in progress allows use of a sparse index
* - the index is not already sparse
* - cone-mode sparse checkout with sparse index is enabled for the repo
* - all index entries are inside of the sparse checkout cone
*/
if (!repo->settings.command_requires_full_index && !o->result.sparse_index &&
core_apply_sparse_checkout && core_sparse_checkout_cone && repo->settings.sparse_index) {
o->result.sparse_index = COLLAPSED;
for (i = 0; i < o->result.cache_nr; i++) {
struct cache_entry *ce = o->result.cache[i];

if (!path_in_cone_mode_sparse_checkout(ce->name, &o->result)) {
o->result.sparse_index = COMPLETELY_FULL;
break;
}
}
}

ret = check_updates(o, &o->result) ? (-2) : 0;
if (o->dst_index) {
move_index_extensions(&o->result, o->src_index);
Expand Down

0 comments on commit 4246d0a

Please sign in to comment.