summaryrefslogtreecommitdiff
path: root/midx.c
diff options
context:
space:
mode:
Diffstat (limited to 'midx.c')
-rw-r--r--midx.c116
1 files changed, 103 insertions, 13 deletions
diff --git a/midx.c b/midx.c
index f96fb2efee..7e06e85975 100644
--- a/midx.c
+++ b/midx.c
@@ -460,6 +460,8 @@ struct write_midx_context {
uint32_t num_large_offsets;
int preferred_pack_idx;
+
+ struct string_list *to_include;
};
static void add_pack_to_midx(const char *full_path, size_t full_path_len,
@@ -469,8 +471,26 @@ static void add_pack_to_midx(const char *full_path, size_t full_path_len,
if (ends_with(file_name, ".idx")) {
display_progress(ctx->progress, ++ctx->pack_paths_checked);
+ /*
+ * Note that at most one of ctx->m and ctx->to_include are set,
+ * so we are testing midx_contains_pack() and
+ * string_list_has_string() independently (guarded by the
+ * appropriate NULL checks).
+ *
+ * We could support passing to_include while reusing an existing
+ * MIDX, but don't currently since the reuse process drags
+ * forward all packs from an existing MIDX (without checking
+ * whether or not they appear in the to_include list).
+ *
+ * If we added support for that, these next two conditional
+ * should be performed independently (likely checking
+ * to_include before the existing MIDX).
+ */
if (ctx->m && midx_contains_pack(ctx->m, file_name))
return;
+ else if (ctx->to_include &&
+ !string_list_has_string(ctx->to_include, file_name))
+ return;
ALLOC_GROW(ctx->info, ctx->nr + 1, ctx->alloc);
@@ -948,7 +968,43 @@ static void bitmap_show_commit(struct commit *commit, void *_data)
data->commits[data->commits_nr++] = commit;
}
+static int read_refs_snapshot(const char *refs_snapshot,
+ struct rev_info *revs)
+{
+ struct strbuf buf = STRBUF_INIT;
+ struct object_id oid;
+ FILE *f = xfopen(refs_snapshot, "r");
+
+ while (strbuf_getline(&buf, f) != EOF) {
+ struct object *object;
+ int preferred = 0;
+ char *hex = buf.buf;
+ const char *end = NULL;
+
+ if (buf.len && *buf.buf == '+') {
+ preferred = 1;
+ hex = &buf.buf[1];
+ }
+
+ if (parse_oid_hex(hex, &oid, &end) < 0)
+ die(_("could not parse line: %s"), buf.buf);
+ if (*end)
+ die(_("malformed line: %s"), buf.buf);
+
+ object = parse_object_or_die(&oid, NULL);
+ if (preferred)
+ object->flags |= NEEDS_BITMAP;
+
+ add_pending_object(revs, object, "");
+ }
+
+ fclose(f);
+ strbuf_release(&buf);
+ return 0;
+}
+
static struct commit **find_commits_for_midx_bitmap(uint32_t *indexed_commits_nr_p,
+ const char *refs_snapshot,
struct write_midx_context *ctx)
{
struct rev_info revs;
@@ -957,8 +1013,12 @@ static struct commit **find_commits_for_midx_bitmap(uint32_t *indexed_commits_nr
cb.ctx = ctx;
repo_init_revisions(the_repository, &revs, NULL);
- setup_revisions(0, NULL, &revs, NULL);
- for_each_ref(add_ref_to_pending, &revs);
+ if (refs_snapshot) {
+ read_refs_snapshot(refs_snapshot, &revs);
+ } else {
+ setup_revisions(0, NULL, &revs, NULL);
+ for_each_ref(add_ref_to_pending, &revs);
+ }
/*
* Skipping promisor objects here is intentional, since it only excludes
@@ -987,18 +1047,23 @@ static struct commit **find_commits_for_midx_bitmap(uint32_t *indexed_commits_nr
static int write_midx_bitmap(char *midx_name, unsigned char *midx_hash,
struct write_midx_context *ctx,
+ const char *refs_snapshot,
unsigned flags)
{
struct packing_data pdata;
struct pack_idx_entry **index;
struct commit **commits = NULL;
uint32_t i, commits_nr;
+ uint16_t options = 0;
char *bitmap_name = xstrfmt("%s-%s.bitmap", midx_name, hash_to_hex(midx_hash));
int ret;
+ if (flags & MIDX_WRITE_BITMAP_HASH_CACHE)
+ options |= BITMAP_OPT_HASH_CACHE;
+
prepare_midx_packing_data(&pdata, ctx);
- commits = find_commits_for_midx_bitmap(&commits_nr, ctx);
+ commits = find_commits_for_midx_bitmap(&commits_nr, refs_snapshot, ctx);
/*
* Build the MIDX-order index based on pdata.objects (which is already
@@ -1034,7 +1099,7 @@ static int write_midx_bitmap(char *midx_name, unsigned char *midx_hash,
goto cleanup;
bitmap_writer_set_checksum(midx_hash);
- bitmap_writer_finish(index, pdata.nr_objects, bitmap_name, 0);
+ bitmap_writer_finish(index, pdata.nr_objects, bitmap_name, options);
cleanup:
free(index);
@@ -1043,8 +1108,10 @@ cleanup:
}
static int write_midx_internal(const char *object_dir,
+ struct string_list *packs_to_include,
struct string_list *packs_to_drop,
const char *preferred_pack_name,
+ const char *refs_snapshot,
unsigned flags)
{
char *midx_name;
@@ -1067,10 +1134,17 @@ static int write_midx_internal(const char *object_dir,
die_errno(_("unable to create leading directories of %s"),
midx_name);
- for (cur = get_multi_pack_index(the_repository); cur; cur = cur->next) {
- if (!strcmp(object_dir, cur->object_dir)) {
- ctx.m = cur;
- break;
+ if (!packs_to_include) {
+ /*
+ * Only reference an existing MIDX when not filtering which
+ * packs to include, since all packs and objects are copied
+ * blindly from an existing MIDX if one is present.
+ */
+ for (cur = get_multi_pack_index(the_repository); cur; cur = cur->next) {
+ if (!strcmp(object_dir, cur->object_dir)) {
+ ctx.m = cur;
+ break;
+ }
}
}
@@ -1121,10 +1195,13 @@ static int write_midx_internal(const char *object_dir,
else
ctx.progress = NULL;
+ ctx.to_include = packs_to_include;
+
for_each_file_in_pack_dir(object_dir, add_pack_to_midx, &ctx);
stop_progress(&ctx.progress);
- if (ctx.m && ctx.nr == ctx.m->num_packs && !packs_to_drop) {
+ if ((ctx.m && ctx.nr == ctx.m->num_packs) &&
+ !(packs_to_include || packs_to_drop)) {
struct bitmap_index *bitmap_git;
int bitmap_exists;
int want_bitmap = flags & MIDX_WRITE_BITMAP;
@@ -1328,7 +1405,8 @@ static int write_midx_internal(const char *object_dir,
if (flags & MIDX_WRITE_REV_INDEX)
write_midx_reverse_index(midx_name, midx_hash, &ctx);
if (flags & MIDX_WRITE_BITMAP) {
- if (write_midx_bitmap(midx_name, midx_hash, &ctx, flags) < 0) {
+ if (write_midx_bitmap(midx_name, midx_hash, &ctx,
+ refs_snapshot, flags) < 0) {
error(_("could not write multi-pack bitmap"));
result = 1;
goto cleanup;
@@ -1363,9 +1441,21 @@ cleanup:
int write_midx_file(const char *object_dir,
const char *preferred_pack_name,
+ const char *refs_snapshot,
unsigned flags)
{
- return write_midx_internal(object_dir, NULL, preferred_pack_name, flags);
+ return write_midx_internal(object_dir, NULL, NULL, preferred_pack_name,
+ refs_snapshot, flags);
+}
+
+int write_midx_file_only(const char *object_dir,
+ struct string_list *packs_to_include,
+ const char *preferred_pack_name,
+ const char *refs_snapshot,
+ unsigned flags)
+{
+ return write_midx_internal(object_dir, packs_to_include, NULL,
+ preferred_pack_name, refs_snapshot, flags);
}
struct clear_midx_data {
@@ -1645,7 +1735,7 @@ int expire_midx_packs(struct repository *r, const char *object_dir, unsigned fla
free(count);
if (packs_to_drop.nr) {
- result = write_midx_internal(object_dir, &packs_to_drop, NULL, flags);
+ result = write_midx_internal(object_dir, NULL, &packs_to_drop, NULL, NULL, flags);
m = NULL;
}
@@ -1836,7 +1926,7 @@ int midx_repack(struct repository *r, const char *object_dir, size_t batch_size,
goto cleanup;
}
- result = write_midx_internal(object_dir, NULL, NULL, flags);
+ result = write_midx_internal(object_dir, NULL, NULL, NULL, NULL, flags);
m = NULL;
cleanup: