#include "git-compat-util.h"
#include "abspath.h"
#include "config.h"
#include "hex.h"
#include "lockfile.h"
#include "packfile.h"
#include "object-file.h"
#include "hash-lookup.h"
#include "midx.h"
#include "progress.h"
#include "trace2.h"
#include "run-command.h"
#include "chunk-format.h"
#include "pack-bitmap.h"
#include "refs.h"
#include "revision.h"
#include "list-objects.h"
#include "path.h"
#include "pack-revindex.h"

#define PACK_EXPIRED UINT_MAX
#define BITMAP_POS_UNKNOWN (~((uint32_t)0))
#define MIDX_CHUNK_FANOUT_SIZE (sizeof(uint32_t) * 256)
#define MIDX_CHUNK_LARGE_OFFSET_WIDTH (sizeof(uint64_t))
#define NO_PREFERRED_PACK (~((uint32_t)0))

extern int midx_checksum_valid(struct multi_pack_index *m);
extern void clear_midx_files_ext(struct odb_source *source, const char *ext,
				 const char *keep_hash);
extern void clear_incremental_midx_files_ext(struct odb_source *source,
					     const char *ext,
					     const char **keep_hashes,
					     uint32_t hashes_nr);
extern int cmp_idx_or_pack_name(const char *idx_or_pack_name,
				const char *idx_name);

static size_t write_midx_header(const struct git_hash_algo *hash_algo,
				struct hashfile *f, unsigned char num_chunks,
				uint32_t num_packs, int version)
{
	if (version != MIDX_VERSION_V1 && version != MIDX_VERSION_V2)
		BUG("unexpected MIDX version: %d", version);

	hashwrite_be32(f, MIDX_SIGNATURE);
	hashwrite_u8(f, version);
	hashwrite_u8(f, oid_version(hash_algo));
	hashwrite_u8(f, num_chunks);
	hashwrite_u8(f, 0); /* unused */
	hashwrite_be32(f, num_packs);

	return MIDX_HEADER_SIZE;
}

struct pack_info {
	uint32_t orig_pack_int_id;
	char *pack_name;
	struct packed_git *p;

	uint32_t bitmap_pos;
	uint32_t bitmap_nr;

	unsigned expired : 1;
};

static void fill_pack_info(struct pack_info *info,
			   struct packed_git *p, const char *pack_name,
			   uint32_t orig_pack_int_id)
{
	memset(info, 0, sizeof(struct pack_info));

	info->orig_pack_int_id = orig_pack_int_id;
	info->pack_name = xstrdup(pack_name);
	info->p = p;
	info->bitmap_pos = BITMAP_POS_UNKNOWN;
}

static int pack_info_compare(const void *_a, const void *_b)
{
	struct pack_info *a = (struct pack_info *)_a;
	struct pack_info *b = (struct pack_info *)_b;
	return strcmp(a->pack_name, b->pack_name);
}

static int idx_or_pack_name_cmp(const void *_va, const void *_vb)
{
	const char *pack_name = _va;
	const struct pack_info *compar = _vb;

	return cmp_idx_or_pack_name(pack_name, compar->pack_name);
}

struct write_midx_context {
	struct pack_info *info;
	size_t nr;
	size_t alloc;
	struct multi_pack_index *m;
	struct multi_pack_index *base_midx;
	struct progress *progress;
	unsigned pack_paths_checked;

	struct pack_midx_entry *entries;
	size_t entries_nr;

	uint32_t *pack_perm;
	uint32_t *pack_order;
	unsigned large_offsets_needed:1;
	uint32_t num_large_offsets;

	uint32_t preferred_pack_idx;

	int version; /* must be MIDX_VERSION_V1 or _V2 */

	int incremental;
	uint32_t num_multi_pack_indexes_before;

	struct multi_pack_index *compact_from;
	struct multi_pack_index *compact_to;
	int compact;

	struct string_list *to_include;

	struct repository *repo;
	struct odb_source *source;
};

static uint32_t midx_pack_perm(struct write_midx_context *ctx,
			       uint32_t orig_pack_int_id)
{
	if (ctx->compact)
		orig_pack_int_id -= ctx->compact_from->num_packs_in_base;
	return ctx->pack_perm[orig_pack_int_id];
}

static int should_include_pack(const struct write_midx_context *ctx,
			       const char *file_name)
{
	/*
	 * 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 0;
	else if (ctx->base_midx && midx_contains_pack(ctx->base_midx,
						      file_name))
		return 0;
	else if (ctx->to_include &&
		 !string_list_has_string(ctx->to_include, file_name))
		return 0;
	return 1;
}

static void add_pack_to_midx(const char *full_path, size_t full_path_len,
			     const char *file_name, void *data)
{
	struct write_midx_context *ctx = data;
	struct packed_git *p;

	if (ends_with(file_name, ".idx")) {
		display_progress(ctx->progress, ++ctx->pack_paths_checked);

		if (!should_include_pack(ctx, file_name))
			return;

		ALLOC_GROW(ctx->info, ctx->nr + 1, ctx->alloc);
		p = add_packed_git(ctx->repo, full_path, full_path_len, 0);
		if (!p) {
			warning(_("failed to add packfile '%s'"),
				full_path);
			return;
		}

		if (open_pack_index(p)) {
			warning(_("failed to open pack-index '%s'"),
				full_path);
			close_pack(p);
			free(p);
			return;
		}

		fill_pack_info(&ctx->info[ctx->nr], p, file_name, ctx->nr);
		ctx->nr++;
	}
}

struct pack_midx_entry {
	struct object_id oid;
	uint32_t pack_int_id;
	time_t pack_mtime;
	uint64_t offset;
	unsigned preferred : 1;
};

static int midx_oid_compare(const void *_a, const void *_b)
{
	const struct pack_midx_entry *a = (const struct pack_midx_entry *)_a;
	const struct pack_midx_entry *b = (const struct pack_midx_entry *)_b;
	int cmp = oidcmp(&a->oid, &b->oid);

	if (cmp)
		return cmp;

	/* Sort objects in a preferred pack first when multiple copies exist. */
	if (a->preferred > b->preferred)
		return -1;
	if (a->preferred < b->preferred)
		return 1;

	if (a->pack_mtime > b->pack_mtime)
		return -1;
	else if (a->pack_mtime < b->pack_mtime)
		return 1;

	return a->pack_int_id - b->pack_int_id;
}

static int nth_midxed_pack_midx_entry(struct multi_pack_index *m,
				      struct pack_midx_entry *e,
				      uint32_t pos)
{
	if (pos >= m->num_objects + m->num_objects_in_base)
		return 1;

	nth_midxed_object_oid(&e->oid, m, pos);
	e->pack_int_id = nth_midxed_pack_int_id(m, pos);
	e->offset = nth_midxed_offset(m, pos);

	/* consider objects in midx to be from "old" packs */
	e->pack_mtime = 0;
	return 0;
}

static void fill_pack_entry(uint32_t pack_int_id,
			    struct packed_git *p,
			    uint32_t cur_object,
			    struct pack_midx_entry *entry,
			    int preferred)
{
	if (nth_packed_object_id(&entry->oid, p, cur_object) < 0)
		die(_("failed to locate object %d in packfile"), cur_object);

	entry->pack_int_id = pack_int_id;
	entry->pack_mtime = p->mtime;

	entry->offset = nth_packed_object_offset(p, cur_object);
	entry->preferred = !!preferred;
}

struct midx_fanout {
	struct pack_midx_entry *entries;
	size_t nr, alloc;
};

static void midx_fanout_grow(struct midx_fanout *fanout, size_t nr)
{
	if (nr < fanout->nr)
		BUG("negative growth in midx_fanout_grow() (%"PRIuMAX" < %"PRIuMAX")",
		    (uintmax_t)nr, (uintmax_t)fanout->nr);
	ALLOC_GROW(fanout->entries, nr, fanout->alloc);
}

static void midx_fanout_sort(struct midx_fanout *fanout)
{
	QSORT(fanout->entries, fanout->nr, midx_oid_compare);
}

static void midx_fanout_add_midx_fanout_1(struct midx_fanout *fanout,
					  struct multi_pack_index *m,
					  uint32_t cur_fanout,
					  uint32_t preferred_pack)
{
	uint32_t start = m->num_objects_in_base, end;
	uint32_t cur_object;

	if (cur_fanout)
		start += ntohl(m->chunk_oid_fanout[cur_fanout - 1]);
	end = m->num_objects_in_base + ntohl(m->chunk_oid_fanout[cur_fanout]);

	for (cur_object = start; cur_object < end; cur_object++) {
		if ((preferred_pack != NO_PREFERRED_PACK) &&
		    (preferred_pack == nth_midxed_pack_int_id(m, cur_object))) {
			/*
			 * Objects from preferred packs are added
			 * separately.
			 */
			continue;
		}

		midx_fanout_grow(fanout, fanout->nr + 1);
		nth_midxed_pack_midx_entry(m,
					   &fanout->entries[fanout->nr],
					   cur_object);
		fanout->entries[fanout->nr].preferred = 0;
		fanout->nr++;
	}
}

static void midx_fanout_add_midx_fanout(struct midx_fanout *fanout,
					struct multi_pack_index *m,
					uint32_t cur_fanout,
					uint32_t preferred_pack)
{
	if (m->base_midx)
		midx_fanout_add_midx_fanout(fanout, m->base_midx, cur_fanout,
					    preferred_pack);
	midx_fanout_add_midx_fanout_1(fanout, m, cur_fanout, preferred_pack);
}

static void midx_fanout_add_pack_fanout(struct midx_fanout *fanout,
					struct pack_info *info,
					uint32_t cur_pack,
					int preferred,
					uint32_t cur_fanout)
{
	struct packed_git *pack = info[cur_pack].p;
	uint32_t start = 0, end;
	uint32_t cur_object;

	if (cur_fanout)
		start = get_pack_fanout(pack, cur_fanout - 1);
	end = get_pack_fanout(pack, cur_fanout);

	for (cur_object = start; cur_object < end; cur_object++) {
		midx_fanout_grow(fanout, fanout->nr + 1);
		fill_pack_entry(cur_pack,
				info[cur_pack].p,
				cur_object,
				&fanout->entries[fanout->nr],
				preferred);
		fanout->nr++;
	}
}

static void midx_fanout_add(struct midx_fanout *fanout,
			    struct write_midx_context *ctx,
			    uint32_t start_pack,
			    uint32_t cur_fanout)
{
	uint32_t cur_pack;

	if (ctx->m && !ctx->incremental)
		midx_fanout_add_midx_fanout(fanout, ctx->m, cur_fanout,
					    ctx->preferred_pack_idx);

	for (cur_pack = start_pack; cur_pack < ctx->nr; cur_pack++) {
		int preferred = cur_pack == ctx->preferred_pack_idx;
		midx_fanout_add_pack_fanout(fanout, ctx->info, cur_pack,
					    preferred, cur_fanout);
	}

	if (ctx->preferred_pack_idx != NO_PREFERRED_PACK &&
	    ctx->preferred_pack_idx < start_pack)
		midx_fanout_add_pack_fanout(fanout, ctx->info,
					    ctx->preferred_pack_idx, 1,
					    cur_fanout);
}

static void midx_fanout_add_compact(struct midx_fanout *fanout,
				    struct write_midx_context *ctx,
				    uint32_t cur_fanout)
{
	struct multi_pack_index *m = ctx->compact_to;

	ASSERT(ctx->compact);

	while (m && m != ctx->compact_from->base_midx) {
		midx_fanout_add_midx_fanout_1(fanout, m, cur_fanout,
					      NO_PREFERRED_PACK);
		m = m->base_midx;
	}
}

/*
 * It is possible to artificially get into a state where there are many
 * duplicate copies of objects. That can create high memory pressure if
 * we are to create a list of all objects before de-duplication. To reduce
 * this memory pressure without a significant performance drop, automatically
 * group objects by the first byte of their object id. Use the IDX fanout
 * tables to group the data, copy to a local array, then sort.
 *
 * Copy only the de-duplicated entries (selected by most-recent modified time
 * of a packfile containing the object).
 */
static void compute_sorted_entries(struct write_midx_context *ctx,
				   uint32_t start_pack)
{
	uint32_t cur_fanout, cur_pack, cur_object;
	size_t alloc_objects, total_objects = 0;
	struct midx_fanout fanout = { 0 };

	if (ctx->compact)
		ASSERT(!start_pack);

	for (cur_pack = start_pack; cur_pack < ctx->nr; cur_pack++)
		total_objects = st_add(total_objects,
				       ctx->info[cur_pack].p->num_objects);

	/*
	 * As we de-duplicate by fanout value, we expect the fanout
	 * slices to be evenly distributed, with some noise. Hence,
	 * allocate slightly more than one 256th.
	 */
	alloc_objects = fanout.alloc = total_objects > 3200 ? total_objects / 200 : 16;

	ALLOC_ARRAY(fanout.entries, fanout.alloc);
	ALLOC_ARRAY(ctx->entries, alloc_objects);
	ctx->entries_nr = 0;

	for (cur_fanout = 0; cur_fanout < 256; cur_fanout++) {
		fanout.nr = 0;

		if (ctx->compact)
			midx_fanout_add_compact(&fanout, ctx, cur_fanout);
		else
			midx_fanout_add(&fanout, ctx, start_pack, cur_fanout);
		midx_fanout_sort(&fanout);

		/*
		 * The batch is now sorted by OID and then mtime (descending).
		 * Take only the first duplicate.
		 */
		for (cur_object = 0; cur_object < fanout.nr; cur_object++) {
			if (cur_object && oideq(&fanout.entries[cur_object - 1].oid,
						&fanout.entries[cur_object].oid))
				continue;
			if (ctx->incremental && ctx->base_midx &&
			    midx_has_oid(ctx->base_midx,
					 &fanout.entries[cur_object].oid))
				continue;

			ALLOC_GROW(ctx->entries, st_add(ctx->entries_nr, 1),
				   alloc_objects);
			memcpy(&ctx->entries[ctx->entries_nr],
			       &fanout.entries[cur_object],
			       sizeof(struct pack_midx_entry));
			ctx->entries_nr++;
		}
	}

	free(fanout.entries);
}

static int write_midx_pack_names(struct hashfile *f, void *data)
{
	struct write_midx_context *ctx = data;
	uint32_t i;
	unsigned char padding[MIDX_CHUNK_ALIGNMENT];
	size_t written = 0;

	for (i = 0; i < ctx->nr; i++) {
		size_t writelen;

		if (ctx->info[i].expired)
			continue;

		if (ctx->version == MIDX_VERSION_V1 &&
		    i && strcmp(ctx->info[i].pack_name,
				ctx->info[i - 1].pack_name) <= 0)
			BUG("incorrect pack-file order: %s before %s",
			    ctx->info[i - 1].pack_name,
			    ctx->info[i].pack_name);

		writelen = strlen(ctx->info[i].pack_name) + 1;
		hashwrite(f, ctx->info[i].pack_name, writelen);
		written += writelen;
	}

	/* add padding to be aligned */
	i = MIDX_CHUNK_ALIGNMENT - (written % MIDX_CHUNK_ALIGNMENT);
	if (i < MIDX_CHUNK_ALIGNMENT) {
		memset(padding, 0, sizeof(padding));
		hashwrite(f, padding, i);
	}

	return 0;
}

static int write_midx_bitmapped_packs(struct hashfile *f, void *data)
{
	struct write_midx_context *ctx = data;
	size_t i;

	for (i = 0; i < ctx->nr; i++) {
		struct pack_info *pack = &ctx->info[i];
		if (pack->expired)
			continue;

		if (pack->bitmap_pos == BITMAP_POS_UNKNOWN && pack->bitmap_nr)
			BUG("pack '%s' has no bitmap position, but has %d bitmapped object(s)",
			    pack->pack_name, pack->bitmap_nr);

		hashwrite_be32(f, pack->bitmap_pos);
		hashwrite_be32(f, pack->bitmap_nr);
	}
	return 0;
}

static int write_midx_oid_fanout(struct hashfile *f,
				 void *data)
{
	struct write_midx_context *ctx = data;
	struct pack_midx_entry *list = ctx->entries;
	struct pack_midx_entry *last = ctx->entries + ctx->entries_nr;
	uint32_t count = 0;
	uint32_t i;

	/*
	* Write the first-level table (the list is sorted,
	* but we use a 256-entry lookup to be able to avoid
	* having to do eight extra binary search iterations).
	*/
	for (i = 0; i < 256; i++) {
		struct pack_midx_entry *next = list;

		while (next < last && next->oid.hash[0] == i) {
			count++;
			next++;
		}

		hashwrite_be32(f, count);
		list = next;
	}

	return 0;
}

static int write_midx_oid_lookup(struct hashfile *f,
				 void *data)
{
	struct write_midx_context *ctx = data;
	unsigned char hash_len = ctx->repo->hash_algo->rawsz;
	struct pack_midx_entry *list = ctx->entries;
	uint32_t i;

	for (i = 0; i < ctx->entries_nr; i++) {
		struct pack_midx_entry *obj = list++;

		if (i < ctx->entries_nr - 1) {
			struct pack_midx_entry *next = list;
			if (oidcmp(&obj->oid, &next->oid) >= 0)
				BUG("OIDs not in order: %s >= %s",
				    oid_to_hex(&obj->oid),
				    oid_to_hex(&next->oid));
		}

		hashwrite(f, obj->oid.hash, (int)hash_len);
	}

	return 0;
}

static int write_midx_object_offsets(struct hashfile *f,
				     void *data)
{
	struct write_midx_context *ctx = data;
	struct pack_midx_entry *list = ctx->entries;
	uint32_t i, nr_large_offset = 0;

	for (i = 0; i < ctx->entries_nr; i++) {
		struct pack_midx_entry *obj = list++;

		if (midx_pack_perm(ctx, obj->pack_int_id) == PACK_EXPIRED)
			BUG("object %s is in an expired pack with int-id %d",
			    oid_to_hex(&obj->oid),
			    obj->pack_int_id);

		hashwrite_be32(f, midx_pack_perm(ctx, obj->pack_int_id));

		if (ctx->large_offsets_needed && obj->offset >> 31)
			hashwrite_be32(f, MIDX_LARGE_OFFSET_NEEDED | nr_large_offset++);
		else if (!ctx->large_offsets_needed && obj->offset >> 32)
			BUG("object %s requires a large offset (%"PRIx64") but the MIDX is not writing large offsets!",
			    oid_to_hex(&obj->oid),
			    obj->offset);
		else
			hashwrite_be32(f, (uint32_t)obj->offset);
	}

	return 0;
}

static int write_midx_large_offsets(struct hashfile *f,
				    void *data)
{
	struct write_midx_context *ctx = data;
	struct pack_midx_entry *list = ctx->entries;
	struct pack_midx_entry *end = ctx->entries + ctx->entries_nr;
	uint32_t nr_large_offset = ctx->num_large_offsets;

	while (nr_large_offset) {
		struct pack_midx_entry *obj;
		uint64_t offset;

		if (list >= end)
			BUG("too many large-offset objects");

		obj = list++;
		offset = obj->offset;

		if (!(offset >> 31))
			continue;

		hashwrite_be64(f, offset);

		nr_large_offset--;
	}

	return 0;
}

static int write_midx_revindex(struct hashfile *f,
			       void *data)
{
	struct write_midx_context *ctx = data;
	uint32_t i, nr_base;

	if (ctx->incremental && ctx->base_midx)
		nr_base = ctx->base_midx->num_objects +
			ctx->base_midx->num_objects_in_base;
	else
		nr_base = 0;

	for (i = 0; i < ctx->entries_nr; i++)
		hashwrite_be32(f, ctx->pack_order[i] + nr_base);

	return 0;
}

struct midx_pack_order_data {
	uint32_t nr;
	uint32_t pack;
	off_t offset;
};

static int midx_pack_order_cmp(const void *va, const void *vb)
{
	const struct midx_pack_order_data *a = va, *b = vb;
	if (a->pack < b->pack)
		return -1;
	else if (a->pack > b->pack)
		return 1;
	else if (a->offset < b->offset)
		return -1;
	else if (a->offset > b->offset)
		return 1;
	else
		return 0;
}

static uint32_t *midx_pack_order(struct write_midx_context *ctx)
{
	struct midx_pack_order_data *data;
	uint32_t *pack_order, base_objects = 0;
	uint32_t i;

	trace2_region_enter("midx", "midx_pack_order", ctx->repo);

	if (ctx->incremental && ctx->base_midx)
		base_objects = ctx->base_midx->num_objects +
			ctx->base_midx->num_objects_in_base;

	ALLOC_ARRAY(pack_order, ctx->entries_nr);
	ALLOC_ARRAY(data, ctx->entries_nr);

	for (i = 0; i < ctx->entries_nr; i++) {
		struct pack_midx_entry *e = &ctx->entries[i];
		data[i].nr = i;
		data[i].pack = midx_pack_perm(ctx, e->pack_int_id);
		if (!e->preferred || ctx->compact)
			data[i].pack |= (1U << 31);
		data[i].offset = e->offset;
	}

	QSORT(data, ctx->entries_nr, midx_pack_order_cmp);

	for (i = 0; i < ctx->entries_nr; i++) {
		struct pack_midx_entry *e = &ctx->entries[data[i].nr];
		struct pack_info *pack = &ctx->info[midx_pack_perm(ctx, e->pack_int_id)];
		if (pack->bitmap_pos == BITMAP_POS_UNKNOWN)
			pack->bitmap_pos = i + base_objects;
		pack->bitmap_nr++;
		pack_order[i] = data[i].nr;
	}
	for (i = 0; i < ctx->nr; i++) {
		struct pack_info *pack = &ctx->info[i];
		if (pack->bitmap_pos == BITMAP_POS_UNKNOWN)
			pack->bitmap_pos = 0;
	}
	free(data);

	trace2_region_leave("midx", "midx_pack_order", ctx->repo);

	return pack_order;
}

static void write_midx_reverse_index(struct write_midx_context *ctx,
				     unsigned char *midx_hash)
{
	struct strbuf buf = STRBUF_INIT;
	char *tmp_file;

	trace2_region_enter("midx", "write_midx_reverse_index", ctx->repo);

	if (ctx->incremental)
		get_split_midx_filename_ext(ctx->source, &buf,
					    midx_hash, MIDX_EXT_REV);
	else
		get_midx_filename_ext(ctx->source, &buf,
				      midx_hash, MIDX_EXT_REV);

	tmp_file = write_rev_file_order(ctx->repo, NULL, ctx->pack_order,
					ctx->entries_nr, midx_hash, WRITE_REV);

	if (finalize_object_file(ctx->repo, tmp_file, buf.buf))
		die(_("cannot store reverse index file"));

	strbuf_release(&buf);
	free(tmp_file);

	trace2_region_leave("midx", "write_midx_reverse_index", ctx->repo);
}

static void prepare_midx_packing_data(struct packing_data *pdata,
				      struct write_midx_context *ctx)
{
	uint32_t i;

	trace2_region_enter("midx", "prepare_midx_packing_data", ctx->repo);

	memset(pdata, 0, sizeof(struct packing_data));
	prepare_packing_data(ctx->repo, pdata);

	for (i = 0; i < ctx->entries_nr; i++) {
		uint32_t pos = ctx->pack_order[i];
		struct pack_midx_entry *from = &ctx->entries[pos];
		struct object_entry *to = packlist_alloc(pdata, &from->oid);

		oe_set_in_pack(pdata, to,
			       ctx->info[midx_pack_perm(ctx, from->pack_int_id)].p);
	}

	trace2_region_leave("midx", "prepare_midx_packing_data", ctx->repo);
}

static int add_ref_to_pending(const struct reference *ref, void *cb_data)
{
	struct rev_info *revs = (struct rev_info*)cb_data;
	const struct object_id *maybe_peeled = ref->oid;
	struct object_id peeled;
	struct object *object;

	if ((ref->flags & REF_ISSYMREF) && (ref->flags & REF_ISBROKEN)) {
		warning("symbolic ref is dangling: %s", ref->name);
		return 0;
	}

	if (!reference_get_peeled_oid(revs->repo, ref, &peeled))
		maybe_peeled = &peeled;

	object = parse_object_or_die(revs->repo, maybe_peeled, ref->name);
	if (object->type != OBJ_COMMIT)
		return 0;

	add_pending_object(revs, object, "");
	if (bitmap_is_preferred_refname(revs->repo, ref->name))
		object->flags |= NEEDS_BITMAP;
	return 0;
}

struct bitmap_commit_cb {
	struct commit_stack *commits;
	struct write_midx_context *ctx;
};

static const struct object_id *bitmap_oid_access(size_t index,
						 const void *_entries)
{
	const struct pack_midx_entry *entries = _entries;
	return &entries[index].oid;
}

static void bitmap_show_commit(struct commit *commit, void *_data)
{
	struct bitmap_commit_cb *data = _data;
	int pos = oid_pos(&commit->object.oid, data->ctx->entries,
			  data->ctx->entries_nr,
			  bitmap_oid_access);
	if (pos < 0)
		return;

	commit_stack_push(data->commits, 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_algop(hex, &oid, &end, revs->repo->hash_algo) < 0)
			die(_("could not parse line: %s"), buf.buf);
		if (*end)
			die(_("malformed line: %s"), buf.buf);

		object = parse_object_or_die(revs->repo, &oid, NULL);
		if (preferred)
			object->flags |= NEEDS_BITMAP;

		add_pending_object(revs, object, "");
	}

	fclose(f);
	strbuf_release(&buf);
	return 0;
}

