292
&existing->cruft_packs);
293
}
294
295
+static int pack_geometry_contains_pack(struct packed_git **packs,
296
+ uint32_t packs_nr,
297
+ const char *base)
298
+{
299
+ struct strbuf buf = STRBUF_INIT;
300
+ uint32_t i;
301
+
302
+ for (i = 0; i < packs_nr; i++) {
303
+ strbuf_reset(&buf);
304
+ strbuf_addstr(&buf, pack_basename(packs[i]));
305
+ strbuf_strip_suffix(&buf, ".pack");
306
+
307
+ if (!strcmp(buf.buf, base)) {
308
+ strbuf_release(&buf);
309
+ return 1;
310
+ }
311
+ }
312
+
313
+ strbuf_release(&buf);
314
+ return 0;
315
+}
316
+
317
+static int pack_geometry_contains_rollup(const struct pack_geometry *geometry,
318
+ const char *base)
319
+{
320
+ if (!geometry || !geometry->split_factor)
321
+ return 0;
322
+
323
+ return pack_geometry_contains_pack(geometry->pack, geometry->split, base) ||
324
+ pack_geometry_contains_pack(geometry->promisor_pack,
325
+ geometry->promisor_split, base);
326
+}
327
+
328
/*
329
* Mark every pack that is referenced by the existing MIDX chain as
330
* retained, so that a subsequent call to
333
* This is used when writing an incremental MIDX layer on top of an
334
* existing chain: retained layers continue to reference the same
335
* packs on disk, so those packs must not be unlinked even if the
303
- * freshly-written pack supersedes them.
336
+ * freshly-written pack supersedes them. When doing a geometric repack,
337
+ * packs below the split are rewritten into the new MIDX tip and should
338
+ * remain eligible for deletion.
339
*/
305
-void existing_packs_retain_midx_packs(struct existing_packs *existing)
340
+void existing_packs_retain_midx_packs(struct existing_packs *existing,
341
+ const struct pack_geometry *geometry)
342
{
343
struct string_list_item *item;
344
struct strbuf buf = STRBUF_INIT;
351
strbuf_strip_suffix(&buf, ".pack");
352
strbuf_strip_suffix(&buf, ".idx");
353
354
+ if (pack_geometry_contains_rollup(geometry, buf.buf))
355
+ continue;
356
+
357
found = string_list_lookup(&existing->non_kept_packs, buf.buf);
358
if (found)
359
existing_packs_mark_retained(found);