[GSoC PATCH v2 5/7] builtin/repack: actually drop filtered promisor blobs
Siddharth Shrimali <[email protected]> Thu, 30 Jul 2026 23:11:51 +0530
| Newsgroups | org.kernel.vger.git |
|---|---|
| Message-ID | <[email protected]> |
Make --drop-filtered remove the enumerated promisor blobs instead of only listing them. The drop set is computed before repack_promisor_objects() runs, and on a real run it is passed in so the rebuilt promisor pack omits those blobs. --drop-filtered implies -d so the old promisor packs, which still contain the dropped blobs, are removed. Without this the blobs would survive in the redundant packs. The existing repack machinery performs the write-before-delete and fsync, so the drop is crash-safe. The dropped blobs become absent locally but remain recoverable from the promisor remote, so a later access lazy-fetches them back transparently. --dry-run keeps its previous behavior, i.e. it lists the candidates and changes nothing. Mentored-by: Christian Couder <[email protected]> Mentored-by: Siddharth Asthana <[email protected]> Signed-off-by: Siddharth Shrimali <[email protected]> --- builtin/repack.c | 17 ++++++++++------- repack-filtered.c | 1 + t/t7706-repack-drop-filtered.sh | 12 ++++++++++++ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/builtin/repack.c b/builtin/repack.c index 8cb92d1a62..9a15ab1f2a 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -273,18 +273,12 @@ int cmd_repack(int argc, 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) { int bitmaps_from_cmdline = (write_bitmaps != write_bitmaps_before_parse); - if (!dry_run) - die(_("--drop-filtered doesn't work without --dry-run yet")); - if (!po_args.filter_options.choice) die(_("--drop-filtered requires --filter")); @@ -317,6 +311,14 @@ int cmd_repack(int argc, write_bitmaps = 0; + /* + * Dropping objects means rebuilding the promisor packs + * without them and then removing the old packs, so the + * redundant packs must be deleted. Imply -d on a real run. + */ + if (!dry_run) + delete_redundant = 1; + ret = enumerate_promisor_blobs(repo, &po_args.filter_options, &drop_oids); if (ret) @@ -442,7 +444,8 @@ int cmd_repack(int argc, strvec_push(&cmd.args, "--delta-islands"); if (pack_everything & ALL_INTO_ONE) { - repack_promisor_objects(repo, &po_args, &names, packtmp, NULL); + repack_promisor_objects(repo, &po_args, &names, packtmp, + (drop_filtered && !dry_run) ? &drop_oids : NULL); if (existing_packs_has_non_kept(&existing) && delete_redundant && diff --git a/repack-filtered.c b/repack-filtered.c index 217fc54d7b..08796818d8 100644 --- a/repack-filtered.c +++ b/repack-filtered.c @@ -119,6 +119,7 @@ int enumerate_promisor_blobs(struct repository *repo, /* * Apply the filter to find which blobs exceed the threshold. + * The caller has to_drop and is responsible for clearing it. */ ret = list_objects_filter__filter_oidset(repo, (struct list_objects_filter_options *)filter, diff --git a/t/t7706-repack-drop-filtered.sh b/t/t7706-repack-drop-filtered.sh index cbdb580702..b3e493e851 100755 --- a/t/t7706-repack-drop-filtered.sh +++ b/t/t7706-repack-drop-filtered.sh @@ -128,4 +128,16 @@ test_expect_success '--dry-run does not remove the filtered objects' ' git -C repo cat-file -e "$BIG" ' +test_expect_success '--drop-filtered removes the promisor blob locally' ' + BIG=$(cat big_oid) && + SMALL=$(cat small_oid) && + + git -C repo -c repack.writeBitmaps=false \ + repack --drop-filtered --filter=blob:limit=1k -a && + + git -C repo cat-file --batch-all-objects --batch-check="%(objectname)" >present && + ! grep -q "$BIG" present && + grep -q "$SMALL" present +' + test_done -- 2.54.0