static void find_commits_for_midx_bitmap(struct commit_stack *commits,
					 const char *refs_snapshot,
					 struct write_midx_context *ctx)
{
	struct rev_info revs;
	struct bitmap_commit_cb cb = { .commits = commits, .ctx = ctx };

	trace2_region_enter("midx", "find_commits_for_midx_bitmap", ctx->repo);

	repo_init_revisions(ctx->repo, &revs, NULL);
	if (refs_snapshot) {
		read_refs_snapshot(refs_snapshot, &revs);
	} else {
		setup_revisions(0, NULL, &revs, NULL);
		refs_for_each_ref(get_main_ref_store(ctx->repo),
				  add_ref_to_pending, &revs);
	}

	/*
	 * Skipping promisor objects here is intentional, since it only excludes
	 * them from the list of reachable commits that we want to select from
	 * when computing the selection of MIDX'd commits to receive bitmaps.
	 *
	 * Reachability bitmaps do require that their objects be closed under
	 * reachability, but fetching any objects missing from promisors at this
	 * point is too late. But, if one of those objects can be reached from
	 * an another object that is included in the bitmap, then we will
	 * complain later that we don't have reachability closure (and fail
	 * appropriately).
	 */
	fetch_if_missing = 0;
	revs.exclude_promisor_objects = 1;

	if (prepare_revision_walk(&revs))
		die(_("revision walk setup failed"));

	traverse_commit_list(&revs, bitmap_show_commit, NULL, &cb);

	release_revisions(&revs);

	trace2_region_leave("midx", "find_commits_for_midx_bitmap", ctx->repo);
}

static int write_midx_bitmap(struct write_midx_context *ctx,
			     const unsigned char *midx_hash,
			     struct packing_data *pdata,
			     struct commit **commits,
			     uint32_t commits_nr,
			     unsigned flags)
{
	int ret;
	uint16_t options = 0;
	struct bitmap_writer writer;
	struct pack_idx_entry **index;
	struct strbuf bitmap_name = STRBUF_INIT;

	trace2_region_enter("midx", "write_midx_bitmap", ctx->repo);

	if (ctx->incremental)
		get_split_midx_filename_ext(ctx->source, &bitmap_name,
					    midx_hash, MIDX_EXT_BITMAP);
	else
		get_midx_filename_ext(ctx->source, &bitmap_name,
				      midx_hash, MIDX_EXT_BITMAP);

	if (flags & MIDX_WRITE_BITMAP_HASH_CACHE)
		options |= BITMAP_OPT_HASH_CACHE;

	if (flags & MIDX_WRITE_BITMAP_LOOKUP_TABLE)
		options |= BITMAP_OPT_LOOKUP_TABLE;

	/*
	 * Build the MIDX-order index based on pdata.objects (which is already
	 * in MIDX order; c.f., 'midx_pack_order_cmp()' for the definition of
	 * this order).
	 */
	ALLOC_ARRAY(index, pdata->nr_objects);
	for (uint32_t i = 0; i < pdata->nr_objects; i++)
		index[i] = &pdata->objects[i].idx;

	bitmap_writer_init(&writer, ctx->repo, pdata,
			   ctx->incremental ? ctx->base_midx : NULL);
	bitmap_writer_show_progress(&writer, flags & MIDX_PROGRESS);
	bitmap_writer_build_type_index(&writer, index);

	/*
	 * bitmap_writer_finish expects objects in lex order, but pack_order
	 * gives us exactly that. use it directly instead of re-sorting the
	 * array.
	 *
	 * This changes the order of objects in 'index' between
	 * bitmap_writer_build_type_index and bitmap_writer_finish.
	 *
	 * The same re-ordering takes place in the single-pack bitmap code via
	 * write_idx_file(), which is called by finish_tmp_packfile(), which
	 * happens between bitmap_writer_build_type_index() and
	 * bitmap_writer_finish().
	 */
	for (uint32_t i = 0; i < pdata->nr_objects; i++)
		index[ctx->pack_order[i]] = &pdata->objects[i].idx;

	bitmap_writer_select_commits(&writer, commits, commits_nr);
	ret = bitmap_writer_build(&writer);
	if (ret < 0)
		goto cleanup;

	bitmap_writer_set_checksum(&writer, midx_hash);
	bitmap_writer_finish(&writer, index, bitmap_name.buf, options);

cleanup:
	free(index);
	strbuf_release(&bitmap_name);
	bitmap_writer_free(&writer);

	trace2_region_leave("midx", "write_midx_bitmap", ctx->repo);

	return ret;
}

static int fill_pack_from_midx(struct pack_info *info,
			       struct multi_pack_index *m,
			       uint32_t pack_int_id)
{
	if (prepare_midx_pack(m, pack_int_id))
		return error(_("could not load pack %d"), pack_int_id);

	fill_pack_info(info,
		       m->packs[pack_int_id - m->num_packs_in_base],
		       m->pack_names[pack_int_id - m->num_packs_in_base],
		       pack_int_id);

	return 0;
}

static int fill_packs_from_midx(struct write_midx_context *ctx)
{
	struct multi_pack_index *m;

	for (m = ctx->m; m; m = m->base_midx) {
		uint32_t i;

		for (i = m->num_packs_in_base;
		     i < m->num_packs_in_base + m->num_packs; i++) {
			ALLOC_GROW(ctx->info, ctx->nr + 1, ctx->alloc);

			if (fill_pack_from_midx(&ctx->info[ctx->nr], m, i) < 0)
				return -1;

			ctx->nr++;
		}
	}
	return 0;
}

static uint32_t compactible_packs_between(const struct multi_pack_index *from,
					  const struct multi_pack_index *to)
{
	uint32_t nr;

	ASSERT(from && to);

	if (unsigned_add_overflows(to->num_packs, to->num_packs_in_base))
		die(_("too many packs, unable to compact"));

	nr = to->num_packs + to->num_packs_in_base;
	if (nr < from->num_packs_in_base)
		BUG("unexpected number of packs in base during compaction: "
		    "%"PRIu32" < %"PRIu32, nr, from->num_packs_in_base);

	return nr - from->num_packs_in_base;
}

static int fill_packs_from_midx_range(struct write_midx_context *ctx,
				      int bitmap_order)
{
	struct multi_pack_index *m = ctx->compact_to;
	uint32_t packs_nr;

	ASSERT(ctx->compact && !ctx->nr);
	ASSERT(ctx->compact_from);
	ASSERT(ctx->compact_to);

	packs_nr = compactible_packs_between(ctx->compact_from,
					     ctx->compact_to);

	ALLOC_GROW(ctx->info, packs_nr, ctx->alloc);

	while (m != ctx->compact_from->base_midx) {
		uint32_t pack_int_id, preferred_pack_id;
		uint32_t i;

		if (bitmap_order) {
			if (midx_preferred_pack(m, &preferred_pack_id) < 0)
				die(_("could not determine preferred pack"));
		} else {
			preferred_pack_id = m->num_packs_in_base;
		}

		pack_int_id = m->num_packs_in_base - ctx->compact_from->num_packs_in_base;

		if (fill_pack_from_midx(&ctx->info[pack_int_id++], m,
					preferred_pack_id) < 0)
			return -1;

		for (i = m->num_packs_in_base;
		     i < m->num_packs_in_base + m->num_packs; i++) {
			if (preferred_pack_id == i)
				continue;

			if (fill_pack_from_midx(&ctx->info[pack_int_id++], m,
						i) < 0)
				return -1;
		}

		ctx->nr += m->num_packs;
		m = m->base_midx;
	}

	ASSERT(ctx->nr == packs_nr);

	return 0;
}

static struct {
	const char *non_split;
	const char *split;
} midx_exts[] = {
	{NULL, MIDX_EXT_MIDX},
	{MIDX_EXT_BITMAP, MIDX_EXT_BITMAP},
	{MIDX_EXT_REV, MIDX_EXT_REV},
};

static int link_midx_to_chain(struct multi_pack_index *m)
{
	struct strbuf from = STRBUF_INIT;
	struct strbuf to = STRBUF_INIT;
	int ret = 0;
	size_t i;

	if (!m || m->has_chain) {
		/*
		 * Either no MIDX previously existed, or it was already
		 * part of a MIDX chain. In both cases, we have nothing
		 * to link, so return early.
		 */
		goto done;
	}

	for (i = 0; i < ARRAY_SIZE(midx_exts); i++) {
		const unsigned char *hash = midx_get_checksum_hash(m);

		get_midx_filename_ext(m->source, &from,
				      hash, midx_exts[i].non_split);
		get_split_midx_filename_ext(m->source, &to, hash,
					    midx_exts[i].split);

		if (link(from.buf, to.buf) < 0 && errno != ENOENT) {
			ret = error_errno(_("unable to link '%s' to '%s'"),
					  from.buf, to.buf);
			goto done;
		}

		strbuf_reset(&from);
		strbuf_reset(&to);
	}

done:
	strbuf_release(&from);
	strbuf_release(&to);
	return ret;
}

