summaryrefslogtreecommitdiff
path: root/builtin/sparse-checkout.c
diff options
context:
space:
mode:
authorDerrick Stolee <stolee@gmail.com>2025-09-12 10:30:07 +0000
committerJunio C Hamano <gitster@pobox.com>2025-09-12 08:59:52 -0700
commita8077c19131a86fa123c5be2c8b735acdb5dacf4 (patch)
treee7404b92f0294a0965bf282216f02a04a5c6a247 /builtin/sparse-checkout.c
parent2520efd3bc8c81cb4bd8f832b241c3b2b8c0630f (diff)
sparse-checkout: match some 'clean' behavior
The 'git sparse-checkout clean' subcommand is somewhat similar to 'git clean' in that it will delete files that should not be in the worktree. The big difference is that it focuses on the directories that should not be in the worktree due to cone-mode sparse-checkout. It also does not discriminate in the kinds of files and focuses on deleting entire directories. However, there are some restrictions that would be good to bring over from 'git clean', specifically how it refuses to do anything without the '-f'/'--force' or '-n'/'--dry-run' arguments. The 'clean.requireForce' config can be set to 'false' to imply '--force'. Add this behavior to avoid accidental deletion of files that cannot be recovered from Git. Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin/sparse-checkout.c')
-rw-r--r--builtin/sparse-checkout.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c
index f7caa28f3f..d777b64960 100644
--- a/builtin/sparse-checkout.c
+++ b/builtin/sparse-checkout.c
@@ -931,6 +931,7 @@ static char const * const builtin_sparse_checkout_clean_usage[] = {
};
static const char *msg_remove = N_("Removing %s\n");
+static const char *msg_would_remove = N_("Would remove %s\n");
static int sparse_checkout_clean(int argc, const char **argv,
const char *prefix,
@@ -939,8 +940,12 @@ static int sparse_checkout_clean(int argc, const char **argv,
struct strbuf full_path = STRBUF_INIT;
const char *msg = msg_remove;
size_t worktree_len;
+ int force = 0, dry_run = 0;
+ int require_force = 1;
struct option builtin_sparse_checkout_clean_options[] = {
+ OPT__DRY_RUN(&dry_run, N_("dry run")),
+ OPT__FORCE(&force, N_("force"), PARSE_OPT_NOCOMPLETE),
OPT_END(),
};
@@ -954,6 +959,13 @@ static int sparse_checkout_clean(int argc, const char **argv,
builtin_sparse_checkout_clean_options,
builtin_sparse_checkout_clean_usage, 0);
+ repo_config_get_bool(repo, "clean.requireforce", &require_force);
+ if (require_force && !force && !dry_run)
+ die(_("for safety, refusing to clean without one of --force or --dry-run"));
+
+ if (dry_run)
+ msg = msg_would_remove;
+
if (repo_read_index(repo) < 0)
die(_("failed to read index"));
@@ -977,7 +989,8 @@ static int sparse_checkout_clean(int argc, const char **argv,
printf(msg, ce->name);
- if (remove_dir_recursively(&full_path, 0))
+ if (dry_run <= 0 &&
+ remove_dir_recursively(&full_path, 0))
warning_errno(_("failed to remove '%s'"), ce->name);
}