[GSoC PATCH v5 5/6] builtin/repack: actually drop filtered promisor blobs
Siddharth Shrimali <[email protected]>
| 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]> --- Documentation/git-repack.adoc | 28 ++++++++++++++++++++++++++++ builtin/repack.c | 14 ++++++++++---- t/t7706-repack-drop-filtered.sh | 12 ++++++++++++ 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/Documentation/git-repack.adoc b/Documentation/git-repack.adoc index 72c42015e2..130249a139 100644 --- a/Documentation/git-repack.adoc +++ b/Documentation/git-repack.adoc @@ -12,6 +12,7 @@ SYNOPSIS 'git repack' [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m] [--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>] [--write-midx[=<mode>]] [--name-hash-version=<n>] [--path-walk] + [--filter=<filter-spec>] [--drop-filtered [--dry-run]] DESCRIPTION ----------- @@ -182,6 +183,33 @@ depth is 4095. `objects` and `objects/info/alternates` sections of linkgit:gitrepository-layout[5]. +--drop-filtered:: + Delete the local objects that match the `--filter` specification + instead of keeping them in a separate packfile, reclaiming the + disk space they occupy. This is intended for partial clones, + where the filtered objects are promisor objects that remain + recoverable from the promisor remote and are lazily re-fetched + on demand when they are next needed. ++ +Only large blobs are supported for now, so `--filter=blob:limit=<n>` +is currently the only accepted filter. Because dropped objects must be +recoverable, this option requires a promisor remote to be configured +and refuses to run otherwise. ++ +This option requires `-a`, and implies `-d`: the objects are dropped by +rebuilding the promisor pack without them and then removing the now +redundant old packs, so the redundant packs must be deleted for the +space to actually be reclaimed. It is incompatible with `--filter-to` +and with bitmap writing (`-b`/`--write-bitmap-index`), since filtering +breaks the single-pack closure that bitmaps require. A bitmap setting +coming from configuration is silently disabled for the duration of the +command. + +--dry-run:: + Only meaningful with `--drop-filtered`. List the objects that + would be dropped, one object ID per line, without rebuilding any + pack or deleting anything. + -b:: --write-bitmap-index:: Write a reachability bitmap index as part of the repack. This diff --git a/builtin/repack.c b/builtin/repack.c index 3633b17ce8..a5f13fdd87 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -287,9 +287,6 @@ int cmd_repack(int argc, 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")); @@ -322,6 +319,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) @@ -447,7 +452,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/t/t7706-repack-drop-filtered.sh b/t/t7706-repack-drop-filtered.sh index 6352f1fdce..80c695742f 100755 --- a/t/t7706-repack-drop-filtered.sh +++ b/t/t7706-repack-drop-filtered.sh @@ -135,4 +135,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 && + test_grep ! "$BIG" present && + test_grep "$SMALL" present +' + test_done -- 2.54.0