static void clear_midx_files(struct odb_source *source,
			     const char **hashes, uint32_t hashes_nr,
			     unsigned incremental)
{
	/*
	 * if incremental:
	 *   - remove all non-incremental MIDX files
	 *   - remove any incremental MIDX files not in the current one
	 *
	 * if non-incremental:
	 *   - remove all incremental MIDX files
	 *   - remove any non-incremental MIDX files not matching the current
	 *     hash
	 */
	struct strbuf buf = STRBUF_INIT;
	const char *exts[] = { MIDX_EXT_BITMAP, MIDX_EXT_REV, MIDX_EXT_MIDX };
	uint32_t i, j;

	for (i = 0; i < ARRAY_SIZE(exts); i++) {
		clear_incremental_midx_files_ext(source, exts[i],
						 hashes, hashes_nr);
		for (j = 0; j < hashes_nr; j++)
			clear_midx_files_ext(source, exts[i], hashes[j]);
	}

	if (incremental)
		get_midx_filename(source, &buf);
	else
		get_midx_chain_filename(source, &buf);

	if (unlink(buf.buf) && errno != ENOENT)
		die_errno(_("failed to clear multi-pack-index at %s"), buf.buf);

	strbuf_release(&buf);
}

static bool midx_needs_update(struct multi_pack_index *midx, struct write_midx_context *ctx)
{
	struct strset packs = STRSET_INIT;
	struct strbuf buf = STRBUF_INIT;
	bool needed = true;

	/*
	 * Ensure that we have a valid checksum before consulting the
	 * exisiting MIDX in order to determine if we can avoid an
	 * update.
	 *
	 * This is necessary because the given MIDX is loaded directly
	 * from the object store (because we still compare our proposed
	 * update to any on-disk MIDX regardless of whether or not we
	 * have assigned "ctx.m") and is thus not guaranteed to have a
	 * valid checksum.
	 */
	if (!midx_checksum_valid(midx))
		goto out;

	/*
	 * If the version differs, we need to update.
	 */
	if (midx->version != ctx->version)
		goto out;

	/*
	 * Ignore incremental updates for now. The assumption is that any
	 * incremental update would be either empty (in which case we will bail
	 * out later) or it would actually cover at least one new pack.
	 */
	if (ctx->incremental)
		goto out;

	if (ctx->compact)
		goto out; /* Compaction always requires an update. */

	/*
	 * Otherwise, we need to verify that the packs covered by the existing
	 * MIDX match the packs that we already have. The logic to do so is way
	 * more complicated than it has any right to be. This is because:
	 *
	 *   - We cannot assume any ordering.
	 *
	 *   - The MIDX packs may not be loaded at all, and loading them would
	 *     be wasteful. So we need to use the pack names tracked by the
	 *     MIDX itself.
	 *
	 *   - The MIDX pack names are tracking the ".idx" files, whereas the
	 *     packs themselves are tracking the ".pack" files. So we need to
	 *     strip suffixes.
	 */
	if (ctx->nr != midx->num_packs + midx->num_packs_in_base)
		goto out;

	for (uint32_t i = 0; i < ctx->nr; i++) {
		strbuf_reset(&buf);
		strbuf_addstr(&buf, pack_basename(ctx->info[i].p));
		strbuf_strip_suffix(&buf, ".pack");

		if (!strset_add(&packs, buf.buf))
			BUG("same pack added twice?");
	}

	for (uint32_t i = 0; i < ctx->nr; i++) {
		strbuf_reset(&buf);
		strbuf_addstr(&buf, midx->pack_names[i]);
		strbuf_strip_suffix(&buf, ".idx");

		if (!strset_contains(&packs, buf.buf))
			goto out;
		strset_remove(&packs, buf.buf);
	}

	needed = false;

out:
	strbuf_release(&buf);
	strset_clear(&packs);
	return needed;
}

static int midx_hashcmp(const struct multi_pack_index *a,
			const struct multi_pack_index *b,
			const struct git_hash_algo *algop)
{
	return hashcmp(midx_get_checksum_hash(a), midx_get_checksum_hash(b),
		       algop);
}

struct write_midx_opts {
	struct odb_source *source; /* non-optional */

	struct string_list *packs_to_include;
	struct string_list *packs_to_drop;

	struct multi_pack_index *compact_from;
	struct multi_pack_index *compact_to;

	const char *preferred_pack_name;
	const char *refs_snapshot;
	unsigned flags;
};

