[PATCH v2 4/8] repack: use a sorted list for explicitly kept packs
- From
Taylor Blau <ttaylorr@openai.com>
- Date
- Oct 1, 2026, 04:11 UTC
- Message-ID
- <c1ff18bf91363c638536265c600a7ce5ac4e1218.1790827875.git.me@ttaylorr.com>
- In-Reply-To
- <cover.1790827875.git.me@ttaylorr.com>
`existing_packs_collect()` performs a linear search through the '--keep-pack' arguments for each local pack. Typically the number of such arguments is small enough that the difference between a linear and binary search is just noise (especially compared with the amount of work that 'repack' is about to perform).
However, an additional caller will wish to search through the same list. To prevent that caller from having to duplicate the clunky for-loop in `existing_packs_collect()`, sort the list using `fspathcmp()` and replace the existing caller's loop with `string_list_has_string()`.
This does not change the overall behavior of '--keep-pack' arguments.
Signed-off-by: Taylor Blau <ttaylorr@openai.com> --- builtin/repack.c | 3 +++ repack.c | 8 +------- repack.h | 4 ++++ 3 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/builtin/repack.c b/builtin/repack.c index b7596d488da..88b05e96b5b 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -2,6 +2,7 @@ #include "builtin.h" #include "config.h" +#include "dir.h" #include "environment.h" #include "parse-options.h" #include "path.h" @@ -455,6 +456,8 @@ int cmd_repack(int argc, packtmp = mkpathdup("%s/%s", packdir, packtmp_name); existing.repo = repo; + keep_pack_list.cmp = fspathcmp; + string_list_sort(&keep_pack_list); existing_packs_collect(&existing, &keep_pack_list); if (geometry.split_factor) { diff --git a/repack.c b/repack.c index d2aa58e1348..fa748ce46ce 100644 --- a/repack.c +++ b/repack.c @@ -1,5 +1,4 @@ #include "git-compat-util.h" -#include "dir.h" #include "midx.h" #include "odb.h" #include "packfile.h" @@ -131,7 +130,6 @@ void existing_packs_collect(struct existing_packs *existing, struct strbuf buf = STRBUF_INIT; repo_for_each_pack(existing->repo, p) { - size_t i; const char *base; if (p->multi_pack_index) @@ -142,15 +140,11 @@ void existing_packs_collect(struct existing_packs *existing, base = pack_basename(p); - for (i = 0; i < extra_keep->nr; i++) - if (!fspathcmp(base, extra_keep->items[i].string)) - break; - strbuf_reset(&buf); strbuf_addstr(&buf, base); strbuf_strip_suffix(&buf, ".pack"); - if ((extra_keep->nr > 0 && i < extra_keep->nr) || p->pack_keep) + if (p->pack_keep || string_list_has_string(extra_keep, base)) string_list_append(&existing->kept_packs, buf.buf); else if (p->is_cruft) string_list_append(&existing->cruft_packs, buf.buf); diff --git a/repack.h b/repack.h index 61e554e4ed3..9f95e3a26f4 100644 --- a/repack.h +++ b/repack.h @@ -76,6 +76,10 @@ struct existing_packs { * or packs->kept based on whether each pack has a corresponding * .keep file or not. Packs without a .keep file are not to be kept * if we are going to pack everything into one file. + * + * A non-empty extra_keep must be sorted and use fspathcmp() as its + * comparator. Its entries are pack basenames, including the ".pack" + * suffix. */ void existing_packs_collect(struct existing_packs *existing, const struct string_list *extra_keep);
-- 2.56.0.8.ga42f775cbe2