]> git.ipfire.org Git - thirdparty/git.git/commitdiff
repack: mark geometric progression of packs as retained
authorTaylor Blau <me@ttaylorr.com>
Fri, 26 Jun 2026 19:02:20 +0000 (15:02 -0400)
committerJunio C Hamano <gitster@pobox.com>
Fri, 26 Jun 2026 21:54:54 +0000 (14:54 -0700)
In non-geometric repacks, any packs which repack wishes to delete are
handled via the `existing_packs` struct, which has a mechanism to retain
would-be-deleted packs (e.g., if we happened to write a new pack
identical to one otherwise marked for deletion).

In geometric repacks, repack removes any rewritten packs (alternatively,
any packs which were combined in order to restore a geometric
progression) by enumerating them via `pack_geometry_remove_redundant()`.

Prepare to use the `existing_packs` deletion machinery for geometric
repacks by marking any non-kept packs above the geometric split line as
retained. Do the same for promisor packs, which have their own split
point.

This commit only records which packs the later deletion pass must keep;
it does not change which packs are written or removed.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/repack.c
repack.c
repack.h

index 1524a9c13ad5b87e97adc7b5b5a710f22cadbe4c..ce979d86d964c35ebd707488d80731ee4b198a28 100644 (file)
@@ -325,6 +325,8 @@ int cmd_repack(int argc,
                }
                pack_geometry_init(&geometry, &existing, &po_args);
                pack_geometry_split(&geometry);
+
+               existing_packs_retain_from_geometry(&existing, &geometry);
        }
 
        prepare_pack_objects(&cmd, &po_args, packtmp);
index 986c74ac7e8c0d1242e4bca2790aba269dda754c..9b3cb4254310a91ccdaef3a3477deaf1d5641a9c 100644 (file)
--- a/repack.c
+++ b/repack.c
@@ -254,6 +254,33 @@ void existing_packs_retain_cruft(struct existing_packs *existing,
        existing_packs_mark_retained(item);
 }
 
+static void existing_packs_retain_non_kept(struct existing_packs *existing,
+                                          struct packed_git *p)
+{
+       struct string_list_item *item;
+
+       if (!p->pack_local)
+               return;
+
+       item = locate_existing_pack(&existing->non_kept_packs, p);
+       if (!item)
+               BUG("could not find non-kept pack '%s'", pack_basename(p));
+
+       existing_packs_mark_retained(item);
+}
+
+void existing_packs_retain_from_geometry(struct existing_packs *existing,
+                                        const struct pack_geometry *geometry)
+{
+       uint32_t i;
+
+       for (i = geometry->split; i < geometry->pack_nr; i++)
+               existing_packs_retain_non_kept(existing, geometry->pack[i]);
+       for (i = geometry->promisor_split; i < geometry->promisor_pack_nr; i++)
+               existing_packs_retain_non_kept(existing,
+                                              geometry->promisor_pack[i]);
+}
+
 void existing_packs_mark_for_deletion(struct existing_packs *existing,
                                      struct string_list *names)
 
index f9fbc895f0294072a338ddedbd47a386a4eff4a4..bb4c944d0cbd9070e7843c668ac44e11f695808f 100644 (file)
--- a/repack.h
+++ b/repack.h
@@ -54,6 +54,7 @@ int finish_pack_objects_cmd(const struct git_hash_algo *algop,
 
 struct repository;
 struct packed_git;
+struct pack_geometry;
 
 struct existing_packs {
        struct repository *repo;
@@ -82,6 +83,8 @@ int existing_packs_has_non_kept(const struct existing_packs *existing);
 int existing_pack_is_marked_for_deletion(struct string_list_item *item);
 void existing_packs_retain_cruft(struct existing_packs *existing,
                                 struct packed_git *cruft);
+void existing_packs_retain_from_geometry(struct existing_packs *existing,
+                                        const struct pack_geometry *geometry);
 void existing_packs_mark_for_deletion(struct existing_packs *existing,
                                      struct string_list *names);
 void existing_packs_retain_midx_packs(struct existing_packs *existing);