static int write_midx_internal(struct write_midx_opts *opts)
{
	struct repository *r = opts->source->odb->repo;
	struct strbuf midx_name = STRBUF_INIT;
	unsigned char midx_hash[GIT_MAX_RAWSZ];
	uint32_t start_pack;
	struct hashfile *f = NULL;
	struct lock_file lk;
	struct tempfile *incr;
	struct write_midx_context ctx = {
		.preferred_pack_idx = NO_PREFERRED_PACK,
		.version = MIDX_VERSION_V2,
	 };
	struct multi_pack_index *midx_to_free = NULL;
	int bitmapped_packs_concat_len = 0;
	int pack_name_concat_len = 0;
	int dropped_packs = 0;
	int result = -1;
	const char **keep_hashes = NULL;
	size_t keep_hashes_nr = 0;
	struct chunkfile *cf;

	trace2_region_enter("midx", "write_midx_internal", r);

	ctx.repo = r;
	ctx.source = opts->source;

	repo_config_get_int(ctx.repo, "midx.version", &ctx.version);
	if (ctx.version != MIDX_VERSION_V1 && ctx.version != MIDX_VERSION_V2)
		die(_("unknown MIDX version: %d"), ctx.version);

	ctx.incremental = !!(opts->flags & MIDX_WRITE_INCREMENTAL);
	ctx.compact = !!(opts->flags & MIDX_WRITE_COMPACT);

	if (ctx.compact) {
		if (ctx.version != MIDX_VERSION_V2)
			die(_("cannot perform MIDX compaction with v1 format"));
		if (!opts->compact_from)
			BUG("expected non-NULL 'from' MIDX during compaction");
		if (!opts->compact_to)
			BUG("expected non-NULL 'to' MIDX during compaction");

		ctx.compact_from = opts->compact_from;
		ctx.compact_to = opts->compact_to;
	}

	if (ctx.incremental)
		strbuf_addf(&midx_name,
			    "%s/pack/multi-pack-index.d/tmp_midx_XXXXXX",
			    opts->source->path);
	else
		get_midx_filename(opts->source, &midx_name);
	if (safe_create_leading_directories(r, midx_name.buf))
		die_errno(_("unable to create leading directories of %s"),
			  midx_name.buf);

	if (!opts->packs_to_include || ctx.incremental) {
		struct multi_pack_index *m = get_multi_pack_index(opts->source);
		if (m && !midx_checksum_valid(m)) {
			warning(_("ignoring existing multi-pack-index; checksum mismatch"));
			m = NULL;
		}

		if (m) {
			/*
			 * 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.
			 */
			if (ctx.incremental)
				ctx.base_midx = m;
			if (!opts->packs_to_include)
				ctx.m = m;
		}
	}

	/*
	 * If compacting MIDX layer(s) in the range [from, to], then the
	 * compacted MIDX will share the same base MIDX as 'from'.
	 */
	if (ctx.compact)
		ctx.base_midx = ctx.compact_from->base_midx;

	ctx.nr = 0;
	ctx.alloc = ctx.m ? ctx.m->num_packs + ctx.m->num_packs_in_base : 16;
	ctx.info = NULL;
	ALLOC_ARRAY(ctx.info, ctx.alloc);

	if (ctx.incremental) {
		struct multi_pack_index *m = ctx.base_midx;
		while (m) {
			if (opts->flags & MIDX_WRITE_BITMAP && load_midx_revindex(m)) {
				error(_("could not load reverse index for MIDX %s"),
				      midx_get_checksum_hex(m));
				goto cleanup;
			}
			ctx.num_multi_pack_indexes_before++;
			m = m->base_midx;
		}
	} else if (ctx.m && !ctx.compact && fill_packs_from_midx(&ctx)) {
		goto cleanup;
	}

	start_pack = ctx.nr;

	ctx.pack_paths_checked = 0;
	if (opts->flags & MIDX_PROGRESS)
		ctx.progress = start_delayed_progress(r,
						      _("Adding packfiles to multi-pack-index"), 0);
	else
		ctx.progress = NULL;

	if (ctx.compact) {
		int bitmap_order = 0;
		if (opts->preferred_pack_name)
			bitmap_order |= 1;
		else if (opts->flags & (MIDX_WRITE_REV_INDEX | MIDX_WRITE_BITMAP))
			bitmap_order |= 1;

		fill_packs_from_midx_range(&ctx, bitmap_order);
	} else {
		ctx.to_include = opts->packs_to_include;
		for_each_file_in_pack_dir(opts->source->path, add_pack_to_midx, &ctx);
	}
	stop_progress(&ctx.progress);

	if (!opts->packs_to_drop) {
		/*
		 * If there is no MIDX then either it doesn't exist, or we're
		 * doing a geometric repack. Try to load it from the source to
		 * tell these two cases apart.
		 */
		struct multi_pack_index *midx = ctx.m;
		if (!midx)
			midx = midx_to_free = load_multi_pack_index(ctx.source);

		if (midx && !midx_needs_update(midx, &ctx)) {
			struct bitmap_index *bitmap_git;
			int bitmap_exists;
			int want_bitmap = opts->flags & MIDX_WRITE_BITMAP;

			bitmap_git = prepare_midx_bitmap_git(midx);
			bitmap_exists = bitmap_git && bitmap_is_midx(bitmap_git);
			free_bitmap_index(bitmap_git);

			if (bitmap_exists || !want_bitmap) {
				/*
				 * The correct MIDX already exists, and so does a
				 * corresponding bitmap (or one wasn't requested).
				 */
				if (!want_bitmap)
					clear_midx_files_ext(ctx.source, "bitmap", NULL);
				result = 0;
				goto cleanup;
			}
		}

		close_midx(midx_to_free);
		midx_to_free = NULL;
	}

	if (ctx.incremental && !ctx.nr) {
		result = 0;
		goto cleanup; /* nothing to do */
	}

	if (opts->preferred_pack_name) {
		ctx.preferred_pack_idx = NO_PREFERRED_PACK;

		for (size_t i = 0; i < ctx.nr; i++) {
			if (!cmp_idx_or_pack_name(opts->preferred_pack_name,
						  ctx.info[i].pack_name)) {
				ctx.preferred_pack_idx = i;
				break;
			}
		}

		if (ctx.preferred_pack_idx == NO_PREFERRED_PACK)
			warning(_("unknown preferred pack: '%s'"),
				opts->preferred_pack_name);
	} else if (ctx.nr &&
		   (opts->flags & (MIDX_WRITE_REV_INDEX | MIDX_WRITE_BITMAP))) {
		struct packed_git *oldest = ctx.info[0].p;
		ctx.preferred_pack_idx = 0;

		/*
		 * Attempt opening the pack index to populate num_objects.
		 * Ignore failiures as they can be expected and are not
		 * fatal during this selection time.
		 */
		open_pack_index(oldest);

		if (opts->packs_to_drop && opts->packs_to_drop->nr)
			BUG("cannot write a MIDX bitmap during expiration");

		/*
		 * set a preferred pack when writing a bitmap to ensure that
		 * the pack from which the first object is selected in pseudo
		 * pack-order has all of its objects selected from that pack
		 * (and not another pack containing a duplicate)
		 */
		for (size_t i = 1; i < ctx.nr; i++) {
			struct packed_git *p = ctx.info[i].p;

			if (!oldest->num_objects || p->mtime < oldest->mtime) {
				oldest = p;
				open_pack_index(oldest);
				ctx.preferred_pack_idx = i;
			}
		}

		if (!oldest->num_objects) {
			/*
			 * If all packs are empty; unset the preferred index.
			 * This is acceptable since there will be no duplicate
			 * objects to resolve, so the preferred value doesn't
			 * matter.
			 */
			ctx.preferred_pack_idx = NO_PREFERRED_PACK;
		}
	} else {
		/*
		 * otherwise don't mark any pack as preferred to avoid
		 * interfering with expiration logic below
		 */
		ctx.preferred_pack_idx = NO_PREFERRED_PACK;
	}

	if (ctx.preferred_pack_idx != NO_PREFERRED_PACK) {
		struct packed_git *preferred = ctx.info[ctx.preferred_pack_idx].p;

		if (open_pack_index(preferred))
			die(_("failed to open preferred pack %s"),
			    ctx.info[ctx.preferred_pack_idx].pack_name);

		if (!preferred->num_objects) {
			error(_("cannot select preferred pack %s with no objects"),
			      preferred->pack_name);
			goto cleanup;
		}
	}

	compute_sorted_entries(&ctx, start_pack);

	ctx.large_offsets_needed = 0;
	for (size_t i = 0; i < ctx.entries_nr; i++) {
		if (ctx.entries[i].offset > 0x7fffffff)
			ctx.num_large_offsets++;
		if (ctx.entries[i].offset > 0xffffffff)
			ctx.large_offsets_needed = 1;
	}

	if (ctx.compact) {
		if (ctx.version != MIDX_VERSION_V2)
			BUG("performing MIDX compaction with v1 MIDX");
	} else {
		QSORT(ctx.info, ctx.nr, pack_info_compare);
	}

	if (opts->packs_to_drop && opts->packs_to_drop->nr) {
		size_t drop_index = 0;
		int missing_drops = 0;

		ASSERT(!ctx.compact);

		for (size_t i = 0;
		     i < ctx.nr && drop_index < opts->packs_to_drop->nr; i++) {
			int cmp = strcmp(ctx.info[i].pack_name,
					 opts->packs_to_drop->items[drop_index].string);

			if (!cmp) {
				drop_index++;
				ctx.info[i].expired = 1;
			} else if (cmp > 0) {
				error(_("did not see pack-file %s to drop"),
				      opts->packs_to_drop->items[drop_index].string);
				drop_index++;
				missing_drops++;
				i--;
			} else {
				ctx.info[i].expired = 0;
			}
		}

		if (missing_drops)
			goto cleanup;
	}

	/*
	 * pack_perm stores a permutation between pack-int-ids from the
	 * previous multi-pack-index to the new one we are writing:
	 *
	 * pack_perm[old_id] = new_id
	 */
	ALLOC_ARRAY(ctx.pack_perm, ctx.nr);
	for (size_t i = 0; i < ctx.nr; i++) {
		uint32_t from = ctx.info[i].orig_pack_int_id;
		uint32_t to;

		if (ctx.info[i].expired) {
			to = PACK_EXPIRED;
			dropped_packs++;
		} else {
			to = i - dropped_packs;
		}

		if (ctx.compact)
			from -= ctx.compact_from->num_packs_in_base;

		ctx.pack_perm[from] = to;
	}

	for (size_t i = 0; i < ctx.nr; i++) {
		if (ctx.info[i].expired)
			continue;
		pack_name_concat_len += strlen(ctx.info[i].pack_name) + 1;
		bitmapped_packs_concat_len += 2 * sizeof(uint32_t);
	}

	/* Check that the preferred pack wasn't expired (if given). */
	if (opts->preferred_pack_name) {
		struct pack_info *preferred = bsearch(opts->preferred_pack_name,
						      ctx.info, ctx.nr,
						      sizeof(*ctx.info),
						      idx_or_pack_name_cmp);
		if (preferred) {
			uint32_t perm = midx_pack_perm(&ctx, preferred->orig_pack_int_id);
			if (perm == PACK_EXPIRED)
				warning(_("preferred pack '%s' is expired"),
					opts->preferred_pack_name);
		}
	}

	if (pack_name_concat_len % MIDX_CHUNK_ALIGNMENT)
		pack_name_concat_len += MIDX_CHUNK_ALIGNMENT -
					(pack_name_concat_len % MIDX_CHUNK_ALIGNMENT);

	if (ctx.nr - dropped_packs == 0) {
		error(_("no pack files to index."));
		goto cleanup;
	}

	if (!ctx.entries_nr) {
		if (opts->flags & MIDX_WRITE_BITMAP)
			warning(_("refusing to write multi-pack .bitmap without any objects"));
		opts->flags &= ~(MIDX_WRITE_REV_INDEX | MIDX_WRITE_BITMAP);
	}

	if (ctx.incremental) {
		struct strbuf lock_name = STRBUF_INIT;

		get_midx_chain_filename(opts->source, &lock_name);
		hold_lock_file_for_update(&lk, lock_name.buf, LOCK_DIE_ON_ERROR);
		strbuf_release(&lock_name);

		incr = mks_tempfile_m(midx_name.buf, 0444);
		if (!incr) {
			error(_("unable to create temporary MIDX layer"));
			goto cleanup;
		}

		if (adjust_shared_perm(r, get_tempfile_path(incr))) {
			error(_("unable to adjust shared permissions for '%s'"),
			      get_tempfile_path(incr));
			goto cleanup;
		}

		f = hashfd(r->hash_algo, get_tempfile_fd(incr),
			   get_tempfile_path(incr));
	} else {
		hold_lock_file_for_update(&lk, midx_name.buf, LOCK_DIE_ON_ERROR);
		f = hashfd(r->hash_algo, get_lock_file_fd(&lk),
			   get_lock_file_path(&lk));
	}

	cf = init_chunkfile(f);

	add_chunk(cf, MIDX_CHUNKID_PACKNAMES, pack_name_concat_len,
		  write_midx_pack_names);
	add_chunk(cf, MIDX_CHUNKID_OIDFANOUT, MIDX_CHUNK_FANOUT_SIZE,
		  write_midx_oid_fanout);
	add_chunk(cf, MIDX_CHUNKID_OIDLOOKUP,
		  st_mult(ctx.entries_nr, r->hash_algo->rawsz),
		  write_midx_oid_lookup);
	add_chunk(cf, MIDX_CHUNKID_OBJECTOFFSETS,
		  st_mult(ctx.entries_nr, MIDX_CHUNK_OFFSET_WIDTH),
		  write_midx_object_offsets);

	if (ctx.large_offsets_needed)
		add_chunk(cf, MIDX_CHUNKID_LARGEOFFSETS,
			st_mult(ctx.num_large_offsets,
				MIDX_CHUNK_LARGE_OFFSET_WIDTH),
			write_midx_large_offsets);

	if (opts->flags & (MIDX_WRITE_REV_INDEX | MIDX_WRITE_BITMAP)) {
		ctx.pack_order = midx_pack_order(&ctx);
		add_chunk(cf, MIDX_CHUNKID_REVINDEX,
			  st_mult(ctx.entries_nr, sizeof(uint32_t)),
			  write_midx_revindex);
		add_chunk(cf, MIDX_CHUNKID_BITMAPPEDPACKS,
			  bitmapped_packs_concat_len,
			  write_midx_bitmapped_packs);
	}

	write_midx_header(r->hash_algo, f, get_num_chunks(cf),
			  ctx.nr - dropped_packs, ctx.version);
	write_chunkfile(cf, &ctx);

	finalize_hashfile(f, midx_hash, FSYNC_COMPONENT_PACK_METADATA,
			  CSUM_FSYNC | CSUM_HASH_IN_STREAM);
	free_chunkfile(cf);

	if (opts->flags & MIDX_WRITE_REV_INDEX &&
	    git_env_bool("GIT_TEST_MIDX_WRITE_REV", 0))
		write_midx_reverse_index(&ctx, midx_hash);

	if (opts->flags & MIDX_WRITE_BITMAP) {
		struct packing_data pdata;
		struct commit_stack commits = COMMIT_STACK_INIT;

		if (!ctx.entries_nr)
			BUG("cannot write a bitmap without any objects");

		prepare_midx_packing_data(&pdata, &ctx);

		find_commits_for_midx_bitmap(&commits, opts->refs_snapshot, &ctx);

		/*
		 * The previous steps translated the information from
		 * 'entries' into information suitable for constructing
		 * bitmaps. We no longer need that array, so clear it to
		 * reduce memory pressure.
		 */
		FREE_AND_NULL(ctx.entries);
		ctx.entries_nr = 0;

		if (write_midx_bitmap(&ctx, midx_hash, &pdata, commits.items,
				      commits.nr, opts->flags) < 0) {
			error(_("could not write multi-pack bitmap"));
			clear_packing_data(&pdata);
			commit_stack_clear(&commits);
			goto cleanup;
		}

		clear_packing_data(&pdata);
		commit_stack_clear(&commits);
	}
	/*
	 * NOTE: Do not use ctx.entries beyond this point, since it might
	 * have been freed in the previous if block.
	 */

	if (ctx.num_multi_pack_indexes_before == UINT32_MAX)
		die(_("too many multi-pack-indexes"));

	if (ctx.compact) {
		struct multi_pack_index *m;

		/*
		 * Keep all MIDX layers excluding those in the range [from, to].
		 */
		for (m = ctx.base_midx; m; m = m->base_midx)
			keep_hashes_nr++;
		for (m = ctx.m;
		     m && midx_hashcmp(m, ctx.compact_to, r->hash_algo);
		     m = m->base_midx)
			keep_hashes_nr++;

		keep_hashes_nr++; /* include the compacted layer */
	} else {
		keep_hashes_nr = ctx.num_multi_pack_indexes_before + 1;
	}
	CALLOC_ARRAY(keep_hashes, keep_hashes_nr);

	if (ctx.incremental) {
		FILE *chainf = fdopen_lock_file(&lk, "w");
		struct strbuf final_midx_name = STRBUF_INIT;
		struct multi_pack_index *m = ctx.base_midx;

		if (!chainf) {
			error_errno(_("unable to open multi-pack-index chain file"));
			goto cleanup;
		}

		if (link_midx_to_chain(ctx.base_midx) < 0)
			goto cleanup;

		get_split_midx_filename_ext(opts->source, &final_midx_name,
					    midx_hash, MIDX_EXT_MIDX);

		if (rename_tempfile(&incr, final_midx_name.buf) < 0) {
			error_errno(_("unable to rename new multi-pack-index layer"));
			goto cleanup;
		}

		strbuf_release(&final_midx_name);

		if (ctx.compact) {
			struct multi_pack_index *m;
			uint32_t num_layers_before_from = 0;
			uint32_t i;

			for (m = ctx.base_midx; m; m = m->base_midx)
				num_layers_before_from++;

			m = ctx.base_midx;
			for (i = 0; i < num_layers_before_from; i++) {
				uint32_t j = num_layers_before_from - i - 1;

				keep_hashes[j] = xstrdup(midx_get_checksum_hex(m));
				m = m->base_midx;
			}

			keep_hashes[i] = xstrdup(hash_to_hex_algop(midx_hash,
								   r->hash_algo));

			i = 0;
			for (m = ctx.m;
			     m && midx_hashcmp(m, ctx.compact_to, r->hash_algo);
			     m = m->base_midx) {
				keep_hashes[keep_hashes_nr - i - 1] =
					xstrdup(midx_get_checksum_hex(m));
				i++;
			}
		} else {
			keep_hashes[ctx.num_multi_pack_indexes_before] =
				xstrdup(hash_to_hex_algop(midx_hash,
							  r->hash_algo));

			for (uint32_t i = 0; i < ctx.num_multi_pack_indexes_before; i++) {
				uint32_t j = ctx.num_multi_pack_indexes_before - i - 1;

				keep_hashes[j] = xstrdup(midx_get_checksum_hex(m));
				m = m->base_midx;
			}
		}

		for (uint32_t i = 0; i < keep_hashes_nr; i++)
			fprintf(get_lock_file_fp(&lk), "%s\n", keep_hashes[i]);
	} else {
		keep_hashes[ctx.num_multi_pack_indexes_before] =
			xstrdup(hash_to_hex_algop(midx_hash, r->hash_algo));
	}

	if (ctx.m || ctx.base_midx)
		odb_close(ctx.repo->objects);

	if (commit_lock_file(&lk) < 0)
		die_errno(_("could not write multi-pack-index"));

	clear_midx_files(opts->source, keep_hashes, keep_hashes_nr,
			 ctx.incremental);
	result = 0;

cleanup:
	for (size_t i = 0; i < ctx.nr; i++) {
		if (ctx.info[i].p) {
			close_pack(ctx.info[i].p);
			free(ctx.info[i].p);
		}
		free(ctx.info[i].pack_name);
	}

	free(ctx.info);
	free(ctx.entries);
	free(ctx.pack_perm);
	free(ctx.pack_order);
	if (keep_hashes) {
		for (uint32_t i = 0; i < keep_hashes_nr; i++)
			free((char *)keep_hashes[i]);
		free(keep_hashes);
	}
	strbuf_release(&midx_name);
	close_midx(midx_to_free);

	trace2_region_leave("midx", "write_midx_internal", r);

	return result;
}

