diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c index 80620d50af..845c702222 100644 --- a/builtin/sparse-checkout.c +++ b/builtin/sparse-checkout.c @@ -958,6 +958,7 @@ static int sparse_checkout_clean(int argc, const char **argv, size_t worktree_len; int force = 0, dry_run = 0, verbose = 0; int require_force = 1; + struct unpack_trees_options o = { 0 }; struct option builtin_sparse_checkout_clean_options[] = { OPT__DRY_RUN(&dry_run, N_("dry run")), @@ -986,6 +987,13 @@ static int sparse_checkout_clean(int argc, const char **argv, if (repo_read_index(repo) < 0) die(_("failed to read index")); + o.verbose_update = verbose; + o.update = 0; /* skip modifying the worktree here. */ + o.head_idx = -1; + o.src_index = o.dst_index = repo->index; + if (update_sparsity(&o, NULL)) + warning(_("failed to reapply sparse-checkout patterns")); + if (convert_to_sparse(repo->index, SPARSE_INDEX_MEMORY_ONLY) || repo->index->sparse_index == INDEX_EXPANDED) die(_("failed to convert index to a sparse index; resolve merge conflicts and try again")); diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh index 116ad7c9a2..4b9078d90a 100755 --- a/t/t1091-sparse-checkout-builtin.sh +++ b/t/t1091-sparse-checkout-builtin.sh @@ -1104,6 +1104,7 @@ test_expect_success 'clean with staged sparse change' ' cat >expect <<-\EOF && Would remove deep/deeper2/ + Would remove folder1/ EOF git -C repo sparse-checkout clean --dry-run >out && @@ -1115,6 +1116,7 @@ test_expect_success 'clean with staged sparse change' ' # deletes deep/deeper2/ but leaves folder1/ and folder2/ cat >expect <<-\EOF && Removing deep/deeper2/ + Removing folder1/ EOF # The previous test case checked the -f option, so @@ -1124,7 +1126,7 @@ test_expect_success 'clean with staged sparse change' ' test_cmp expect out && test_path_is_missing repo/deep/deeper2 && - test_path_exists repo/folder1 && + test_path_is_missing repo/folder1 && test_path_exists repo/folder2 ' @@ -1147,7 +1149,11 @@ test_expect_success 'sparse-checkout operations with merge conflicts' ' git commit -a -m "left" && git checkout -b merge && - git sparse-checkout set deep/deeper1 && + + touch deep/deeper2/extra && + git sparse-checkout set deep/deeper1 2>err && + grep "contains untracked files" err && + test_path_exists deep/deeper2/extra && test_must_fail git merge -m "will-conflict" right && @@ -1159,15 +1165,19 @@ test_expect_success 'sparse-checkout operations with merge conflicts' ' git merge --continue && test_path_exists folder1/even/more/dirs/file && + test_path_exists deep/deeper2/extra && + + cat >expect <<-\EOF && + Removing deep/deeper2/ + Removing folder1/ + EOF # clean does not remove the file, because the # SKIP_WORKTREE bit was not cleared by the merge command. git sparse-checkout clean -f >out && - test_line_count = 0 out && - test_path_exists folder1/even/more/dirs/file && - - git sparse-checkout reapply && - test_path_is_missing folder1 + test_cmp expect out && + test_path_is_missing folder1 && + test_path_is_missing deep/deeper2 ) ' diff --git a/unpack-trees.c b/unpack-trees.c index f38c761ab9..3a5dc062d7 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -2138,7 +2138,7 @@ enum update_sparsity_result update_sparsity(struct unpack_trees_options *o, index_state_init(&o->internal.result, o->src_index->repo); /* Sanity checks */ - if (!o->update || o->index_only || o->skip_sparse_checkout) + if (o->index_only || o->skip_sparse_checkout) BUG("update_sparsity() is for reflecting sparsity patterns in working directory"); if (o->src_index != o->dst_index || o->fn) BUG("update_sparsity() called wrong");