From: Siddharth Shrimali Date: Thu, 16 Jul 2026 13:28:42 GMT Subject: [RFC PATCH 1/7] builtin/repack.c: add --drop-filtered and --dry-run options Message-ID: <20260716132848.95982-2-r.siddharth.shrimali@gmail.com> In-Reply-To: <20260716132848.95982-1-r.siddharth.shrimali@gmail.com> Add two new command-line options to 'git-repack': --drop-filtered: intended to eventually delete objects that match the filter specification. Requires --filter and -a, and is incompatible with --filter-to. --dry-run: show which objects would be dropped without making any changes. Only meaningful with --drop-filtered. --drop-filtered also requires a promisor remote to be configured, since dropping objects without a remote to fetch them back from would be permanent data loss. --drop-filtered is incompatible with bitmap writing: filtering breaks the "all objects in one pack" closure that bitmaps require. An explicit -b is rejected with a clear error and a default-on bitmap configuration is silently disabled for the duration of the command. These options currently only perform validation. The actual enumeration and deletion will be added in follow-up commits. Mentored-by: Christian Couder Mentored-by: Siddharth Asthana Signed-off-by: Siddharth Shrimali --- builtin/repack.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/builtin/repack.c b/builtin/repack.c index db504d673f..f4db0fc535 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -14,6 +14,7 @@ #include "promisor-remote.h" #include "repack.h" #include "shallow.h" +#include "list-objects-filter-options.h" #define ALL_INTO_ONE 1 #define LOOSEN_UNREACHABLE 2 @@ -28,6 +29,8 @@ static int use_delta_islands; static int run_update_server_info = 1; static char *packdir, *packtmp_name, *packtmp; static int midx_must_contain_cruft = 1; +static int drop_filtered; +static int dry_run; static const char *const git_repack_usage[] = { N_("git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" @@ -231,6 +234,10 @@ int cmd_repack(int argc, N_("pack prefix to store a pack containing pruned objects")), OPT_STRING(0, "filter-to", &filter_to, N_("dir"), N_("pack prefix to store a pack containing filtered out objects")), + OPT_BOOL(0, "drop-filtered", &drop_filtered, + N_("delete filtered out objects (requires --filter)")), + OPT_BOOL(0, "dry-run", &dry_run, + N_("only show which objects would be dropped")), OPT_END() }; @@ -252,6 +259,43 @@ int cmd_repack(int argc, po_args.depth = xstrdup_or_null(opt_depth); po_args.threads = xstrdup_or_null(opt_threads); + die_for_incompatible_opt2(drop_filtered, "--drop-filtered", + !!filter_to, "--filter-to"); + + die_for_incompatible_opt2(drop_filtered, "--drop-filtered", + write_bitmaps > 0, "--write-bitmap-index"); + + if (dry_run && !drop_filtered) + die(_("--dry-run only takes effect with --drop-filtered")); + + if (drop_filtered) { + if (!dry_run) + die(_("--drop-filtered doesn't work without --dry-run yet")); + + if (!po_args.filter_options.choice) + die(_("--drop-filtered requires --filter")); + + if (!(pack_everything & ALL_INTO_ONE)) + die(_("--drop-filtered requires -a")); + + /* + * Only blob:limit= is supported for now. Reject other + * filter choices early, before walking the object database. + */ + if (po_args.filter_options.choice != LOFC_BLOB_LIMIT) + die(_("--drop-filtered only supports --filter=blob:limit= for now")); + + /* + * Without a promisor remote there is nowhere to re-fetch the + * dropped objects from, so dropping them would be permanent + * data loss. + */ + if (!repo_has_promisor_remote(repo)) + die(_("--drop-filtered requires a promisor remote")); + + write_bitmaps = 0; + } + if (delete_redundant && repo->repository_format_precious_objects) die(_("cannot delete packs in a precious-objects repo")); -- 2.54.0