int write_midx_file(struct odb_source *source,
		    const char *preferred_pack_name,
		    const char *refs_snapshot, unsigned flags)
{
	struct write_midx_opts opts = {
		.source = source,
		.preferred_pack_name = preferred_pack_name,
		.refs_snapshot = refs_snapshot,
		.flags = flags,
	};

	return write_midx_internal(&opts);
}

int write_midx_file_only(struct odb_source *source,
			 struct string_list *packs_to_include,
			 const char *preferred_pack_name,
			 const char *refs_snapshot, unsigned flags)
{
	struct write_midx_opts opts = {
		.source = source,
		.packs_to_include = packs_to_include,
		.preferred_pack_name = preferred_pack_name,
		.refs_snapshot = refs_snapshot,
		.flags = flags,
	};

	return write_midx_internal(&opts);
}

int write_midx_file_compact(struct odb_source *source,
			    struct multi_pack_index *from,
			    struct multi_pack_index *to,
			    unsigned flags)
{
	struct write_midx_opts opts = {
		.source = source,
		.compact_from = from,
		.compact_to = to,
		.flags = flags | MIDX_WRITE_COMPACT,
	};

	return write_midx_internal(&opts);
}

int expire_midx_packs(struct odb_source *source, unsigned flags)
{
	uint32_t i, *count, result = 0;
	struct string_list packs_to_drop = STRING_LIST_INIT_DUP;
	struct multi_pack_index *m = get_multi_pack_index(source);
	struct progress *progress = NULL;

	if (!m)
		return 0;

	if (m->base_midx)
		die(_("cannot expire packs from an incremental multi-pack-index"));

	CALLOC_ARRAY(count, m->num_packs);

	if (flags & MIDX_PROGRESS)
		progress = start_delayed_progress(
					  source->odb->repo,
					  _("Counting referenced objects"),
					  m->num_objects);
	for (i = 0; i < m->num_objects; i++) {
		uint32_t pack_int_id = nth_midxed_pack_int_id(m, i);
		count[pack_int_id]++;
		display_progress(progress, i + 1);
	}
	stop_progress(&progress);

	if (flags & MIDX_PROGRESS)
		progress = start_delayed_progress(
					  source->odb->repo,
					  _("Finding and deleting unreferenced packfiles"),
					  m->num_packs);
	for (i = 0; i < m->num_packs; i++) {
		char *pack_name;
		display_progress(progress, i + 1);

		if (count[i])
			continue;

		if (prepare_midx_pack(m, i))
			continue;

		if (m->packs[i]->pack_keep || m->packs[i]->is_cruft)
			continue;

		pack_name = xstrdup(m->packs[i]->pack_name);
		close_pack(m->packs[i]);

		string_list_insert(&packs_to_drop, m->pack_names[i]);
		unlink_pack_path(pack_name, 0);
		free(pack_name);
	}
	stop_progress(&progress);

	free(count);

	if (packs_to_drop.nr) {
		struct write_midx_opts opts = {
			.source = source,
			.packs_to_drop = &packs_to_drop,
			.flags = flags & MIDX_PROGRESS,
		};
		result = write_midx_internal(&opts);
	}

	string_list_clear(&packs_to_drop, 0);

	return result;
}

