From: Siddharth Shrimali <r.siddharth.shrimali@gmail.com>
To: git@vger.kernel.org
Cc: gitster@pobox.com, christian.couder@gmail.com,
siddharthasthana31@gmail.com, ttaylorr@openai.com, ps@pks.im,
johannes.schindelin@gmx.de, l.s.r@web.de,
r.siddharth.shrimali@gmail.com
Subject: [GSoC PATCH v5 1/6] builtin/repack: add --drop-filtered and --dry-run options
Date: Fri, 14 Aug 2026 01:38:25 +0530 [thread overview]
Message-ID: <20260813200830.84348-2-r.siddharth.shrimali@gmail.com> (raw)
In-Reply-To: <20260813200830.84348-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.
Keep --dry-run as a separate option rather than folding it into
--drop-filtered (e.g. --drop-filtered=dry-run), to stay consistent with
the --dry-run option other Git commands already provide and to leave
room for it to describe other repack behavior later. A
--drop-filtered=<mode> form can still be added later if more
drop-specific modes are needed.
--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. Detect an
explicit -b/--write-bitmap-index on the command line with a dedicated
option callback that sets a "write_bitmaps_given" flag, so it can be
distinguished from a repack.writeBitmaps configuration value even when
config already enables bitmaps. An explicit -b is reported as a conflict,
while a config-provided default 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 <christian.couder@gmail.com>
Mentored-by: Siddharth Asthana <siddharthasthana31@gmail.com>
Signed-off-by: Siddharth Shrimali <r.siddharth.shrimali@gmail.com>
---
builtin/repack.c | 74 +++++++++++++++++++++++++++++++--
t/meson.build | 1 +
t/t7706-repack-drop-filtered.sh | 55 ++++++++++++++++++++++++
3 files changed, 127 insertions(+), 3 deletions(-)
create mode 100755 t/t7706-repack-drop-filtered.sh
diff --git a/builtin/repack.c b/builtin/repack.c
index db504d673f..ed79c04e13 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,11 +29,15 @@ 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 int write_bitmaps_given;
static const char *const git_repack_usage[] = {
N_("git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n"
"[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n"
- "[--write-midx[=<mode>]] [--name-hash-version=<n>] [--path-walk]"),
+ "[--write-midx[=<mode>]] [--name-hash-version=<n>] [--path-walk]\n"
+ "[--filter=<filter-spec>] [--drop-filtered [--dry-run]]"),
NULL
};
@@ -111,6 +116,21 @@ static int repack_config(const char *var, const char *value,
return git_default_config(var, value, ctx, cb);
}
+static int option_parse_write_bitmaps(const struct option *opt, const char *arg,
+ int unset)
+{
+ int *value = opt->value;
+
+ BUG_ON_OPT_ARG(arg);
+ if (unset)
+ *value = 0;
+ else
+ *value = 1;
+
+ write_bitmaps_given = 1;
+ return 0;
+}
+
static int option_parse_write_midx(const struct option *opt, const char *arg,
int unset)
{
@@ -194,8 +214,9 @@ int cmd_repack(int argc,
OPT__QUIET(&po_args.quiet, N_("be quiet")),
OPT_BOOL('l', "local", &po_args.local,
N_("pass --local to git-pack-objects")),
- OPT_BOOL('b', "write-bitmap-index", &write_bitmaps,
- N_("write bitmap index")),
+ OPT_CALLBACK_F('b', "write-bitmap-index", &write_bitmaps, NULL,
+ N_("write bitmap index"),
+ PARSE_OPT_NOARG, option_parse_write_bitmaps),
OPT_BOOL('i', "delta-islands", &use_delta_islands,
N_("pass --delta-islands to git-pack-objects")),
OPT_STRING(0, "unpack-unreachable", &unpack_unreachable, N_("approxidate"),
@@ -231,6 +252,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 +277,49 @@ 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");
+
+ if (dry_run && !drop_filtered)
+ die(_("--dry-run only takes effect with --drop-filtered"));
+
+ if (drop_filtered) {
+ if (!dry_run)
+ die(_("--drop-filtered does not 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=<n> 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=<n> for now"));
+
+ /*
+ * An explicit -b on the command line is a conflict we have to
+ * report; a bitmap setting from config is silently overridden
+ * for the duration of the command.
+ */
+ if (write_bitmaps_given && write_bitmaps > 0)
+ die(_("options '%s' and '%s' cannot be used together"),
+ "--drop-filtered", "--write-bitmap-index");
+
+ /*
+ * 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"));
diff --git a/t/meson.build b/t/meson.build
index a25f37d2f5..92352e43c4 100644
--- a/t/meson.build
+++ b/t/meson.build
@@ -964,6 +964,7 @@ integration_tests = [
't7703-repack-geometric.sh',
't7704-repack-cruft.sh',
't7705-repack-incremental-midx.sh',
+ 't7706-repack-drop-filtered.sh',
't7800-difftool.sh',
't7810-grep.sh',
't7811-grep-open.sh',
diff --git a/t/t7706-repack-drop-filtered.sh b/t/t7706-repack-drop-filtered.sh
new file mode 100755
index 0000000000..07a976874a
--- /dev/null
+++ b/t/t7706-repack-drop-filtered.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+
+test_description='git repack --drop-filtered option validation'
+
+. ./test-lib.sh
+
+# Check option validation before any promisor walk
+test_expect_success 'setup plain repo for validation' '
+ git init plain &&
+ test_commit -C plain initial &&
+ git clone --bare plain plain.git &&
+ git -C plain.git repack -a -d
+'
+
+test_expect_success '--drop-filtered requires --filter' '
+ test_must_fail git -C plain.git repack --drop-filtered --dry-run -a 2>err &&
+ test_grep "drop-filtered requires --filter" err
+'
+
+test_expect_success '--drop-filtered cannot be used with --filter-to' '
+ test_must_fail git -C plain.git repack --drop-filtered \
+ --filter=blob:limit=1k --filter-to=./filter-out 2>err &&
+ test_grep "options .--drop-filtered. and .--filter-to. cannot be used together" err
+'
+
+test_expect_success '--dry-run only takes effect with --drop-filtered' '
+ test_must_fail git -C plain.git repack --dry-run 2>err &&
+ test_grep "dry-run only takes effect with --drop-filtered" err
+'
+
+test_expect_success '--drop-filtered requires -a' '
+ test_must_fail git -C plain.git repack --drop-filtered \
+ --filter=blob:limit=1k --dry-run 2>err &&
+ test_grep "drop-filtered requires -a" err
+'
+
+test_expect_success '--drop-filtered fails with --write-bitmap-index' '
+ test_must_fail git -C plain.git repack --drop-filtered \
+ --filter=blob:limit=1k --dry-run -a -b 2>err &&
+ test_grep "options .--drop-filtered. and .--write-bitmap-index. cannot be used together" err
+'
+
+test_expect_success '--drop-filtered rejects explicit -b even when repack.writeBitmaps=true' '
+ test_must_fail git -C plain.git -c repack.writeBitmaps=true \
+ repack --drop-filtered --filter=blob:limit=1k --dry-run -a -b 2>err &&
+ test_grep "options .--drop-filtered. and .--write-bitmap-index. cannot be used together" err
+'
+
+test_expect_success '--drop-filtered fails without a promisor remote' '
+ test_must_fail git -C plain.git repack --drop-filtered \
+ --filter=blob:limit=1k --dry-run -a 2>err &&
+ test_grep "drop-filtered requires a promisor remote" err
+'
+
+test_done
--
2.54.0
next prev parent reply other threads:[~2026-08-13 20:08 UTC|newest]
Thread overview: 74+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-16 13:28 [RFC PATCH 0/7] repack: add --drop-filtered to reclaim space in partial clones Siddharth Shrimali
2026-07-16 13:28 ` [RFC PATCH 1/7] builtin/repack.c: add --drop-filtered and --dry-run options Siddharth Shrimali
2026-07-16 21:08 ` Junio C Hamano
2026-07-17 18:00 ` Siddharth Shrimali
2026-07-23 19:31 ` Siddharth Asthana
2026-07-18 12:30 ` Christian Couder
2026-07-20 10:19 ` Siddharth Shrimali
2026-07-16 13:28 ` [RFC PATCH 2/7] list-objects-filter: add list_objects_filter__filter_oidset() Siddharth Shrimali
2026-07-16 13:28 ` [RFC PATCH 3/7] repack-promisor: allow excluding objects from the rebuilt promisor pack Siddharth Shrimali
2026-07-16 13:28 ` [RFC PATCH 4/7] builtin/repack: enumerate promisor blobs for --drop-filtered Siddharth Shrimali
2026-07-16 13:28 ` [RFC PATCH 5/7] t7706: test --drop-filtered enumeration and validation Siddharth Shrimali
2026-07-16 13:28 ` [RFC PATCH 6/7] builtin/repack: actually drop filtered promisor blobs Siddharth Shrimali
2026-07-23 19:42 ` Siddharth Asthana
2026-07-25 19:30 ` Siddharth Shrimali
2026-07-16 13:28 ` [RFC PATCH 7/7] repack-promisor: record dropped objects in a drop log Siddharth Shrimali
2026-07-23 19:41 ` Siddharth Asthana
2026-07-25 19:35 ` Siddharth Shrimali
2026-07-23 19:26 ` [RFC PATCH 0/7] repack: add --drop-filtered to reclaim space in partial clones Siddharth Asthana
2026-07-25 19:23 ` Siddharth Shrimali
2026-07-30 17:41 ` [GSoC PATCH v2 " Siddharth Shrimali
2026-07-30 17:41 ` [GSoC PATCH v2 1/7] builtin/repack.c: add --drop-filtered and --dry-run options Siddharth Shrimali
2026-08-04 21:13 ` Siddharth Asthana
2026-07-30 17:41 ` [GSoC PATCH v2 2/7] list-objects-filter: add list_objects_filter__filter_oidset() Siddharth Shrimali
2026-07-30 17:41 ` [GSoC PATCH v2 3/7] repack-promisor: allow excluding objects from the rebuilt promisor pack Siddharth Shrimali
2026-07-30 17:41 ` [GSoC PATCH v2 4/7] builtin/repack: enumerate promisor blobs for --drop-filtered Siddharth Shrimali
2026-07-30 17:41 ` [GSoC PATCH v2 5/7] builtin/repack: actually drop filtered promisor blobs Siddharth Shrimali
2026-07-30 17:41 ` [GSoC PATCH v2 6/7] builtin/repack: add safety guards for --drop-filtered Siddharth Shrimali
2026-08-04 21:13 ` Siddharth Asthana
2026-07-30 17:41 ` [GSoC PATCH v2 7/7] Documentation/git-repack: document --drop-filtered and --dry-run Siddharth Shrimali
2026-07-31 15:33 ` [GSoC PATCH v2 0/7] repack: add --drop-filtered to reclaim space in partial clones Junio C Hamano
2026-08-01 18:19 ` Siddharth Shrimali
2026-08-02 2:18 ` Junio C Hamano
2026-08-02 11:28 ` Siddharth Shrimali
2026-08-04 21:12 ` Siddharth Asthana
2026-08-06 11:21 ` [GSoC PATCH v3 " Siddharth Shrimali
2026-08-06 11:21 ` [GSoC PATCH v3 1/7] builtin/repack.c: add --drop-filtered and --dry-run options Siddharth Shrimali
2026-08-06 11:21 ` [GSoC PATCH v3 2/7] list-objects-filter: add list_objects_filter__filter_oidset() Siddharth Shrimali
2026-08-06 11:21 ` [GSoC PATCH v3 3/7] repack-promisor: allow excluding objects from the rebuilt promisor pack Siddharth Shrimali
2026-08-06 11:21 ` [GSoC PATCH v3 4/7] builtin/repack: enumerate promisor blobs for --drop-filtered Siddharth Shrimali
2026-08-06 11:22 ` [GSoC PATCH v3 5/7] builtin/repack: actually drop filtered promisor blobs Siddharth Shrimali
2026-08-06 11:22 ` [GSoC PATCH v3 6/7] builtin/repack: add guards for --drop-filtered Siddharth Shrimali
2026-08-06 11:22 ` [GSoC PATCH v3 7/7] Documentation/git-repack: document --drop-filtered and --dry-run Siddharth Shrimali
2026-08-06 21:34 ` [GSoC PATCH v3 0/7] repack: add --drop-filtered to reclaim space in partial clones Junio C Hamano
2026-08-06 22:19 ` Junio C Hamano
2026-08-07 9:06 ` Siddharth Shrimali
2026-08-07 20:52 ` Junio C Hamano
2026-08-08 20:07 ` Siddharth Shrimali
2026-08-10 17:40 ` [GSoC PATCH v4 " Siddharth Shrimali
2026-08-10 17:40 ` [GSoC PATCH v4 1/7] builtin/repack.c: add --drop-filtered and --dry-run options Siddharth Shrimali
2026-08-10 17:40 ` [GSoC PATCH v4 2/7] list-objects-filter: add list_objects_filter__filter_oidset() Siddharth Shrimali
2026-08-12 17:09 ` Christian Couder
2026-08-12 18:04 ` Junio C Hamano
2026-08-12 19:22 ` Siddharth Shrimali
2026-08-10 17:40 ` [GSoC PATCH v4 3/7] repack-promisor: allow excluding objects from the rebuilt promisor pack Siddharth Shrimali
2026-08-10 17:40 ` [GSoC PATCH v4 4/7] builtin/repack: enumerate promisor blobs for --drop-filtered Siddharth Shrimali
2026-08-12 17:21 ` Christian Couder
2026-08-10 17:40 ` [GSoC PATCH v4 5/7] builtin/repack: actually drop filtered promisor blobs Siddharth Shrimali
2026-08-10 17:40 ` [GSoC PATCH v4 6/7] builtin/repack: add guards for --drop-filtered Siddharth Shrimali
2026-08-12 17:41 ` Christian Couder
2026-08-12 19:45 ` Siddharth Shrimali
2026-08-10 17:40 ` [GSoC PATCH v4 7/7] Documentation/git-repack: document --drop-filtered and --dry-run Siddharth Shrimali
2026-08-12 17:51 ` Christian Couder
2026-08-11 17:50 ` [GSoC PATCH v4 0/7] repack: add --drop-filtered to reclaim space in partial clones Junio C Hamano
2026-08-12 7:35 ` Siddharth Shrimali
2026-08-13 20:08 ` [GSoC PATCH v5 0/6] " Siddharth Shrimali
2026-08-13 20:08 ` Siddharth Shrimali [this message]
2026-08-13 20:08 ` [GSoC PATCH v5 2/6] list-objects-filter: add list_objects_filter__filter_oidset() Siddharth Shrimali
2026-08-13 20:08 ` [GSoC PATCH v5 3/6] repack-promisor: allow excluding objects from the rebuilt promisor pack Siddharth Shrimali
2026-08-13 20:08 ` [GSoC PATCH v5 4/6] builtin/repack: enumerate promisor blobs for --drop-filtered Siddharth Shrimali
2026-08-13 20:08 ` [GSoC PATCH v5 5/6] builtin/repack: actually drop filtered promisor blobs Siddharth Shrimali
2026-08-13 20:08 ` [GSoC PATCH v5 6/6] builtin/repack: add guards for --drop-filtered Siddharth Shrimali
2026-08-14 17:12 ` [GSoC PATCH v5 0/6] repack: add --drop-filtered to reclaim space in partial clones Christian Couder
2026-08-14 17:17 ` Junio C Hamano
2026-08-14 19:32 ` Siddharth Shrimali
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260813200830.84348-2-r.siddharth.shrimali@gmail.com \
--to=r.siddharth.shrimali@gmail.com \
--cc=christian.couder@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=johannes.schindelin@gmx.de \
--cc=l.s.r@web.de \
--cc=ps@pks.im \
--cc=siddharthasthana31@gmail.com \
--cc=ttaylorr@openai.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.