Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove sparse index expansions from untracked file stashes #433

Merged
merged 3 commits into from
Sep 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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];
vdye marked this conversation as resolved.
Show resolved Hide resolved
}
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 @@ -1185,6 +1185,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 @@ -1301,28 +1304,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 @@ -1945,6 +1945,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_modesparse_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