struct repack_info {
	timestamp_t mtime;
	uint32_t referenced_objects;
	uint32_t pack_int_id;
};

static int compare_by_mtime(const void *a_, const void *b_)
{
	const struct repack_info *a, *b;

	a = (const struct repack_info *)a_;
	b = (const struct repack_info *)b_;

	if (a->mtime < b->mtime)
		return -1;
	if (a->mtime > b->mtime)
		return 1;
	return 0;
}

static int want_included_pack(struct multi_pack_index *m,
			      int pack_kept_objects,
			      uint32_t pack_int_id)
{
	struct packed_git *p;
	if (prepare_midx_pack(m, pack_int_id))
		return 0;
	p = m->packs[pack_int_id];
	if (!pack_kept_objects && p->pack_keep)
		return 0;
	if (p->is_cruft)
		return 0;
	if (open_pack_index(p) || !p->num_objects)
		return 0;
	return 1;
}

static void fill_included_packs_all(struct repository *r,
				    struct multi_pack_index *m,
				    unsigned char *include_pack)
{
	uint32_t i;
	int pack_kept_objects = 0;

	repo_config_get_bool(r, "repack.packkeptobjects", &pack_kept_objects);

	for (i = 0; i < m->num_packs; i++) {
		if (!want_included_pack(m, pack_kept_objects, i))
			continue;

		include_pack[i] = 1;
	}
}

static void fill_included_packs_batch(struct repository *r,
				      struct multi_pack_index *m,
				      unsigned char *include_pack,
				      size_t batch_size)
{
	uint32_t i;
	size_t total_size;
	struct repack_info *pack_info;
	int pack_kept_objects = 0;

	CALLOC_ARRAY(pack_info, m->num_packs);

	repo_config_get_bool(r, "repack.packkeptobjects", &pack_kept_objects);

	for (i = 0; i < m->num_packs; i++) {
		pack_info[i].pack_int_id = i;

		if (prepare_midx_pack(m, i))
			continue;

		pack_info[i].mtime = m->packs[i]->mtime;
	}

	for (i = 0; i < m->num_objects; i++) {
		uint32_t pack_int_id = nth_midxed_pack_int_id(m, i);
		pack_info[pack_int_id].referenced_objects++;
	}

	QSORT(pack_info, m->num_packs, compare_by_mtime);

	total_size = 0;
	for (i = 0; total_size < batch_size && i < m->num_packs; i++) {
		uint32_t pack_int_id = pack_info[i].pack_int_id;
		struct packed_git *p = m->packs[pack_int_id];
		uint64_t expected_size;

		if (!want_included_pack(m, pack_kept_objects, pack_int_id))
			continue;

		/*
		 * Use shifted integer arithmetic to calculate the
		 * expected pack size to ~4 significant digits without
		 * overflow for packsizes less that 1PB.
		 */
		expected_size = (uint64_t)pack_info[i].referenced_objects << 14;
		expected_size /= p->num_objects;
		expected_size = u64_mult(expected_size, p->pack_size);
		expected_size = u64_add(expected_size, 1u << 13) >> 14;

		if (expected_size >= batch_size)
			continue;

		if (unsigned_add_overflows(total_size, (size_t)expected_size))
			total_size = SIZE_MAX;
		else
			total_size += expected_size;

		include_pack[pack_int_id] = 1;
	}

	free(pack_info);
}

int midx_repack(struct odb_source *source, size_t batch_size, unsigned flags)
{
	struct repository *r = source->odb->repo;
	int result = 0;
	uint32_t i, packs_to_repack = 0;
	unsigned char *include_pack;
	struct child_process cmd = CHILD_PROCESS_INIT;
	FILE *cmd_in;
	struct multi_pack_index *m = get_multi_pack_index(source);
	struct write_midx_opts opts = {
		.source = source,
		.flags = flags,
	};

	/*
	 * When updating the default for these configuration
	 * variables in builtin/repack.c, these must be adjusted
	 * to match.
	 */
	int delta_base_offset = 1;
	int use_delta_islands = 0;

	if (!m)
		return 0;
	if (m->base_midx)
		die(_("cannot repack an incremental multi-pack-index"));

	CALLOC_ARRAY(include_pack, m->num_packs);

	if (batch_size)
		fill_included_packs_batch(r, m, include_pack, batch_size);
	else
		fill_included_packs_all(r, m, include_pack);

	for (i = 0; i < m->num_packs; i++) {
		if (include_pack[i])
			packs_to_repack++;
	}
	if (packs_to_repack <= 1)
		goto cleanup;

	repo_config_get_bool(r, "repack.usedeltabaseoffset", &delta_base_offset);
	repo_config_get_bool(r, "repack.usedeltaislands", &use_delta_islands);

	strvec_push(&cmd.args, "pack-objects");

	strvec_pushf(&cmd.args, "%s/pack/pack", source->path);

	if (delta_base_offset)
		strvec_push(&cmd.args, "--delta-base-offset");
	if (use_delta_islands)
		strvec_push(&cmd.args, "--delta-islands");

	if (flags & MIDX_PROGRESS)
		strvec_push(&cmd.args, "--progress");
	else
		strvec_push(&cmd.args, "-q");

	cmd.git_cmd = 1;
	cmd.in = cmd.out = -1;

	if (start_command(&cmd)) {
		error(_("could not start pack-objects"));
		result = 1;
		goto cleanup;
	}

	cmd_in = xfdopen(cmd.in, "w");

	for (i = 0; i < m->num_objects; i++) {
		struct object_id oid;
		uint32_t pack_int_id = nth_midxed_pack_int_id(m, i);

		if (!include_pack[pack_int_id])
			continue;

		nth_midxed_object_oid(&oid, m, i);
		fprintf(cmd_in, "%s\n", oid_to_hex(&oid));
	}
	fclose(cmd_in);

	if (finish_command(&cmd)) {
		error(_("could not finish pack-objects"));
		result = 1;
		goto cleanup;
	}

	result = write_midx_internal(&opts);

cleanup:
	free(include_pack);
	return result;
}
