midx: expose `write_midx_file_only()` publicly
Expose a variant of the write_midx_file() function which ignores packs that aren't included in an explicit "allow" list. This will be used in an upcoming patch to power a new `--stdin-packs` mode of `git multi-pack-index write` for callers that only want to include certain packs in a MIDX (and ignore any packs which may have happened to enter the repository independently, e.g., from pushes). Those patches will provide test coverage for this new function. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Taylor Blau committed
Sep 28, 2021 at 21:55 UTC
56d863e9799c9d440eba3e61346662745a58ab21
2 files changed
+58
-8
midx.c
+49
-8
@@ -475,6 +475,8 @@ struct write_midx_context {
475
uint32_t num_large_offsets;
476
477
int preferred_pack_idx;
478
+
479
+ struct string_list *to_include;
480
};
481
482
static void add_pack_to_midx(const char *full_path, size_t full_path_len,
@@ -484,8 +486,26 @@ static void add_pack_to_midx(const char *full_path, size_t full_path_len,
486
487
if (ends_with(file_name, ".idx")) {
488
display_progress(ctx->progress, ++ctx->pack_paths_checked);
489
+ /*
490
+ * Note that at most one of ctx->m and ctx->to_include are set,
491
+ * so we are testing midx_contains_pack() and
492
+ * string_list_has_string() independently (guarded by the
493
+ * appropriate NULL checks).
494
+ *
495
+ * We could support passing to_include while reusing an existing
496
+ * MIDX, but don't currently since the reuse process drags
497
+ * forward all packs from an existing MIDX (without checking
498
+ * whether or not they appear in the to_include list).
499
+ *
500
+ * If we added support for that, these next two conditional
501
+ * should be performed independently (likely checking
502
+ * to_include before the existing MIDX).
503
+ */
504
if (ctx->m && midx_contains_pack(ctx->m, file_name))
505
return;
506
+ else if (ctx->to_include &&
507
+ !string_list_has_string(ctx->to_include, file_name))
508
+ return;
509
510
ALLOC_GROW(ctx->info, ctx->nr + 1, ctx->alloc);
511
@@ -1058,6 +1078,7 @@ cleanup:
1078
}
1079
1080
static int write_midx_internal(const char *object_dir,
1081
+ struct string_list *packs_to_include,
1082
struct string_list *packs_to_drop,
1083
const char *preferred_pack_name,
1084
unsigned flags)
@@ -1082,10 +1103,17 @@ static int write_midx_internal(const char *object_dir,
1103
die_errno(_("unable to create leading directories of %s"),
1104
midx_name);
1105
1085
- for (cur = get_multi_pack_index(the_repository); cur; cur = cur->next) {
1086
- if (!strcmp(object_dir, cur->object_dir)) {
1087
- ctx.m = cur;
1088
- break;
1106
+ if (!packs_to_include) {
1107
+ /*
1108
+ * Only reference an existing MIDX when not filtering which
1109
+ * packs to include, since all packs and objects are copied
1110
+ * blindly from an existing MIDX if one is present.
1111
+ */
1112
+ for (cur = get_multi_pack_index(the_repository); cur; cur = cur->next) {
1113
+ if (!strcmp(object_dir, cur->object_dir)) {
1114
+ ctx.m = cur;
1115
+ break;
1116
+ }
1117
}
1118
}
1119
@@ -1136,10 +1164,13 @@ static int write_midx_internal(const char *object_dir,
1164
else
1165
ctx.progress = NULL;
1166
1167
+ ctx.to_include = packs_to_include;
1168
+
1169
for_each_file_in_pack_dir(object_dir, add_pack_to_midx, &ctx);
1170
stop_progress(&ctx.progress);
1171
1142
- if (ctx.m && ctx.nr == ctx.m->num_packs && !packs_to_drop) {
1172
+ if ((ctx.m && ctx.nr == ctx.m->num_packs) &&
1173
+ !(packs_to_include || packs_to_drop)) {
1174
struct bitmap_index *bitmap_git;
1175
int bitmap_exists;
1176
int want_bitmap = flags & MIDX_WRITE_BITMAP;
@@ -1380,7 +1411,17 @@ int write_midx_file(const char *object_dir,
1411
const char *preferred_pack_name,
1412
unsigned flags)
1413
{
1383
- return write_midx_internal(object_dir, NULL, preferred_pack_name, flags);
1414
+ return write_midx_internal(object_dir, NULL, NULL, preferred_pack_name,
1415
+ flags);
1416
+}
1417
+
1418
+int write_midx_file_only(const char *object_dir,
1419
+ struct string_list *packs_to_include,
1420
+ const char *preferred_pack_name,
1421
+ unsigned flags)
1422
+{
1423
+ return write_midx_internal(object_dir, packs_to_include, NULL,
1424
+ preferred_pack_name, flags);
1425
}
1426
1427
struct clear_midx_data {
@@ -1660,7 +1701,7 @@ int expire_midx_packs(struct repository *r, const char *object_dir, unsigned fla
1701
free(count);
1702
1703
if (packs_to_drop.nr) {
1663
- result = write_midx_internal(object_dir, &packs_to_drop, NULL, flags);
1704
+ result = write_midx_internal(object_dir, NULL, &packs_to_drop, NULL, flags);
1705
m = NULL;
1706
}
1707
@@ -1851,7 +1892,7 @@ int midx_repack(struct repository *r, const char *object_dir, size_t batch_size,
1892
goto cleanup;
1893
}
1894
1854
- result = write_midx_internal(object_dir, NULL, NULL, flags);
1895
+ result = write_midx_internal(object_dir, NULL, NULL, NULL, flags);
1896
m = NULL;
1897
1898
cleanup:
midx.h
+9
@@ -2,6 +2,7 @@
2
#define MIDX_H
3
4
#include "repository.h"
5
+#include "string-list.h"
6
7
struct object_id;
8
struct pack_entry;
@@ -62,6 +63,14 @@ int midx_contains_pack(struct multi_pack_index *m, const char *idx_or_pack_name)
63
int prepare_multi_pack_index_one(struct repository *r, const char *object_dir, int local);
64
65
int write_midx_file(const char *object_dir, const char *preferred_pack_name, unsigned flags);
66
+/*
67
+ * Variant of write_midx_file which writes a MIDX containing only the packs
68
+ * specified in packs_to_include.
69
+ */
70
+int write_midx_file_only(const char *object_dir,
71
+ struct string_list *packs_to_include,
72
+ const char *preferred_pack_name,
73
+ unsigned flags);
74
void clear_midx_file(struct repository *r);
75
int verify_midx_file(struct repository *r, const char *object_dir, unsigned flags);
76
int expire_midx_packs(struct repository *r, const char *object_dir, unsigned flags);