sparse-checkout: add sanity-checks on initial sparsity state

Most sparse-checkout subcommands (list, add, reapply) only make sense when already in a sparse state. Add a quick check that will error out early if this is not the case. Also document with a comment why we do not exit early in `disable` even when core.sparseCheckout starts as false. Reviewed-by: Derrick Stolee <dstolee@microsoft.com> Reviewed-by: Victoria Dye <vdye@github.com> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Elijah Newren committed Dec 14, 2021 at 04:09 UTC 45c5e47048a89e08a9e844bcf976401af8b60478
2 files changed +29 -1
builtin/sparse-checkout.c
+20
@@ -56,6 +56,9 @@ static int sparse_checkout_list(int argc, const char **argv)
56 char *sparse_filename;
57 int res;
58
59 + if (!core_apply_sparse_checkout)
60 + die(_("this worktree is not sparse"));
61 +
62 argc = parse_options(argc, argv, NULL,
63 builtin_sparse_checkout_list_options,
64 builtin_sparse_checkout_list_usage, 0);
@@ -671,6 +674,9 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix)
674 OPT_END(),
675 };
676
677 + if (!core_apply_sparse_checkout)
678 + die(_("no sparse-checkout to add to"));
679 +
680 repo_read_index(the_repository);
681
682 argc = parse_options(argc, argv, prefix,
@@ -719,6 +725,9 @@ static int sparse_checkout_reapply(int argc, const char **argv)
725 OPT_END(),
726 };
727
728 + if (!core_apply_sparse_checkout)
729 + die(_("must be in a sparse-checkout to reapply sparsity patterns"));
730 +
731 argc = parse_options(argc, argv, NULL,
732 builtin_sparse_checkout_reapply_options,
733 builtin_sparse_checkout_reapply_usage, 0);
@@ -740,6 +749,17 @@ static int sparse_checkout_disable(int argc, const char **argv)
749 struct pattern_list pl;
750 struct strbuf match_all = STRBUF_INIT;
751
752 + /*
753 + * We do not exit early if !core_apply_sparse_checkout; due to the
754 + * ability for users to manually muck things up between
755 + * direct editing of .git/info/sparse-checkout
756 + * running read-tree -m u HEAD or update-index --skip-worktree
757 + * direct toggling of config options
758 + * users might end up with an index with SKIP_WORKTREE bit set on
759 + * some files and not know how to undo it. So, here we just
760 + * forcibly return to a dense checkout regardless of initial state.
761 + */
762 +
763 argc = parse_options(argc, argv, NULL,
764 builtin_sparse_checkout_disable_options,
765 builtin_sparse_checkout_disable_usage, 0);
t/t1091-sparse-checkout-builtin.sh
+9 -1
@@ -41,7 +41,15 @@ test_expect_success 'setup' '
41 )
42 '
43
44 -test_expect_success 'git sparse-checkout list (empty)' '
44 +test_expect_success 'git sparse-checkout list (not sparse)' '
45 + test_must_fail git -C repo sparse-checkout list >list 2>err &&
46 + test_must_be_empty list &&
47 + test_i18ngrep "this worktree is not sparse" err
48 +'
49 +
50 +test_expect_success 'git sparse-checkout list (not sparse)' '
51 + git -C repo sparse-checkout set &&
52 + rm repo/.git/info/sparse-checkout &&
53 git -C repo sparse-checkout list >list 2>err &&
54 test_must_be_empty list &&
55 test_i18ngrep "this worktree is not sparse (sparse-checkout file may not exist)" err