]> git.ipfire.org Git - thirdparty/git.git/commitdiff
rm: add --sparse option
authorDerrick Stolee <dstolee@microsoft.com>
Fri, 24 Sep 2021 15:39:11 +0000 (15:39 +0000)
committerJunio C Hamano <gitster@pobox.com>
Tue, 28 Sep 2021 17:31:02 +0000 (10:31 -0700)
As we did previously in 'git add', add a '--sparse' option to 'git rm'
that allows modifying paths outside of the sparse-checkout definition.
The existing checks in 'git rm' are restricted to tracked files that
have the SKIP_WORKTREE bit in the current index. Future changes will
cause 'git rm' to reject removing paths outside of the sparse-checkout
definition, even if they are untracked or do not have the SKIP_WORKTREE
bit.

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-rm.txt
builtin/rm.c
t/t3602-rm-sparse-checkout.sh

index 26e9b2847047c62b066730c20873d805b6790f51..81bc23f3cdbb56fbb8e0bd79c2bae40d35772cac 100644 (file)
@@ -72,6 +72,12 @@ For more details, see the 'pathspec' entry in linkgit:gitglossary[7].
 --ignore-unmatch::
        Exit with a zero status even if no files matched.
 
+--sparse::
+       Allow updating index entries outside of the sparse-checkout cone.
+       Normally, `git rm` refuses to update index entries whose paths do
+       not fit within the sparse-checkout cone. See
+       linkgit:git-sparse-checkout[1] for more.
+
 -q::
 --quiet::
        `git rm` normally outputs one line (in the form of an `rm` command)
index 8a24c715e02bab24098af5f3e354c631ee9abf3c..4208f3f9a5fb2695171f70554186cc49651ec0f5 100644 (file)
@@ -237,6 +237,7 @@ static int check_local_mod(struct object_id *head, int index_only)
 
 static int show_only = 0, force = 0, index_only = 0, recursive = 0, quiet = 0;
 static int ignore_unmatch = 0, pathspec_file_nul;
+static int include_sparse;
 static char *pathspec_from_file;
 
 static struct option builtin_rm_options[] = {
@@ -247,6 +248,7 @@ static struct option builtin_rm_options[] = {
        OPT_BOOL('r', NULL,             &recursive,  N_("allow recursive removal")),
        OPT_BOOL( 0 , "ignore-unmatch", &ignore_unmatch,
                                N_("exit with a zero status even if nothing matched")),
+       OPT_BOOL(0, "sparse", &include_sparse, N_("allow updating entries outside of the sparse-checkout cone")),
        OPT_PATHSPEC_FROM_FILE(&pathspec_from_file),
        OPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),
        OPT_END(),
@@ -298,7 +300,8 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
        ensure_full_index(&the_index);
        for (i = 0; i < active_nr; i++) {
                const struct cache_entry *ce = active_cache[i];
-               if (ce_skip_worktree(ce))
+
+               if (!include_sparse && ce_skip_worktree(ce))
                        continue;
                if (!ce_path_match(&the_index, ce, &pathspec, seen))
                        continue;
@@ -322,7 +325,8 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
                                seen_any = 1;
                        else if (ignore_unmatch)
                                continue;
-                       else if (matches_skip_worktree(&pathspec, i, &skip_worktree_seen))
+                       else if (!include_sparse &&
+                                matches_skip_worktree(&pathspec, i, &skip_worktree_seen))
                                string_list_append(&only_match_skip_worktree, original);
                        else
                                die(_("pathspec '%s' did not match any files"), original);
index e9e9a15c74cd339d592f64e31c3bb1e1adfde845..493c8f636b80f2dfe4d916c8720accfb05e9dce7 100755 (executable)
@@ -43,6 +43,18 @@ test_expect_success 'recursive rm does not remove sparse entries' '
        test_cmp expected actual
 '
 
+test_expect_success 'recursive rm --sparse removes sparse entries' '
+       git reset --hard &&
+       git sparse-checkout set "sub/dir" &&
+       git rm --sparse -r sub &&
+       git status --porcelain -uno >actual &&
+       cat >expected <<-\EOF &&
+       D  sub/d
+       D  sub/dir/e
+       EOF
+       test_cmp expected actual
+'
+
 test_expect_success 'rm obeys advice.updateSparsePath' '
        git reset --hard &&
        git sparse-checkout set a &&