#define DISABLE_SIGN_COMPARE_WARNINGS

#include "git-compat-util.h"
#include "config.h"
#include "csum-file.h"
#include "environment.h"
#include "gettext.h"
#include "hex.h"
#include "lockfile.h"
#include "packfile.h"
#include "commit.h"
#include "object.h"
#include "refs.h"
#include "hash-lookup.h"
#include "commit-graph.h"
#include "odb.h"
#include "oid-array.h"
#include "path.h"
#include "alloc.h"
#include "hashmap.h"
#include "replace-object.h"
#include "progress.h"
#include "bloom.h"
#include "commit-slab.h"
#include "shallow.h"
#include "json-writer.h"
#include "trace2.h"
#include "tree.h"
#include "chunk-format.h"

void git_test_write_commit_graph_or_die(struct odb_source *source)
{
	int flags = 0;
	if (!git_env_bool(GIT_TEST_COMMIT_GRAPH, 0))
		return;

	if (git_env_bool(GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS, 0))
		flags = COMMIT_GRAPH_WRITE_BLOOM_FILTERS;

	if (write_commit_graph_reachable(source, flags, NULL))
		die("failed to write commit-graph under GIT_TEST_COMMIT_GRAPH");
}

#define GRAPH_SIGNATURE 0x43475048 /* "CGPH" */
#define GRAPH_CHUNKID_OIDFANOUT 0x4f494446 /* "OIDF" */
#define GRAPH_CHUNKID_OIDLOOKUP 0x4f49444c /* "OIDL" */
#define GRAPH_CHUNKID_DATA 0x43444154 /* "CDAT" */
#define GRAPH_CHUNKID_GENERATION_DATA 0x47444132 /* "GDA2" */
#define GRAPH_CHUNKID_GENERATION_DATA_OVERFLOW 0x47444f32 /* "GDO2" */
#define GRAPH_CHUNKID_EXTRAEDGES 0x45444745 /* "EDGE" */
#define GRAPH_CHUNKID_BLOOMINDEXES 0x42494458 /* "BIDX" */
#define GRAPH_CHUNKID_BLOOMDATA 0x42444154 /* "BDAT" */
#define GRAPH_CHUNKID_BASE 0x42415345 /* "BASE" */

#define GRAPH_VERSION_1 0x1
#define GRAPH_VERSION GRAPH_VERSION_1

#define GRAPH_EXTRA_EDGES_NEEDED 0x80000000
#define GRAPH_EDGE_LAST_MASK 0x7fffffff
#define GRAPH_PARENT_NONE 0x70000000

#define GRAPH_LAST_EDGE 0x80000000

#define GRAPH_HEADER_SIZE 8
#define GRAPH_FANOUT_SIZE (4 * 256)

#define CORRECTED_COMMIT_DATE_OFFSET_OVERFLOW (1ULL << 31)

/* Remember to update object flag allocation in object.h */
#define REACHABLE       (1u<<15)

define_commit_slab(topo_level_slab, uint32_t);

/* Keep track of the order in which commits are added to our list. */
define_commit_slab(commit_pos, int);
static struct commit_pos commit_pos = COMMIT_SLAB_INIT(1, commit_pos);

static size_t graph_data_width(const struct git_hash_algo *algop)
{
	return algop->rawsz + 16;
}

static size_t graph_min_size(const struct git_hash_algo *algop)
{
	return GRAPH_HEADER_SIZE + 4 * CHUNK_TOC_ENTRY_SIZE + GRAPH_FANOUT_SIZE + algop->rawsz;
}

static void set_commit_pos(struct repository *r, const struct object_id *oid)
{
	static int32_t max_pos;
	struct commit *commit = lookup_commit(r, oid);

	if (!commit)
		return; /* should never happen, but be lenient */

	*commit_pos_at(&commit_pos, commit) = max_pos++;
}

static int commit_pos_cmp(const void *va, const void *vb)
{
	const struct commit *a = *(const struct commit **)va;
	const struct commit *b = *(const struct commit **)vb;
	return commit_pos_at(&commit_pos, a) -
	       commit_pos_at(&commit_pos, b);
}

define_commit_slab(commit_graph_data_slab, struct commit_graph_data);
static struct commit_graph_data_slab commit_graph_data_slab =
	COMMIT_SLAB_INIT(1, commit_graph_data_slab);

static int get_configured_generation_version(struct repository *r)
{
	int version = 2;
	repo_config_get_int(r, "commitgraph.generationversion", &version);
	return version;
}

uint32_t commit_graph_position(const struct commit *c)
{
	struct commit_graph_data *data =
		commit_graph_data_slab_peek(&commit_graph_data_slab, c);

	return data ? data->graph_pos : COMMIT_NOT_FROM_GRAPH;
}

timestamp_t commit_graph_generation(const struct commit *c)
{
	struct commit_graph_data *data =
		commit_graph_data_slab_peek(&commit_graph_data_slab, c);

	if (data && data->generation)
		return data->generation;

	return GENERATION_NUMBER_INFINITY;
}

static timestamp_t commit_graph_generation_from_graph(const struct commit *c)
{
	struct commit_graph_data *data =
		commit_graph_data_slab_peek(&commit_graph_data_slab, c);

	if (!data || data->graph_pos == COMMIT_NOT_FROM_GRAPH)
		return GENERATION_NUMBER_INFINITY;
	return data->generation;
}

static struct commit_graph_data *commit_graph_data_at(const struct commit *c)
{
	unsigned int i, nth_slab;
	struct commit_graph_data *data =
		commit_graph_data_slab_peek(&commit_graph_data_slab, c);

	if (data)
		return data;

	nth_slab = c->index / commit_graph_data_slab.slab_size;
	data = commit_graph_data_slab_at(&commit_graph_data_slab, c);

	/*
	 * commit-slab initializes elements with zero, overwrite this with
	 * COMMIT_NOT_FROM_GRAPH for graph_pos.
	 *
	 * We avoid initializing generation with checking if graph position
	 * is not COMMIT_NOT_FROM_GRAPH.
	 */
	for (i = 0; i < commit_graph_data_slab.slab_size; i++) {
		commit_graph_data_slab.slab[nth_slab][i].graph_pos =
			COMMIT_NOT_FROM_GRAPH;
	}

	return data;
}

/*
 * Should be used only while writing commit-graph as it compares
 * generation value of commits by directly accessing commit-slab.
 */
static int commit_gen_cmp(const void *va, const void *vb)
{
	const struct commit *a = *(const struct commit **)va;
	const struct commit *b = *(const struct commit **)vb;

	const timestamp_t generation_a = commit_graph_data_at(a)->generation;
	const timestamp_t generation_b = commit_graph_data_at(b)->generation;
	/* lower generation commits first */
	if (generation_a < generation_b)
		return -1;
	else if (generation_a > generation_b)
		return 1;

	/* use date as a heuristic when generations are equal */
	if (a->date < b->date)
		return -1;
	else if (a->date > b->date)
		return 1;
	return 0;
}

char *get_commit_graph_filename(struct odb_source *source)
{
	return xstrfmt("%s/info/commit-graph", source->path);
}

static char *get_split_graph_filename(struct odb_source *source,
				      const char *oid_hex)
{
	return xstrfmt("%s/info/commit-graphs/graph-%s.graph", source->path,
		       oid_hex);
}

char *get_commit_graph_chain_filename(struct odb_source *source)
{
	return xstrfmt("%s/info/commit-graphs/commit-graph-chain", source->path);
}

static struct commit_graph *alloc_commit_graph(void)
{
	struct commit_graph *g = xcalloc(1, sizeof(*g));

	return g;
}

static int commit_graph_compatible(struct repository *r)
{
	if (!r->gitdir)
		return 0;

	if (replace_refs_enabled(r)) {
		prepare_replace_object(r);
		if (oidmap_get_size(&r->objects->replace_map))
			return 0;
	}

	prepare_commit_graft(r);
	if (r->parsed_objects &&
	    (r->parsed_objects->grafts_nr || r->parsed_objects->substituted_parent))
		return 0;
	if (is_repository_shallow(r))
		return 0;

	return 1;
}

int open_commit_graph(const char *graph_file, int *fd, struct stat *st)
{
	*fd = git_open(graph_file);
	if (*fd < 0)
		return 0;
	if (fstat(*fd, st)) {
		close(*fd);
		return 0;
	}
	return 1;
}

struct commit_graph *load_commit_graph_one_fd_st(struct odb_source *source,
						 int fd, struct stat *st)
{
	void *graph_map;
	size_t graph_size;
	struct commit_graph *ret;

	graph_size = xsize_t(st->st_size);

	if (graph_size < graph_min_size(source->odb->repo->hash_algo)) {
		close(fd);
		error(_("commit-graph file is too small"));
		return NULL;
	}
	graph_map = xmmap(NULL, graph_size, PROT_READ, MAP_PRIVATE, fd, 0);
	close(fd);

	ret = parse_commit_graph(source->odb->repo, graph_map, graph_size);
	if (ret)
		ret->odb_source = source;
	else
		munmap(graph_map, graph_size);

	return ret;
}

static int graph_read_oid_fanout(const unsigned char *chunk_start,
				 size_t chunk_size, void *data)
{
	struct commit_graph *g = data;
	int i;

	if (chunk_size != 256 * sizeof(uint32_t))
		return error(_("commit-graph oid fanout chunk is wrong size"));
	g->chunk_oid_fanout = (const uint32_t *)chunk_start;
	g->num_commits = ntohl(g->chunk_oid_fanout[255]);

	for (i = 0; i < 255; i++) {
		uint32_t oid_fanout1 = ntohl(g->chunk_oid_fanout[i]);
		uint32_t oid_fanout2 = ntohl(g->chunk_oid_fanout[i + 1]);

		if (oid_fanout1 > oid_fanout2) {
			error(_("commit-graph fanout values out of order"));
			return 1;
		}
	}

	return 0;
}

static int graph_read_oid_lookup(const unsigned char *chunk_start,
				 size_t chunk_size, void *data)
{
	struct commit_graph *g = data;
	g->chunk_oid_lookup = chunk_start;
	if (chunk_size / g->hash_algo->rawsz != g->num_commits)
		return error(_("commit-graph OID lookup chunk is the wrong size"));
	return 0;
}

static int graph_read_commit_data(const unsigned char *chunk_start,
				  size_t chunk_size, void *data)
{
	struct commit_graph *g = data;
	if (chunk_size / graph_data_width(g->hash_algo) != g->num_commits)
		return error(_("commit-graph commit data chunk is wrong size"));
	g->chunk_commit_data = chunk_start;
	return 0;
}

static int graph_read_generation_data(const unsigned char *chunk_start,
				      size_t chunk_size, void *data)
{
	struct commit_graph *g = data;
	if (chunk_size / sizeof(uint32_t) != g->num_commits)
		return error(_("commit-graph generations chunk is wrong size"));
	g->chunk_generation_data = chunk_start;
	return 0;
}

static int graph_read_bloom_index(const unsigned char *chunk_start,
				  size_t chunk_size, void *data)
{
	struct commit_graph *g = data;
	if (chunk_size / 4 != g->num_commits) {
		warning(_("commit-graph changed-path index chunk is too small"));
		return -1;
	}
	g->chunk_bloom_indexes = chunk_start;
	return 0;
}

static int graph_read_bloom_data(const unsigned char *chunk_start,
				  size_t chunk_size, void *data)
{
	struct commit_graph *g = data;

	if (chunk_size < BLOOMDATA_CHUNK_HEADER_SIZE) {
		warning(_("ignoring too-small changed-path chunk"
			" (%"PRIuMAX" < %"PRIuMAX") in commit-graph file"),
			(uintmax_t)chunk_size,
			(uintmax_t)BLOOMDATA_CHUNK_HEADER_SIZE);
		return -1;
	}

	g->chunk_bloom_data = chunk_start;
	g->chunk_bloom_data_size = chunk_size;

	g->bloom_filter_settings = xmalloc(sizeof(struct bloom_filter_settings));
	g->bloom_filter_settings->hash_version = get_be32(chunk_start);
	g->bloom_filter_settings->num_hashes = get_be32(chunk_start + 4);
	g->bloom_filter_settings->bits_per_entry = get_be32(chunk_start + 8);
	g->bloom_filter_settings->max_changed_paths = DEFAULT_BLOOM_MAX_CHANGES;

	return 0;
}

struct commit_graph *parse_commit_graph(struct repository *r,
					void *graph_map, size_t graph_size)
{
	const unsigned char *data;
	struct commit_graph *graph;
	uint32_t graph_signature;
	unsigned char graph_version, hash_version;
	struct chunkfile *cf = NULL;

	if (!graph_map)
		return NULL;

	if (graph_size < graph_min_size(r->hash_algo))
		return NULL;

	data = (const unsigned char *)graph_map;

	graph_signature = get_be32(data);
	if (graph_signature != GRAPH_SIGNATURE) {
		error(_("commit-graph signature %X does not match signature %X"),
		      graph_signature, GRAPH_SIGNATURE);
		return NULL;
	}

	graph_version = *(unsigned char*)(data + 4);
	if (graph_version != GRAPH_VERSION) {
		error(_("commit-graph version %X does not match version %X"),
		      graph_version, GRAPH_VERSION);
		return NULL;
	}

	hash_version = *(unsigned char*)(data + 5);
	if (hash_version != oid_version(r->hash_algo)) {
		error(_("commit-graph hash version %X does not match version %X"),
		      hash_version, oid_version(r->hash_algo));
		return NULL;
	}

	graph = alloc_commit_graph();

	graph->hash_algo = r->hash_algo;
	graph->num_chunks = *(unsigned char*)(data + 6);
	graph->data = graph_map;
	graph->data_len = graph_size;

	if (graph_size < GRAPH_HEADER_SIZE +
			 (graph->num_chunks + 1) * CHUNK_TOC_ENTRY_SIZE +
			 GRAPH_FANOUT_SIZE + r->hash_algo->rawsz) {
		error(_("commit-graph file is too small to hold %u chunks"),
		      graph->num_chunks);
		free(graph);
		return NULL;
	}

	cf = init_chunkfile(NULL);

	if (read_table_of_contents(cf, graph->data, graph_size,
				   GRAPH_HEADER_SIZE, graph->num_chunks, 1))
		goto free_and_return;

	if (read_chunk(cf, GRAPH_CHUNKID_OIDFANOUT, graph_read_oid_fanout, graph)) {
		error(_("commit-graph required OID fanout chunk missing or corrupted"));
		goto free_and_return;
	}
	if (read_chunk(cf, GRAPH_CHUNKID_OIDLOOKUP, graph_read_oid_lookup, graph)) {
		error(_("commit-graph required OID lookup chunk missing or corrupted"));
		goto free_and_return;
	}
	if (read_chunk(cf, GRAPH_CHUNKID_DATA, graph_read_commit_data, graph)) {
		error(_("commit-graph required commit data chunk missing or corrupted"));
		goto free_and_return;
	}

	pair_chunk(cf, GRAPH_CHUNKID_EXTRAEDGES, &graph->chunk_extra_edges,
		   &graph->chunk_extra_edges_size);
	pair_chunk(cf, GRAPH_CHUNKID_BASE, &graph->chunk_base_graphs,
		   &graph->chunk_base_graphs_size);

	prepare_repo_settings(r);

	if (r->settings.commit_graph_generation_version >= 2) {
		read_chunk(cf, GRAPH_CHUNKID_GENERATION_DATA,
			   graph_read_generation_data, graph);
		pair_chunk(cf, GRAPH_CHUNKID_GENERATION_DATA_OVERFLOW,
			   &graph->chunk_generation_data_overflow,
			   &graph->chunk_generation_data_overflow_size);

		if (graph->chunk_generation_data)
			graph->read_generation_data = 1;
	}

	if (r->settings.commit_graph_changed_paths_version) {
		read_chunk(cf, GRAPH_CHUNKID_BLOOMINDEXES,
			   graph_read_bloom_index, graph);
		read_chunk(cf, GRAPH_CHUNKID_BLOOMDATA,
			   graph_read_bloom_data, graph);
	}

	if (graph->chunk_bloom_indexes && graph->chunk_bloom_data) {
		init_bloom_filters();
	} else {
		/* We need both the bloom chunks to exist together. Else ignore the data */
		graph->chunk_bloom_indexes = NULL;
		graph->chunk_bloom_data = NULL;
		FREE_AND_NULL(graph->bloom_filter_settings);
	}

	oidread(&graph->oid, graph->data + graph->data_len - graph->hash_algo->rawsz,
		r->hash_algo);

	free_chunkfile(cf);
	return graph;

free_and_return:
	free_chunkfile(cf);
	free(graph->bloom_filter_settings);
	free(graph);
	return NULL;
}

static struct commit_graph *load_commit_graph_one(struct odb_source *source,
						  const char *graph_file)
{
	struct stat st;
	int fd;
	struct commit_graph *g;
	int open_ok = open_commit_graph(graph_file, &fd, &st);

	if (!open_ok)
		return NULL;

	g = load_commit_graph_one_fd_st(source, fd, &st);
	if (g)
		g->filename = xstrdup(graph_file);

	return g;
}

static struct commit_graph *load_commit_graph_v1(struct odb_source *source)
{
	char *graph_name = get_commit_graph_filename(source);
	struct commit_graph *g = load_commit_graph_one(source, graph_name);
	free(graph_name);

	return g;
}

/*
 * returns 1 if and only if all graphs in the chain have
 * corrected commit dates stored in the generation_data chunk.
 */
static int validate_mixed_generation_chain(struct commit_graph *g)
{
	int read_generation_data = 1;
	struct commit_graph *p = g;

	while (read_generation_data && p) {
		read_generation_data = p->read_generation_data;
		p = p->base_graph;
	}

	if (read_generation_data)
		return 1;

	while (g) {
		g->read_generation_data = 0;
		g = g->base_graph;
	}

	return 0;
}

static void validate_mixed_bloom_settings(struct commit_graph *g)
{
	struct bloom_filter_settings *settings = NULL;
	for (; g; g = g->base_graph) {
		if (!g->bloom_filter_settings)
			continue;
		if (!settings) {
			settings = g->bloom_filter_settings;
			continue;
		}

		if (g->bloom_filter_settings->bits_per_entry != settings->bits_per_entry ||
		    g->bloom_filter_settings->num_hashes != settings->num_hashes ||
		    g->bloom_filter_settings->hash_version != settings->hash_version) {
			g->chunk_bloom_indexes = NULL;
			g->chunk_bloom_data = NULL;
			FREE_AND_NULL(g->bloom_filter_settings);

			warning(_("disabling Bloom filters for commit-graph "
				  "layer '%s' due to incompatible settings"),
				oid_to_hex(&g->oid));
		}
	}
}

static int add_graph_to_chain(struct commit_graph *g,
			      struct commit_graph *chain,
			      struct object_id *oids,
			      int n)
{
	struct commit_graph *cur_g = chain;

	if (n && !g->chunk_base_graphs) {
		warning(_("commit-graph has no base graphs chunk"));
		return 0;
	}

	if (g->chunk_base_graphs_size / g->hash_algo->rawsz < n) {
		warning(_("commit-graph base graphs chunk is too small"));
		return 0;
	}

	while (n) {
		n--;

		if (!cur_g ||
		    !oideq(&oids[n], &cur_g->oid) ||
		    !hasheq(oids[n].hash, g->chunk_base_graphs + st_mult(g->hash_algo->rawsz, n),
			    g->hash_algo)) {
			warning(_("commit-graph chain does not match"));
			return 0;
		}

		cur_g = cur_g->base_graph;
	}

	if (chain) {
		if (unsigned_add_overflows(chain->num_commits,
					   chain->num_commits_in_base)) {
			warning(_("commit count in base graph too high: %"PRIuMAX),
				(uintmax_t)chain->num_commits_in_base);
			return 0;
		}
		g->num_commits_in_base = chain->num_commits + chain->num_commits_in_base;
	}

	g->base_graph = chain;

	return 1;
}

int open_commit_graph_chain(const char *chain_file,
			    int *fd, struct stat *st,
			    const struct git_hash_algo *hash_algo)
{
	*fd = git_open(chain_file);
	if (*fd < 0)
		return 0;
	if (fstat(*fd, st)) {
		close(*fd);
		return 0;
	}
	if (st->st_size < hash_algo->hexsz) {
		close(*fd);
		if (!st->st_size) {
			/* treat empty files the same as missing */
			errno = ENOENT;
		} else {
			warning(_("commit-graph chain file too small"));
			errno = EINVAL;
		}
		return 0;
	}
	return 1;
}

struct commit_graph *load_commit_graph_chain_fd_st(struct object_database *odb,
						   int fd, struct stat *st,
						   int *incomplete_chain)
{
	struct commit_graph *graph_chain = NULL;
	struct strbuf line = STRBUF_INIT;
	struct object_id *oids;
	int i = 0, valid = 1, count;
	FILE *fp = xfdopen(fd, "r");

	count = st->st_size / (odb->repo->hash_algo->hexsz + 1);
	CALLOC_ARRAY(oids, count);

	odb_prepare_alternates(odb);

	for (i = 0; i < count; i++) {
		struct odb_source *source;

		if (strbuf_getline_lf(&line, fp) == EOF)
			break;

		if (get_oid_hex_algop(line.buf, &oids[i], odb->repo->hash_algo)) {
			warning(_("invalid commit-graph chain: line '%s' not a hash"),
				line.buf);
			valid = 0;
			break;
		}

		valid = 0;
		for (source = odb->sources; source; source = source->next) {
			char *graph_name = get_split_graph_filename(source, line.buf);
			struct commit_graph *g = load_commit_graph_one(source, graph_name);

			free(graph_name);

			if (g) {
				if (add_graph_to_chain(g, graph_chain, oids, i)) {
					graph_chain = g;
					valid = 1;
				} else {
					free_commit_graph(g);
				}

				break;
			}
		}

		if (!valid) {
			warning(_("unable to find all commit-graph files"));
			break;
		}
	}

	validate_mixed_generation_chain(graph_chain);
	validate_mixed_bloom_settings(graph_chain);

	free(oids);
	fclose(fp);
	strbuf_release(&line);

	*incomplete_chain = !valid;
	return graph_chain;
}

static struct commit_graph *load_commit_graph_chain(struct odb_source *source)
{
	char *chain_file = get_commit_graph_chain_filename(source);
	struct stat st;
	int fd;
	struct commit_graph *g = NULL;

	if (open_commit_graph_chain(chain_file, &fd, &st, source->odb->repo->hash_algo)) {
		int incomplete;
		/* ownership of fd is taken over by load function */
		g = load_commit_graph_chain_fd_st(source->odb, fd, &st, &incomplete);
	}

	free(chain_file);
	return g;
}

struct commit_graph *read_commit_graph_one(struct odb_source *source)
{
	struct commit_graph *g = load_commit_graph_v1(source);

	if (!g)
		g = load_commit_graph_chain(source);

	return g;
}

/*
 * Return 1 if commit_graph is non-NULL, and 0 otherwise.
 *
 * On the first invocation, this function attempts to load the commit
 * graph if the repository is configured to have one.
 */
static struct commit_graph *prepare_commit_graph(struct repository *r)
{
	struct odb_source *source;

	/*
	 * Early return if there is no git dir or if the commit graph is
	 * disabled.
	 *
	 * This must come before the "already attempted?" check below, because
	 * we want to disable even an already-loaded graph file.
	 */
	if (!r->gitdir || r->commit_graph_disabled)
		return NULL;

	if (r->objects->commit_graph_attempted)
		return r->objects->commit_graph;
	r->objects->commit_graph_attempted = 1;

	prepare_repo_settings(r);

	if (!git_env_bool(GIT_TEST_COMMIT_GRAPH, 0) &&
	    r->settings.core_commit_graph != 1)
		/*
		 * This repository is not configured to use commit graphs, so
		 * do not load one. (But report commit_graph_attempted anyway
		 * so that commit graph loading is not attempted again for this
		 * repository.)
		 */
		return NULL;

	if (!commit_graph_compatible(r))
		return NULL;

	odb_prepare_alternates(r->objects);
	for (source = r->objects->sources; source; source = source->next) {
		r->objects->commit_graph = read_commit_graph_one(source);
		if (r->objects->commit_graph)
			break;
	}

	return r->objects->commit_graph;
}

int generation_numbers_enabled(struct repository *r)
{
	uint32_t first_generation;
	struct commit_graph *g;

	g = prepare_commit_graph(r);
	if (!g || !g->num_commits)
	       return 0;

	first_generation = get_be32(g->chunk_commit_data +
				    g->hash_algo->rawsz + 8) >> 2;

	return !!first_generation;
}

int corrected_commit_dates_enabled(struct repository *r)
{
	struct commit_graph *g;

	g = prepare_commit_graph(r);
	if (!g || !g->num_commits)
		return 0;

	return g->read_generation_data;
}

struct bloom_filter_settings *get_bloom_filter_settings(struct repository *r)
{
	struct commit_graph *g;

	if (!prepare_commit_graph(r))
	       return NULL;

	g = r->objects->commit_graph;
	while (g) {
		if (g->bloom_filter_settings)
			return g->bloom_filter_settings;
		g = g->base_graph;
	}
	return NULL;
}

void close_commit_graph(struct object_database *o)
{
	if (!o->commit_graph)
		return;

	clear_commit_graph_data_slab(&commit_graph_data_slab);
	deinit_bloom_filters();
	free_commit_graph(o->commit_graph);
	o->commit_graph = NULL;
}

static int bsearch_graph(struct commit_graph *g, const struct object_id *oid, uint32_t *pos)
{
	return bsearch_hash(oid->hash, g->chunk_oid_fanout,
			    g->chunk_oid_lookup, g->hash_algo->rawsz, pos);
}

static void load_oid_from_graph(struct commit_graph *g,
				uint32_t pos,
				struct object_id *oid)
{
	uint32_t lex_index;

	while (g && pos < g->num_commits_in_base)
		g = g->base_graph;

	if (!g)
		BUG("NULL commit-graph");

	if (pos >= g->num_commits + g->num_commits_in_base)
		die(_("invalid commit position. commit-graph is likely corrupt"));

	lex_index = pos - g->num_commits_in_base;

	oidread(oid, g->chunk_oid_lookup + st_mult(g->hash_algo->rawsz, lex_index),
		g->hash_algo);
}

static struct commit_list **insert_parent_or_die(struct commit_graph *g,
						 uint32_t pos,
						 struct commit_list **pptr)
{
	struct commit *c;
	struct object_id oid;

	if (pos >= g->num_commits + g->num_commits_in_base)
		die("invalid parent position %"PRIu32, pos);

	load_oid_from_graph(g, pos, &oid);
	c = lookup_commit(g->odb_source->odb->repo, &oid);
	if (!c)
		die(_("could not find commit %s"), oid_to_hex(&oid));
	commit_graph_data_at(c)->graph_pos = pos;
	return &commit_list_insert(c, pptr)->next;
}

static void fill_commit_graph_info(struct commit *item, struct commit_graph *g, uint32_t pos)
{
	const unsigned char *commit_data;
	struct commit_graph_data *graph_data;
	uint32_t lex_index, offset_pos;
	uint64_t date_high, date_low, offset;

	while (pos < g->num_commits_in_base)
		g = g->base_graph;

	if (pos >= g->num_commits + g->num_commits_in_base)
		die(_("invalid commit position. commit-graph is likely corrupt"));

	lex_index = pos - g->num_commits_in_base;
	commit_data = g->chunk_commit_data + st_mult(graph_data_width(g->hash_algo), lex_index);

	graph_data = commit_graph_data_at(item);
	graph_data->graph_pos = pos;

	date_high = get_be32(commit_data + g->hash_algo->rawsz + 8) & 0x3;
	date_low = get_be32(commit_data + g->hash_algo->rawsz + 12);
	item->date = (timestamp_t)((date_high << 32) | date_low);

	if (g->read_generation_data) {
		offset = (timestamp_t)get_be32(g->chunk_generation_data + st_mult(sizeof(uint32_t), lex_index));

		if (offset & CORRECTED_COMMIT_DATE_OFFSET_OVERFLOW) {
			if (!g->chunk_generation_data_overflow)
				die(_("commit-graph requires overflow generation data but has none"));

			offset_pos = offset ^ CORRECTED_COMMIT_DATE_OFFSET_OVERFLOW;
			if (g->chunk_generation_data_overflow_size / sizeof(uint64_t) <= offset_pos)
				die(_("commit-graph overflow generation data is too small"));
			graph_data->generation = item->date +
				get_be64(g->chunk_generation_data_overflow + sizeof(uint64_t) * offset_pos);
		} else
			graph_data->generation = item->date + offset;
	} else
		graph_data->generation = get_be32(commit_data + g->hash_algo->rawsz + 8) >> 2;

	if (g->topo_levels)
		*topo_level_slab_at(g->topo_levels, item) = get_be32(commit_data + g->hash_algo->rawsz + 8) >> 2;
}

static inline void set_commit_tree(struct commit *c, struct tree *t)
{
	c->maybe_tree = t;
}

static int fill_commit_in_graph(struct commit *item,
				struct commit_graph *g, uint32_t pos)
{
	uint32_t edge_value;
	uint32_t parent_data_pos;
	struct commit_list **pptr;
	const unsigned char *commit_data;
	uint32_t lex_index;

	while (pos < g->num_commits_in_base)
		g = g->base_graph;

	fill_commit_graph_info(item, g, pos);

	lex_index = pos - g->num_commits_in_base;
	commit_data = g->chunk_commit_data + st_mult(g->hash_algo->rawsz + 16, lex_index);

	item->object.parsed = 1;

	set_commit_tree(item, NULL);

	pptr = &item->parents;

	edge_value = get_be32(commit_data + g->hash_algo->rawsz);
	if (edge_value == GRAPH_PARENT_NONE)
		return 1;
	pptr = insert_parent_or_die(g, edge_value, pptr);

	edge_value = get_be32(commit_data + g->hash_algo->rawsz + 4);
	if (edge_value == GRAPH_PARENT_NONE)
		return 1;
	if (!(edge_value & GRAPH_EXTRA_EDGES_NEEDED)) {
		pptr = insert_parent_or_die(g, edge_value, pptr);
		return 1;
	}

	parent_data_pos = edge_value & GRAPH_EDGE_LAST_MASK;
	do {
		if (g->chunk_extra_edges_size / sizeof(uint32_t) <= parent_data_pos) {
			error(_("commit-graph extra-edges pointer out of bounds"));
			free_commit_list(item->parents);
			item->parents = NULL;
			item->object.parsed = 0;
			return 0;
		}
		edge_value = get_be32(g->chunk_extra_edges +
				      sizeof(uint32_t) * parent_data_pos);
		pptr = insert_parent_or_die(g,
					    edge_value & GRAPH_EDGE_LAST_MASK,
					    pptr);
		parent_data_pos++;
	} while (!(edge_value & GRAPH_LAST_EDGE));

	return 1;
}

static int search_commit_pos_in_graph(const struct object_id *id, struct commit_graph *g, uint32_t *pos)
{
	struct commit_graph *cur_g = g;
	uint32_t lex_index;

	while (cur_g && !bsearch_graph(cur_g, id, &lex_index))
		cur_g = cur_g->base_graph;

	if (cur_g) {
		*pos = lex_index + cur_g->num_commits_in_base;
		return 1;
	}

	return 0;
}

static int find_commit_pos_in_graph(struct commit *item, struct commit_graph *g, uint32_t *pos)
{
	uint32_t graph_pos = commit_graph_position(item);
	if (graph_pos != COMMIT_NOT_FROM_GRAPH) {
		*pos = graph_pos;
		return 1;
	} else {
		return search_commit_pos_in_graph(&item->object.oid, g, pos);
	}
}

struct commit_graph *repo_find_commit_pos_in_graph(struct repository *r,
						   struct commit *c,
						   uint32_t *pos)
{
	struct commit_graph *g = prepare_commit_graph(r);
	if (!g)
		return NULL;
	if (!find_commit_pos_in_graph(c, g, pos))
		return NULL;
	return g;
}

struct commit *lookup_commit_in_graph(struct repository *repo, const struct object_id *id)
{
	static int commit_graph_paranoia = -1;
	struct commit_graph *g;
	struct commit *commit;
	uint32_t pos;

	if (commit_graph_paranoia == -1)
		commit_graph_paranoia = git_env_bool(GIT_COMMIT_GRAPH_PARANOIA, 0);

	g = prepare_commit_graph(repo);
	if (!g)
		return NULL;
	if (!search_commit_pos_in_graph(id, g, &pos))
		return NULL;
	if (commit_graph_paranoia && !odb_has_object(repo->objects, id, 0))
		return NULL;

	commit = lookup_commit(repo, id);
	if (!commit)
		return NULL;
	if (commit->object.parsed)
		return commit;

	if (!fill_commit_in_graph(commit, g, pos))
		return NULL;

	return commit;
}

static int parse_commit_in_graph_one(struct commit_graph *g,
				     struct commit *item)
{
	uint32_t pos;

	if (item->object.parsed)
		return 1;

	if (find_commit_pos_in_graph(item, g, &pos))
		return fill_commit_in_graph(item, g, pos);

	return 0;
}

int parse_commit_in_graph(struct repository *r, struct commit *item)
{
	static int checked_env = 0;
	struct commit_graph *g;

	if (!checked_env &&
	    git_env_bool(GIT_TEST_COMMIT_GRAPH_DIE_ON_PARSE, 0))
		die("dying as requested by the '%s' variable on commit-graph parse!",
		    GIT_TEST_COMMIT_GRAPH_DIE_ON_PARSE);
	checked_env = 1;

	g = prepare_commit_graph(r);
	if (!g)
		return 0;
	return parse_commit_in_graph_one(g, item);
}

void load_commit_graph_info(struct repository *r, struct commit *item)
{
	struct commit_graph *g;
	uint32_t pos;

	g = repo_find_commit_pos_in_graph(r, item, &pos);
	if (g)
		fill_commit_graph_info(item, g, pos);
}

static struct tree *load_tree_for_commit(struct commit_graph *g,
					 struct commit *c)
{
	struct object_id oid;
	const unsigned char *commit_data;
	uint32_t graph_pos = commit_graph_position(c);

	while (graph_pos < g->num_commits_in_base)
		g = g->base_graph;

	commit_data = g->chunk_commit_data +
			st_mult(graph_data_width(g->hash_algo),
				graph_pos - g->num_commits_in_base);

	oidread(&oid, commit_data, g->hash_algo);
	set_commit_tree(c, lookup_tree(g->odb_source->odb->repo, &oid));

	return c->maybe_tree;
}

static struct tree *get_commit_tree_in_graph_one(struct commit_graph *g,
						 const struct commit *c)
{
	if (c->maybe_tree)
		return c->maybe_tree;
	if (commit_graph_position(c) == COMMIT_NOT_FROM_GRAPH)
		BUG("get_commit_tree_in_graph_one called from non-commit-graph commit");

	return load_tree_for_commit(g, (struct commit *)c);
}

struct tree *get_commit_tree_in_graph(struct repository *r, const struct commit *c)
{
	return get_commit_tree_in_graph_one(r->objects->commit_graph, c);
}

struct write_commit_graph_context {
	struct repository *r;
	struct odb_source *odb_source;
	char *graph_name;
	struct oid_array oids;
	struct commit_stack commits;
	int num_extra_edges;
	int num_generation_data_overflows;
	unsigned long approx_nr_objects;
	struct progress *progress;
	int progress_done;
	uint64_t progress_cnt;

	char *base_graph_name;
	int num_commit_graphs_before;
	int num_commit_graphs_after;
	char **commit_graph_filenames_before;
	char **commit_graph_filenames_after;
	char **commit_graph_hash_after;
	uint32_t new_num_commits_in_base;
	struct commit_graph *new_base_graph;

	unsigned append:1,
		 report_progress:1,
		 split:1,
		 changed_paths:1,
		 order_by_pack:1,
		 write_generation_data:1,
		 trust_generation_numbers:1;

	struct topo_level_slab *topo_levels;
	const struct commit_graph_opts *opts;
	size_t total_bloom_filter_data_size;
	const struct bloom_filter_settings *bloom_settings;

	int count_bloom_filter_computed;
	int count_bloom_filter_not_computed;
	int count_bloom_filter_trunc_empty;
	int count_bloom_filter_trunc_large;
	int count_bloom_filter_upgraded;
};

static int write_graph_chunk_fanout(struct hashfile *f,
				    void *data)
{
	struct write_commit_graph_context *ctx = data;
	int i, count = 0;
	struct commit **list = ctx->commits.items;

	/*
	 * 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++) {
		while (count < ctx->commits.nr) {
			if ((*list)->object.oid.hash[0] != i)
				break;
			display_progress(ctx->progress, ++ctx->progress_cnt);
			count++;
			list++;
		}

		hashwrite_be32(f, count);
	}

	return 0;
}

static int write_graph_chunk_oids(struct hashfile *f,
				  void *data)
{
	struct write_commit_graph_context *ctx = data;
	struct commit **list = ctx->commits.items;
	int count;
	for (count = 0; count < ctx->commits.nr; count++, list++) {
		display_progress(ctx->progress, ++ctx->progress_cnt);
		hashwrite(f, (*list)->object.oid.hash, f->algop->rawsz);
	}

	return 0;
}

static const struct object_id *commit_to_oid(size_t index, const void *table)
{
	const struct commit * const *commits = table;
	return &commits[index]->object.oid;
}

static int write_graph_chunk_data(struct hashfile *f,
				  void *data)
{
	struct write_commit_graph_context *ctx = data;
	struct commit **list = ctx->commits.items;
	struct commit **last = ctx->commits.items + ctx->commits.nr;
	uint32_t num_extra_edges = 0;

	while (list < last) {
		struct commit_list *parent;
		struct object_id *tree;
		int edge_value;
		uint32_t packedDate[2];
		display_progress(ctx->progress, ++ctx->progress_cnt);

		if (repo_parse_commit_no_graph(ctx->r, *list))
			die(_("unable to parse commit %s"),
				oid_to_hex(&(*list)->object.oid));
		tree = get_commit_tree_oid(*list);
		hashwrite(f, tree->hash, ctx->r->hash_algo->rawsz);

		parent = (*list)->parents;

		if (!parent)
			edge_value = GRAPH_PARENT_NONE;
		else {
			edge_value = oid_pos(&parent->item->object.oid,
					     ctx->commits.items,
					     ctx->commits.nr,
					     commit_to_oid);

			if (edge_value >= 0)
				edge_value += ctx->new_num_commits_in_base;
			else if (ctx->new_base_graph) {
				uint32_t pos;
				if (find_commit_pos_in_graph(parent->item,
							     ctx->new_base_graph,
							     &pos))
					edge_value = pos;
			}

			if (edge_value < 0)
				BUG("missing parent %s for commit %s",
				    oid_to_hex(&parent->item->object.oid),
				    oid_to_hex(&(*list)->object.oid));
		}

		hashwrite_be32(f, edge_value);

		if (parent)
			parent = parent->next;

		if (!parent)
			edge_value = GRAPH_PARENT_NONE;
		else if (parent->next)
			edge_value = GRAPH_EXTRA_EDGES_NEEDED | num_extra_edges;
		else {
			edge_value = oid_pos(&parent->item->object.oid,
					     ctx->commits.items,
					     ctx->commits.nr,
					     commit_to_oid);

			if (edge_value >= 0)
				edge_value += ctx->new_num_commits_in_base;
			else if (ctx->new_base_graph) {
				uint32_t pos;
				if (find_commit_pos_in_graph(parent->item,
							     ctx->new_base_graph,
							     &pos))
					edge_value = pos;
			}

			if (edge_value < 0)
				BUG("missing parent %s for commit %s",
				    oid_to_hex(&parent->item->object.oid),
				    oid_to_hex(&(*list)->object.oid));
		}

		hashwrite_be32(f, edge_value);

		if (edge_value & GRAPH_EXTRA_EDGES_NEEDED) {
			do {
				num_extra_edges++;
				parent = parent->next;
			} while (parent);
		}

		if (sizeof((*list)->date) > 4)
			packedDate[0] = htonl(((*list)->date >> 32) & 0x3);
		else
			packedDate[0] = 0;

		packedDate[0] |= htonl(*topo_level_slab_at(ctx->topo_levels, *list) << 2);

		packedDate[1] = htonl((*list)->date);
		hashwrite(f, packedDate, 8);

		list++;
	}

	return 0;
}

static int write_graph_chunk_generation_data(struct hashfile *f,
					     void *data)
{
	struct write_commit_graph_context *ctx = data;
	int i, num_generation_data_overflows = 0;

	for (i = 0; i < ctx->commits.nr; i++) {
		struct commit *c = ctx->commits.items[i];
		timestamp_t offset;
		repo_parse_commit(ctx->r, c);
		offset = commit_graph_data_at(c)->generation - c->date;
		display_progress(ctx->progress, ++ctx->progress_cnt);

		if (offset > GENERATION_NUMBER_V2_OFFSET_MAX) {
			offset = CORRECTED_COMMIT_DATE_OFFSET_OVERFLOW | num_generation_data_overflows;
			num_generation_data_overflows++;
		}

		hashwrite_be32(f, offset);
	}

	return 0;
}

static int write_graph_chunk_generation_data_overflow(struct hashfile *f,
						      void *data)
{
	struct write_commit_graph_context *ctx = data;
	int i;
	for (i = 0; i < ctx->commits.nr; i++) {
		struct commit *c = ctx->commits.items[i];
		timestamp_t offset = commit_graph_data_at(c)->generation - c->date;
		display_progress(ctx->progress, ++ctx->progress_cnt);

		if (offset > GENERATION_NUMBER_V2_OFFSET_MAX) {
			hashwrite_be32(f, offset >> 32);
			hashwrite_be32(f, (uint32_t) offset);
		}
	}

	return 0;
}

static int write_graph_chunk_extra_edges(struct hashfile *f,
					 void *data)
{
	struct write_commit_graph_context *ctx = data;
	struct commit **list = ctx->commits.items;
	struct commit **last = ctx->commits.items + ctx->commits.nr;
	struct commit_list *parent;

	while (list < last) {
		int num_parents = 0;

		display_progress(ctx->progress, ++ctx->progress_cnt);

		for (parent = (*list)->parents; num_parents < 3 && parent;
		     parent = parent->next)
			num_parents++;

		if (num_parents <= 2) {
			list++;
			continue;
		}

		/* Since num_parents > 2, this initializer is safe. */
		for (parent = (*list)->parents->next; parent; parent = parent->next) {
			int edge_value = oid_pos(&parent->item->object.oid,
						 ctx->commits.items,
						 ctx->commits.nr,
						 commit_to_oid);

			if (edge_value >= 0)
				edge_value += ctx->new_num_commits_in_base;
			else if (ctx->new_base_graph) {
				uint32_t pos;
				if (find_commit_pos_in_graph(parent->item,
							     ctx->new_base_graph,
							     &pos))
					edge_value = pos;
			}

			if (edge_value < 0)
				BUG("missing parent %s for commit %s",
				    oid_to_hex(&parent->item->object.oid),
				    oid_to_hex(&(*list)->object.oid));
			else if (!parent->next)
				edge_value |= GRAPH_LAST_EDGE;

			hashwrite_be32(f, edge_value);
		}

		list++;
	}

	return 0;
}

static int write_graph_chunk_bloom_indexes(struct hashfile *f,
					   void *data)
{
	struct write_commit_graph_context *ctx = data;
	struct commit **list = ctx->commits.items;
	struct commit **last = ctx->commits.items + ctx->commits.nr;
	uint32_t cur_pos = 0;

	while (list < last) {
		struct bloom_filter *filter = get_bloom_filter(ctx->r, *list);
		size_t len = filter ? filter->len : 0;
		cur_pos += len;
		display_progress(ctx->progress, ++ctx->progress_cnt);
		hashwrite_be32(f, cur_pos);
		list++;
	}

	return 0;
}

static void trace2_bloom_filter_settings(struct write_commit_graph_context *ctx)
{
	struct json_writer jw = JSON_WRITER_INIT;

	jw_object_begin(&jw, 0);
	jw_object_intmax(&jw, "hash_version", ctx->bloom_settings->hash_version);
	jw_object_intmax(&jw, "num_hashes", ctx->bloom_settings->num_hashes);
	jw_object_intmax(&jw, "bits_per_entry", ctx->bloom_settings->bits_per_entry);
	jw_object_intmax(&jw, "max_changed_paths", ctx->bloom_settings->max_changed_paths);
	jw_end(&jw);

	trace2_data_json("bloom", ctx->r, "settings", &jw);

	jw_release(&jw);
}

static int write_graph_chunk_bloom_data(struct hashfile *f,
					void *data)
{
	struct write_commit_graph_context *ctx = data;
	struct commit **list = ctx->commits.items;
	struct commit **last = ctx->commits.items + ctx->commits.nr;

	trace2_bloom_filter_settings(ctx);

	hashwrite_be32(f, ctx->bloom_settings->hash_version);
	hashwrite_be32(f, ctx->bloom_settings->num_hashes);
	hashwrite_be32(f, ctx->bloom_settings->bits_per_entry);

	while (list < last) {
		struct bloom_filter *filter = get_bloom_filter(ctx->r, *list);
		size_t len = filter ? filter->len : 0;

		display_progress(ctx->progress, ++ctx->progress_cnt);
		if (len)
			hashwrite(f, filter->data, len * sizeof(unsigned char));
		list++;
	}

	return 0;
}

static int add_packed_commits(const struct object_id *oid,
			      struct packed_git *pack,
			      uint32_t pos,
			      void *data)
{
	struct write_commit_graph_context *ctx = (struct write_commit_graph_context*)data;
	enum object_type type;
	off_t offset = nth_packed_object_offset(pack, pos);
	struct object_info oi = OBJECT_INFO_INIT;

	if (ctx->progress)
		display_progress(ctx->progress, ++ctx->progress_done);

	oi.typep = &type;
	if (packed_object_info(pack, offset, &oi) < 0)
		die(_("unable to get type of object %s"), oid_to_hex(oid));

	if (type != OBJ_COMMIT)
		return 0;

	oid_array_append(&ctx->oids, oid);
	set_commit_pos(ctx->r, oid);

	return 0;
}

static void add_missing_parents(struct write_commit_graph_context *ctx, struct commit *commit)
{
	struct commit_list *parent;
	for (parent = commit->parents; parent; parent = parent->next) {
		if (!(parent->item->object.flags & REACHABLE)) {
			oid_array_append(&ctx->oids, &parent->item->object.oid);
			parent->item->object.flags |= REACHABLE;
		}
	}
}

static void close_reachable(struct write_commit_graph_context *ctx)
{
	int i;
	struct commit *commit;
	enum commit_graph_split_flags flags = ctx->opts ?
		ctx->opts->split_flags : COMMIT_GRAPH_SPLIT_UNSPECIFIED;

	if (ctx->report_progress)
		ctx->progress = start_delayed_progress(
					ctx->r,
					_("Loading known commits in commit graph"),
					ctx->oids.nr);
	for (i = 0; i < ctx->oids.nr; i++) {
		display_progress(ctx->progress, i + 1);
		commit = lookup_commit(ctx->r, &ctx->oids.oid[i]);
		if (commit)
			commit->object.flags |= REACHABLE;
	}
	stop_progress(&ctx->progress);

	/*
	 * As this loop runs, ctx->oids.nr may grow, but not more
	 * than the number of missing commits in the reachable
	 * closure.
	 */
	if (ctx->report_progress)
		ctx->progress = start_delayed_progress(
					ctx->r,
					_("Expanding reachable commits in commit graph"),
					0);
	for (i = 0; i < ctx->oids.nr; i++) {
		display_progress(ctx->progress, i + 1);
		commit = lookup_commit(ctx->r, &ctx->oids.oid[i]);

		if (!commit)
			continue;
		if (ctx->split) {
			if ((!repo_parse_commit(ctx->r, commit) &&
			     commit_graph_position(commit) == COMMIT_NOT_FROM_GRAPH) ||
			    flags == COMMIT_GRAPH_SPLIT_REPLACE)
				add_missing_parents(ctx, commit);
		} else if (!repo_parse_commit_no_graph(ctx->r, commit))
			add_missing_parents(ctx, commit);
	}
	stop_progress(&ctx->progress);

	if (ctx->report_progress)
		ctx->progress = start_delayed_progress(
					ctx->r,
					_("Clearing commit marks in commit graph"),
					ctx->oids.nr);
	for (i = 0; i < ctx->oids.nr; i++) {
		display_progress(ctx->progress, i + 1);
		commit = lookup_commit(ctx->r, &ctx->oids.oid[i]);

		if (commit)
			commit->object.flags &= ~REACHABLE;
	}
	stop_progress(&ctx->progress);
}

struct compute_generation_info {
	struct repository *r;
	struct commit_stack *commits;
	struct progress *progress;
	int progress_cnt;

	timestamp_t (*get_generation)(struct commit *c, void *data);
	void (*set_generation)(struct commit *c, timestamp_t gen, void *data);
	void *data;
};

static timestamp_t compute_generation_from_max(struct commit *c,
					       timestamp_t max_gen,
					       int generation_version)
{
	switch (generation_version) {
	case 1: /* topological levels */
		if (max_gen > GENERATION_NUMBER_V1_MAX - 1)
			max_gen = GENERATION_NUMBER_V1_MAX - 1;
		return max_gen + 1;

	case 2: /* corrected commit date */
		if (c->date && c->date > max_gen)
			max_gen = c->date - 1;
		return max_gen + 1;

	default:
		BUG("attempting unimplemented version");
	}
}

static void compute_reachable_generation_numbers(
			struct compute_generation_info *info,
			int generation_version)
{
	int i;
	struct commit_list *list = NULL;

	for (i = 0; i < info->commits->nr; i++) {
		struct commit *c = info->commits->items[i];
		timestamp_t gen;
		repo_parse_commit(info->r, c);
		gen = info->get_generation(c, info->data);
		display_progress(info->progress, ++info->progress_cnt);

		if (gen != GENERATION_NUMBER_ZERO && gen != GENERATION_NUMBER_INFINITY)
			continue;

		commit_list_insert(c, &list);
		while (list) {
			struct commit *current = list->item;
			struct commit_list *parent;
			int all_parents_computed = 1;
			uint32_t max_gen = 0;

			for (parent = current->parents; parent; parent = parent->next) {
				repo_parse_commit(info->r, parent->item);
				gen = info->get_generation(parent->item, info->data);

				if (gen == GENERATION_NUMBER_ZERO) {
					all_parents_computed = 0;
					commit_list_insert(parent->item, &list);
					break;
				}

				if (gen > max_gen)
					max_gen = gen;
			}

			if (all_parents_computed) {
				pop_commit(&list);
				gen = compute_generation_from_max(
						current, max_gen,
						generation_version);
				info->set_generation(current, gen, info->data);
			}
		}
	}
}

static timestamp_t get_topo_level(struct commit *c, void *data)
{
	struct write_commit_graph_context *ctx = data;
	return *topo_level_slab_at(ctx->topo_levels, c);
}

static void set_topo_level(struct commit *c, timestamp_t t, void *data)
{
	struct write_commit_graph_context *ctx = data;
	*topo_level_slab_at(ctx->topo_levels, c) = (uint32_t)t;
}

static void compute_topological_levels(struct write_commit_graph_context *ctx)
{
	struct compute_generation_info info = {
		.r = ctx->r,
		.commits = &ctx->commits,
		.get_generation = get_topo_level,
		.set_generation = set_topo_level,
		.data = ctx,
	};

	if (ctx->report_progress)
		info.progress = ctx->progress
			      = start_delayed_progress(
					ctx->r,
					_("Computing commit graph topological levels"),
					ctx->commits.nr);

	compute_reachable_generation_numbers(&info, 1);

	stop_progress(&ctx->progress);
}

static timestamp_t get_generation_from_graph_data(struct commit *c,
						  void *data UNUSED)
{
	return commit_graph_data_at(c)->generation;
}

static void set_generation_v2(struct commit *c, timestamp_t t,
			      void *data UNUSED)
{
	struct commit_graph_data *g = commit_graph_data_at(c);
	g->generation = t;
}

static void compute_generation_numbers(struct write_commit_graph_context *ctx)
{
	int i;
	struct compute_generation_info info = {
		.r = ctx->r,
		.commits = &ctx->commits,
		.get_generation = get_generation_from_graph_data,
		.set_generation = set_generation_v2,
	};

	if (ctx->report_progress)
		info.progress = ctx->progress
			      = start_delayed_progress(
					ctx->r,
					_("Computing commit graph generation numbers"),
					ctx->commits.nr);

	if (!ctx->trust_generation_numbers) {
		for (i = 0; i < ctx->commits.nr; i++) {
			struct commit *c = ctx->commits.items[i];
			repo_parse_commit(ctx->r, c);
			commit_graph_data_at(c)->generation = GENERATION_NUMBER_ZERO;
		}
	}

	compute_reachable_generation_numbers(&info, 2);

	for (i = 0; i < ctx->commits.nr; i++) {
		struct commit *c = ctx->commits.items[i];
		timestamp_t offset = commit_graph_data_at(c)->generation - c->date;
		if (offset > GENERATION_NUMBER_V2_OFFSET_MAX)
			ctx->num_generation_data_overflows++;
	}
	stop_progress(&ctx->progress);
}

static void set_generation_in_graph_data(struct commit *c, timestamp_t t,
					 void *data UNUSED)
{
	commit_graph_data_at(c)->generation = t;
}

/*
 * After this method, all commits reachable from those in the given
 * list will have non-zero, non-infinite generation numbers.
 */
void ensure_generations_valid(struct repository *r,
			      struct commit **commits, size_t nr)
{
	int generation_version = get_configured_generation_version(r);
	struct commit_stack list = {
		.items = commits,
		.alloc = nr,
		.nr = nr,
	};
	struct compute_generation_info info = {
		.r = r,
		.commits = &list,
		.get_generation = get_generation_from_graph_data,
		.set_generation = set_generation_in_graph_data,
	};

	compute_reachable_generation_numbers(&info, generation_version);
}

static void trace2_bloom_filter_write_statistics(struct write_commit_graph_context *ctx)
{
	trace2_data_intmax("commit-graph", ctx->r, "filter-computed",
			   ctx->count_bloom_filter_computed);
	trace2_data_intmax("commit-graph", ctx->r, "filter-not-computed",
			   ctx->count_bloom_filter_not_computed);
	trace2_data_intmax("commit-graph", ctx->r, "filter-trunc-empty",
			   ctx->count_bloom_filter_trunc_empty);
	trace2_data_intmax("commit-graph", ctx->r, "filter-trunc-large",
			   ctx->count_bloom_filter_trunc_large);
	trace2_data_intmax("commit-graph", ctx->r, "filter-upgraded",
			   ctx->count_bloom_filter_upgraded);
}

static void compute_bloom_filters(struct write_commit_graph_context *ctx)
{
	int i;
	struct progress *progress = NULL;
	struct commit **sorted_commits;
	int max_new_filters;

	init_bloom_filters();

	if (ctx->report_progress)
		progress = start_delayed_progress(
			ctx->r,
			_("Computing commit changed paths Bloom filters"),
			ctx->commits.nr);

	DUP_ARRAY(sorted_commits, ctx->commits.items, ctx->commits.nr);

	if (ctx->order_by_pack)
		QSORT(sorted_commits, ctx->commits.nr, commit_pos_cmp);
	else
		QSORT(sorted_commits, ctx->commits.nr, commit_gen_cmp);

	max_new_filters = ctx->opts && ctx->opts->max_new_filters >= 0 ?
		ctx->opts->max_new_filters : ctx->commits.nr;

	for (i = 0; i < ctx->commits.nr; i++) {
		enum bloom_filter_computed computed = 0;
		struct commit *c = sorted_commits[i];
		struct bloom_filter *filter = get_or_compute_bloom_filter(
			ctx->r,
			c,
			ctx->count_bloom_filter_computed < max_new_filters,
			ctx->bloom_settings,
			&computed);
		if (computed & BLOOM_COMPUTED) {
			ctx->count_bloom_filter_computed++;
			if (computed & BLOOM_TRUNC_EMPTY)
				ctx->count_bloom_filter_trunc_empty++;
			if (computed & BLOOM_TRUNC_LARGE)
				ctx->count_bloom_filter_trunc_large++;
		} else if (computed & BLOOM_UPGRADED) {
			ctx->count_bloom_filter_upgraded++;
		} else if (computed & BLOOM_NOT_COMPUTED)
			ctx->count_bloom_filter_not_computed++;
		ctx->total_bloom_filter_data_size += filter
			? sizeof(unsigned char) * filter->len : 0;
		display_progress(progress, i + 1);
	}

	if (trace2_is_enabled())
		trace2_bloom_filter_write_statistics(ctx);

	free(sorted_commits);
	stop_progress(&progress);
}

struct refs_cb_data {
	struct repository *repo;
	struct oidset *commits;
	struct progress *progress;
};

static int add_ref_to_set(const struct reference *ref, void *cb_data)
{
	const struct object_id *maybe_peeled = ref->oid;
	struct object_id peeled;
	struct refs_cb_data *data = (struct refs_cb_data *)cb_data;

	if (!reference_get_peeled_oid(data->repo, ref, &peeled))
		maybe_peeled = &peeled;
	if (odb_read_object_info(data->repo->objects, maybe_peeled, NULL) == OBJ_COMMIT)
		oidset_insert(data->commits, maybe_peeled);

	display_progress(data->progress, oidset_size(data->commits));

	return 0;
}

int write_commit_graph_reachable(struct odb_source *source,
				 enum commit_graph_write_flags flags,
				 const struct commit_graph_opts *opts)
{
	struct oidset commits = OIDSET_INIT;
	struct refs_cb_data data;
	int result;

	memset(&data, 0, sizeof(data));
	data.repo = source->odb->repo;
	data.commits = &commits;

	if (flags & COMMIT_GRAPH_WRITE_PROGRESS)
		data.progress = start_delayed_progress(
			source->odb->repo,
			_("Collecting referenced commits"), 0);

	refs_for_each_ref(get_main_ref_store(source->odb->repo), add_ref_to_set,
			  &data);

	stop_progress(&data.progress);

	result = write_commit_graph(source, NULL, &commits,
				    flags, opts);

	oidset_clear(&commits);
	return result;
}

static int fill_oids_from_packs(struct write_commit_graph_context *ctx,
				const struct string_list *pack_indexes)
{
	uint32_t i;
	struct strbuf progress_title = STRBUF_INIT;
	struct strbuf packname = STRBUF_INIT;
	int dirlen;
	int ret = 0;

	strbuf_addf(&packname, "%s/pack/", ctx->odb_source->path);
	dirlen = packname.len;
	if (ctx->report_progress) {
		strbuf_addf(&progress_title,
			    Q_("Finding commits for commit graph in %"PRIuMAX" pack",
			       "Finding commits for commit graph in %"PRIuMAX" packs",
			       pack_indexes->nr),
			    (uintmax_t)pack_indexes->nr);
		ctx->progress = start_delayed_progress(ctx->r,
						       progress_title.buf, 0);
		ctx->progress_done = 0;
	}
	for (i = 0; i < pack_indexes->nr; i++) {
		struct packed_git *p;
		strbuf_setlen(&packname, dirlen);
		strbuf_addstr(&packname, pack_indexes->items[i].string);
		p = add_packed_git(ctx->r, packname.buf, packname.len, 1);
		if (!p) {
			ret = error(_("error adding pack %s"), packname.buf);
			goto cleanup;
		}
		if (open_pack_index(p)) {
			ret = error(_("error opening index for %s"), packname.buf);
			close_pack(p);
			free(p);
			goto cleanup;
		}
		for_each_object_in_pack(p, add_packed_commits, ctx,
					FOR_EACH_OBJECT_PACK_ORDER);
		close_pack(p);
		free(p);
	}

cleanup:
	stop_progress(&ctx->progress);
	strbuf_release(&progress_title);
	strbuf_release(&packname);

	return ret;
}

static int fill_oids_from_commits(struct write_commit_graph_context *ctx,
				  struct oidset *commits)
{
	struct oidset_iter iter;
	struct object_id *oid;

	if (!oidset_size(commits))
		return 0;

	oidset_iter_init(commits, &iter);
	while ((oid = oidset_iter_next(&iter))) {
		oid_array_append(&ctx->oids, oid);
	}

	return 0;
}

static void fill_oids_from_all_packs(struct write_commit_graph_context *ctx)
{
	if (ctx->report_progress)
		ctx->progress = start_delayed_progress(
			ctx->r,
			_("Finding commits for commit graph among packed objects"),
			ctx->approx_nr_objects);
	for_each_packed_object(ctx->r, add_packed_commits, ctx,
			       FOR_EACH_OBJECT_PACK_ORDER);
	if (ctx->progress_done < ctx->approx_nr_objects)
		display_progress(ctx->progress, ctx->approx_nr_objects);
	stop_progress(&ctx->progress);
}

static void copy_oids_to_commits(struct write_commit_graph_context *ctx)
{
	uint32_t i;
	enum commit_graph_split_flags flags = ctx->opts ?
		ctx->opts->split_flags : COMMIT_GRAPH_SPLIT_UNSPECIFIED;

	ctx->num_extra_edges = 0;
	if (ctx->report_progress)
		ctx->progress = start_delayed_progress(
			ctx->r,
			_("Finding extra edges in commit graph"),
			ctx->oids.nr);
	oid_array_sort(&ctx->oids);
	for (i = 0; i < ctx->oids.nr; i = oid_array_next_unique(&ctx->oids, i)) {
		unsigned int num_parents;
		struct commit *commit;

		display_progress(ctx->progress, i + 1);

		commit = lookup_commit(ctx->r, &ctx->oids.oid[i]);

		if (ctx->split && flags != COMMIT_GRAPH_SPLIT_REPLACE &&
		    commit_graph_position(commit) != COMMIT_NOT_FROM_GRAPH)
			continue;

		if (ctx->split && flags == COMMIT_GRAPH_SPLIT_REPLACE)
			repo_parse_commit(ctx->r, commit);
		else
			repo_parse_commit_no_graph(ctx->r, commit);

		num_parents = commit_list_count(commit->parents);
		if (num_parents > 2)
			ctx->num_extra_edges += num_parents - 1;

		commit_stack_push(&ctx->commits, commit);
	}
	stop_progress(&ctx->progress);
}

static int write_graph_chunk_base_1(struct hashfile *f,
				    struct commit_graph *g)
{
	int num = 0;

	if (!g)
		return 0;

	num = write_graph_chunk_base_1(f, g->base_graph);
	hashwrite(f, g->oid.hash, g->hash_algo->rawsz);
	return num + 1;
}

static int write_graph_chunk_base(struct hashfile *f,
				    void *data)
{
	struct write_commit_graph_context *ctx = data;
	int num = write_graph_chunk_base_1(f, ctx->new_base_graph);

	if (num != ctx->num_commit_graphs_after - 1) {
		error(_("failed to write correct number of base graph ids"));
		return -1;
	}

	return 0;
}

static int write_commit_graph_file(struct write_commit_graph_context *ctx)
{
	uint32_t i;
	struct hashfile *f;
	struct tempfile *graph_layer; /* when ctx->split is non-zero */
	struct lock_file lk = LOCK_INIT;
	const unsigned hashsz = ctx->r->hash_algo->rawsz;
	struct strbuf progress_title = STRBUF_INIT;
	struct chunkfile *cf;
	unsigned char file_hash[GIT_MAX_RAWSZ];

	if (ctx->split) {
		struct strbuf tmp_file = STRBUF_INIT;

		strbuf_addf(&tmp_file,
			    "%s/info/commit-graphs/tmp_graph_XXXXXX",
			    ctx->odb_source->path);
		ctx->graph_name = strbuf_detach(&tmp_file, NULL);
	} else {
		ctx->graph_name = get_commit_graph_filename(ctx->odb_source);
	}

	if (safe_create_leading_directories(ctx->r, ctx->graph_name)) {
		error(_("unable to create leading directories of %s"),
			ctx->graph_name);
		return -1;
	}

	if (ctx->split) {
		char *lock_name = get_commit_graph_chain_filename(ctx->odb_source);

		hold_lock_file_for_update_mode(&lk, lock_name,
					       LOCK_DIE_ON_ERROR, 0444);
		free(lock_name);

		graph_layer = mks_tempfile_m(ctx->graph_name, 0444);
		if (!graph_layer) {
			error(_("unable to create temporary graph layer"));
			return -1;
		}

		if (adjust_shared_perm(ctx->r, get_tempfile_path(graph_layer))) {
			error(_("unable to adjust shared permissions for '%s'"),
			      get_tempfile_path(graph_layer));
			return -1;
		}

		f = hashfd(ctx->r->hash_algo,
			   get_tempfile_fd(graph_layer), get_tempfile_path(graph_layer));
	} else {
		hold_lock_file_for_update_mode(&lk, ctx->graph_name,
					       LOCK_DIE_ON_ERROR, 0444);
		f = hashfd(ctx->r->hash_algo,
			   get_lock_file_fd(&lk), get_lock_file_path(&lk));
	}

	cf = init_chunkfile(f);

	add_chunk(cf, GRAPH_CHUNKID_OIDFANOUT, GRAPH_FANOUT_SIZE,
		  write_graph_chunk_fanout);
	add_chunk(cf, GRAPH_CHUNKID_OIDLOOKUP, st_mult(hashsz, ctx->commits.nr),
		  write_graph_chunk_oids);
	add_chunk(cf, GRAPH_CHUNKID_DATA, st_mult(hashsz + 16, ctx->commits.nr),
		  write_graph_chunk_data);

	if (ctx->write_generation_data)
		add_chunk(cf, GRAPH_CHUNKID_GENERATION_DATA,
			  st_mult(sizeof(uint32_t), ctx->commits.nr),
			  write_graph_chunk_generation_data);
	if (ctx->num_generation_data_overflows)
		add_chunk(cf, GRAPH_CHUNKID_GENERATION_DATA_OVERFLOW,
			  st_mult(sizeof(timestamp_t), ctx->num_generation_data_overflows),
			  write_graph_chunk_generation_data_overflow);
	if (ctx->num_extra_edges)
		add_chunk(cf, GRAPH_CHUNKID_EXTRAEDGES,
			  st_mult(4, ctx->num_extra_edges),
			  write_graph_chunk_extra_edges);
	if (ctx->changed_paths) {
		add_chunk(cf, GRAPH_CHUNKID_BLOOMINDEXES,
			  st_mult(sizeof(uint32_t), ctx->commits.nr),
			  write_graph_chunk_bloom_indexes);
		add_chunk(cf, GRAPH_CHUNKID_BLOOMDATA,
			  st_add(sizeof(uint32_t) * 3,
				 ctx->total_bloom_filter_data_size),
			  write_graph_chunk_bloom_data);
	}
	if (ctx->num_commit_graphs_after > 1)
		add_chunk(cf, GRAPH_CHUNKID_BASE,
			  st_mult(hashsz, ctx->num_commit_graphs_after - 1),
			  write_graph_chunk_base);

	hashwrite_be32(f, GRAPH_SIGNATURE);

	hashwrite_u8(f, GRAPH_VERSION);
	hashwrite_u8(f, oid_version(ctx->r->hash_algo));
	hashwrite_u8(f, get_num_chunks(cf));
	hashwrite_u8(f, ctx->num_commit_graphs_after - 1);

	if (ctx->report_progress) {
		strbuf_addf(&progress_title,
			    Q_("Writing out commit graph in %d pass",
			       "Writing out commit graph in %d passes",
			       get_num_chunks(cf)),
			    get_num_chunks(cf));
		ctx->progress = start_delayed_progress(
			ctx->r,
			progress_title.buf,
			st_mult(get_num_chunks(cf), ctx->commits.nr));
	}

	write_chunkfile(cf, ctx);

	stop_progress(&ctx->progress);
	strbuf_release(&progress_title);

	if (ctx->split && ctx->base_graph_name && ctx->num_commit_graphs_after > 1) {
		char *new_base_hash = xstrdup(oid_to_hex(&ctx->new_base_graph->oid));
		char *new_base_name = get_split_graph_filename(ctx->new_base_graph->odb_source, new_base_hash);

		free(ctx->commit_graph_filenames_after[ctx->num_commit_graphs_after - 2]);
		free(ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 2]);
		ctx->commit_graph_filenames_after[ctx->num_commit_graphs_after - 2] = new_base_name;
		ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 2] = new_base_hash;
	}

	close_commit_graph(ctx->r->objects);
	finalize_hashfile(f, file_hash, FSYNC_COMPONENT_COMMIT_GRAPH,
			  CSUM_HASH_IN_STREAM | CSUM_FSYNC);
	free_chunkfile(cf);

	if (ctx->split) {
		FILE *chainf = fdopen_lock_file(&lk, "w");
		char *final_graph_name;
		int result;

		if (!chainf) {
			error(_("unable to open commit-graph chain file"));
			return -1;
		}

		if (ctx->base_graph_name) {
			const char *dest;
			int idx = ctx->num_commit_graphs_after - 1;
			if (ctx->num_commit_graphs_after > 1)
				idx--;

			dest = ctx->commit_graph_filenames_after[idx];

			if (strcmp(ctx->base_graph_name, dest)) {
				result = rename(ctx->base_graph_name, dest);

				if (result) {
					error(_("failed to rename base commit-graph file"));
					return -1;
				}
			}
		} else {
			char *graph_name = get_commit_graph_filename(ctx->odb_source);
			unlink(graph_name);
			free(graph_name);
		}

		free(ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1]);
		ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1] =
			xstrdup(hash_to_hex_algop(file_hash, ctx->r->hash_algo));
		final_graph_name = get_split_graph_filename(ctx->odb_source,
					ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1]);
		free(ctx->commit_graph_filenames_after[ctx->num_commit_graphs_after - 1]);
		ctx->commit_graph_filenames_after[ctx->num_commit_graphs_after - 1] = final_graph_name;

		result = rename_tempfile(&graph_layer, final_graph_name);

		for (i = 0; i < ctx->num_commit_graphs_after; i++)
			fprintf(get_lock_file_fp(&lk), "%s\n", ctx->commit_graph_hash_after[i]);

		if (result) {
			error(_("failed to rename temporary commit-graph file"));
			return -1;
		}
	}

	commit_lock_file(&lk);

	return 0;
}

static void split_graph_merge_strategy(struct write_commit_graph_context *ctx,
				       struct commit_graph *graph_to_merge)
{
	struct commit_graph *g;
	uint32_t num_commits;
	enum commit_graph_split_flags flags = COMMIT_GRAPH_SPLIT_UNSPECIFIED;
	uint32_t i;

	int max_commits = 0;
	int size_mult = 2;

	if (ctx->opts) {
		max_commits = ctx->opts->max_commits;

		if (ctx->opts->size_multiple)
			size_mult = ctx->opts->size_multiple;

		flags = ctx->opts->split_flags;
	}

	g = graph_to_merge;
	num_commits = ctx->commits.nr;
	if (flags == COMMIT_GRAPH_SPLIT_REPLACE)
		ctx->num_commit_graphs_after = 1;
	else
		ctx->num_commit_graphs_after = ctx->num_commit_graphs_before + 1;

	if (flags != COMMIT_GRAPH_SPLIT_MERGE_PROHIBITED &&
	    flags != COMMIT_GRAPH_SPLIT_REPLACE) {
		while (g && (g->num_commits <= st_mult(size_mult, num_commits) ||
			    (max_commits && num_commits > max_commits))) {
			if (g->odb_source != ctx->odb_source)
				break;

			if (unsigned_add_overflows(num_commits, g->num_commits))
				die(_("cannot merge graphs with %"PRIuMAX", "
				      "%"PRIuMAX" commits"),
				    (uintmax_t)num_commits,
				    (uintmax_t)g->num_commits);
			num_commits += g->num_commits;
			g = g->base_graph;

			ctx->num_commit_graphs_after--;
		}
	}

	if (flags != COMMIT_GRAPH_SPLIT_REPLACE)
		ctx->new_base_graph = g;
	else if (ctx->num_commit_graphs_after != 1)
		BUG("split_graph_merge_strategy: num_commit_graphs_after "
		    "should be 1 with --split=replace");

	if (ctx->num_commit_graphs_after == 2) {
		char *old_graph_name = get_commit_graph_filename(g->odb_source);

		if (!strcmp(g->filename, old_graph_name) &&
		    g->odb_source != ctx->odb_source) {
			ctx->num_commit_graphs_after = 1;
			ctx->new_base_graph = NULL;
		}

		free(old_graph_name);
	}

	CALLOC_ARRAY(ctx->commit_graph_filenames_after, ctx->num_commit_graphs_after);
	CALLOC_ARRAY(ctx->commit_graph_hash_after, ctx->num_commit_graphs_after);

	for (i = 0; i < ctx->num_commit_graphs_after &&
		    i < ctx->num_commit_graphs_before; i++)
		ctx->commit_graph_filenames_after[i] = xstrdup(ctx->commit_graph_filenames_before[i]);

	i = ctx->num_commit_graphs_before - 1;
	g = graph_to_merge;

	while (g) {
		if (i < ctx->num_commit_graphs_after)
			ctx->commit_graph_hash_after[i] = xstrdup(oid_to_hex(&g->oid));

		/*
		 * If the topmost remaining layer has generation data chunk, the
		 * resultant layer also has generation data chunk.
		 */
		if (i == ctx->num_commit_graphs_after - 2)
			ctx->write_generation_data = !!g->chunk_generation_data;

		i--;
		g = g->base_graph;
	}
}

static void merge_commit_graph(struct write_commit_graph_context *ctx,
			       struct commit_graph *g)
{
	uint32_t i;
	uint32_t offset = g->num_commits_in_base;

	if (unsigned_add_overflows(ctx->commits.nr, g->num_commits))
		die(_("cannot merge graph %s, too many commits: %"PRIuMAX),
		    oid_to_hex(&g->oid),
		    (uintmax_t)st_add(ctx->commits.nr, g->num_commits));

	commit_stack_grow(&ctx->commits, g->num_commits);

	for (i = 0; i < g->num_commits; i++) {
		struct object_id oid;
		struct commit *result;

		display_progress(ctx->progress, i + 1);

		load_oid_from_graph(g, i + offset, &oid);

		/* only add commits if they still exist in the repo */
		result = lookup_commit_reference_gently(ctx->r, &oid, 1);

		if (result)
			commit_stack_push(&ctx->commits, result);
	}
}

static int commit_compare(const void *_a, const void *_b)
{
	const struct commit *a = *(const struct commit **)_a;
	const struct commit *b = *(const struct commit **)_b;
	return oidcmp(&a->object.oid, &b->object.oid);
}

static void sort_and_scan_merged_commits(struct write_commit_graph_context *ctx)
{
	uint32_t i, dedup_i = 0;

	if (ctx->report_progress)
		ctx->progress = start_delayed_progress(
					ctx->r,
					_("Scanning merged commits"),
					ctx->commits.nr);

	QSORT(ctx->commits.items, ctx->commits.nr, commit_compare);

	ctx->num_extra_edges = 0;
	for (i = 0; i < ctx->commits.nr; i++) {
		display_progress(ctx->progress, i + 1);

		if (i && oideq(&ctx->commits.items[i - 1]->object.oid,
			  &ctx->commits.items[i]->object.oid)) {
			/*
			 * Silently ignore duplicates. These were likely
			 * created due to a commit appearing in multiple
			 * layers of the chain, which is unexpected but
			 * not invalid. We should make sure there is a
			 * unique copy in the new layer.
			 */
		} else {
			unsigned int num_parents;

			ctx->commits.items[dedup_i] = ctx->commits.items[i];
			dedup_i++;

			num_parents = commit_list_count(ctx->commits.items[i]->parents);
			if (num_parents > 2)
				ctx->num_extra_edges += num_parents - 1;
		}
	}

	ctx->commits.nr = dedup_i;

	stop_progress(&ctx->progress);
}

static void merge_commit_graphs(struct write_commit_graph_context *ctx,
				struct commit_graph *g)
{
	uint32_t current_graph_number = ctx->num_commit_graphs_before;

	while (g && current_graph_number >= ctx->num_commit_graphs_after) {
		current_graph_number--;

		if (ctx->report_progress)
			ctx->progress = start_delayed_progress(ctx->r,
							       _("Merging commit-graph"), 0);

		merge_commit_graph(ctx, g);
		stop_progress(&ctx->progress);

		g = g->base_graph;
	}

	if (g) {
		ctx->new_base_graph = g;
		ctx->new_num_commits_in_base = g->num_commits + g->num_commits_in_base;
	}

	if (ctx->new_base_graph)
		ctx->base_graph_name = xstrdup(ctx->new_base_graph->filename);

	sort_and_scan_merged_commits(ctx);
}

static void mark_commit_graphs(struct write_commit_graph_context *ctx)
{
	uint32_t i;
	time_t now = time(NULL);

	for (i = ctx->num_commit_graphs_after - 1; i < ctx->num_commit_graphs_before; i++) {
		struct stat st;
		struct utimbuf updated_time;

		if (stat(ctx->commit_graph_filenames_before[i], &st) < 0)
			continue;

		updated_time.actime = st.st_atime;
		updated_time.modtime = now;
		utime(ctx->commit_graph_filenames_before[i], &updated_time);
	}
}

static void expire_commit_graphs(struct write_commit_graph_context *ctx)
{
	struct strbuf path = STRBUF_INIT;
	DIR *dir;
	struct dirent *de;
	size_t dirnamelen;
	timestamp_t expire_time = time(NULL);

	if (ctx->opts && ctx->opts->expire_time)
		expire_time = ctx->opts->expire_time;
	if (!ctx->split) {
		char *chain_file_name = get_commit_graph_chain_filename(ctx->odb_source);
		unlink(chain_file_name);
		free(chain_file_name);
		ctx->num_commit_graphs_after = 0;
	}

	strbuf_addstr(&path, ctx->odb_source->path);
	strbuf_addstr(&path, "/info/commit-graphs");
	dir = opendir(path.buf);

	if (!dir)
		goto out;

	strbuf_addch(&path, '/');
	dirnamelen = path.len;
	while ((de = readdir(dir)) != NULL) {
		struct stat st;
		uint32_t i, found = 0;

		strbuf_setlen(&path, dirnamelen);
		strbuf_addstr(&path, de->d_name);

		if (stat(path.buf, &st) < 0)
			continue;

		if (st.st_mtime > expire_time)
			continue;
		if (path.len < 6 || strcmp(path.buf + path.len - 6, ".graph"))
			continue;

		for (i = 0; i < ctx->num_commit_graphs_after; i++) {
			if (!strcmp(ctx->commit_graph_filenames_after[i],
				    path.buf)) {
				found = 1;
				break;
			}
		}

		if (!found)
			unlink(path.buf);
	}

out:
	if(dir)
		closedir(dir);
	strbuf_release(&path);
}

int write_commit_graph(struct odb_source *source,
		       const struct string_list *const pack_indexes,
		       struct oidset *commits,
		       enum commit_graph_write_flags flags,
		       const struct commit_graph_opts *opts)
{
	struct repository *r = source->odb->repo;
	struct write_commit_graph_context ctx = {
		.r = r,
		.odb_source = source,
		.append = flags & COMMIT_GRAPH_WRITE_APPEND ? 1 : 0,
		.report_progress = flags & COMMIT_GRAPH_WRITE_PROGRESS ? 1 : 0,
		.split = flags & COMMIT_GRAPH_WRITE_SPLIT ? 1 : 0,
		.opts = opts,
		.total_bloom_filter_data_size = 0,
		.write_generation_data = (get_configured_generation_version(r) == 2),
		.num_generation_data_overflows = 0,
	};
	uint32_t i;
	int res = 0;
	int replace = 0;
	struct bloom_filter_settings bloom_settings = DEFAULT_BLOOM_FILTER_SETTINGS;
	struct topo_level_slab topo_levels;
	struct commit_graph *g;

	prepare_repo_settings(r);
	if (!r->settings.core_commit_graph) {
		warning(_("attempting to write a commit-graph, but 'core.commitGraph' is disabled"));
		return 0;
	}
	if (!commit_graph_compatible(r))
		return 0;
	if (r->settings.commit_graph_changed_paths_version < -1
	    || r->settings.commit_graph_changed_paths_version > 2) {
		warning(_("attempting to write a commit-graph, but "
			  "'commitGraph.changedPathsVersion' (%d) is not supported"),
			r->settings.commit_graph_changed_paths_version);
		return 0;
	}

	bloom_settings.hash_version = r->settings.commit_graph_changed_paths_version;
	bloom_settings.bits_per_entry = git_env_ulong("GIT_TEST_BLOOM_SETTINGS_BITS_PER_ENTRY",
						      bloom_settings.bits_per_entry);
	bloom_settings.num_hashes = git_env_ulong("GIT_TEST_BLOOM_SETTINGS_NUM_HASHES",
						  bloom_settings.num_hashes);
	bloom_settings.max_changed_paths = git_env_ulong("GIT_TEST_BLOOM_SETTINGS_MAX_CHANGED_PATHS",
							 bloom_settings.max_changed_paths);
	ctx.bloom_settings = &bloom_settings;

	init_topo_level_slab(&topo_levels);
	ctx.topo_levels = &topo_levels;

	g = prepare_commit_graph(ctx.r);
	for (struct commit_graph *chain = g; chain; chain = chain->base_graph)
		g->topo_levels = &topo_levels;

	if (flags & COMMIT_GRAPH_WRITE_BLOOM_FILTERS)
		ctx.changed_paths = 1;
	if (!(flags & COMMIT_GRAPH_NO_WRITE_BLOOM_FILTERS)) {
		/* We have changed-paths already. Keep them in the next graph */
		if (g && g->bloom_filter_settings) {
			ctx.changed_paths = 1;

			/* don't propagate the hash_version unless unspecified */
			if (bloom_settings.hash_version == -1)
				bloom_settings.hash_version = g->bloom_filter_settings->hash_version;
			bloom_settings.bits_per_entry = g->bloom_filter_settings->bits_per_entry;
			bloom_settings.num_hashes = g->bloom_filter_settings->num_hashes;
			bloom_settings.max_changed_paths = g->bloom_filter_settings->max_changed_paths;
		}
	}

	bloom_settings.hash_version = bloom_settings.hash_version == 2 ? 2 : 1;

	if (ctx.split) {
		for (struct commit_graph *chain = g; chain; chain = chain->base_graph)
			ctx.num_commit_graphs_before++;

		if (ctx.num_commit_graphs_before) {
			ALLOC_ARRAY(ctx.commit_graph_filenames_before, ctx.num_commit_graphs_before);
			i = ctx.num_commit_graphs_before;

			for (struct commit_graph *chain = g; chain; chain = chain->base_graph)
				ctx.commit_graph_filenames_before[--i] = xstrdup(chain->filename);
		}

		if (ctx.opts)
			replace = ctx.opts->split_flags & COMMIT_GRAPH_SPLIT_REPLACE;
	}

	ctx.approx_nr_objects = repo_approximate_object_count(r);

	if (ctx.append && g) {
		for (i = 0; i < g->num_commits; i++) {
			struct object_id oid;
			oidread(&oid, g->chunk_oid_lookup + st_mult(g->hash_algo->rawsz, i),
				r->hash_algo);
			oid_array_append(&ctx.oids, &oid);
		}
	}

	if (pack_indexes) {
		ctx.order_by_pack = 1;
		if ((res = fill_oids_from_packs(&ctx, pack_indexes)))
			goto cleanup;
	}

	if (commits) {
		if ((res = fill_oids_from_commits(&ctx, commits)))
			goto cleanup;
	}

	if (!pack_indexes && !commits) {
		ctx.order_by_pack = 1;
		fill_oids_from_all_packs(&ctx);
	}

	close_reachable(&ctx);

	copy_oids_to_commits(&ctx);

	if (ctx.commits.nr >= GRAPH_EDGE_LAST_MASK) {
		error(_("too many commits to write graph"));
		res = -1;
		goto cleanup;
	}

	if (!ctx.commits.nr && !replace)
		goto cleanup;

	if (ctx.split) {
		split_graph_merge_strategy(&ctx, g);

		if (!replace)
			merge_commit_graphs(&ctx, g);
	} else {
		ctx.num_commit_graphs_after = 1;
	}

	ctx.trust_generation_numbers = validate_mixed_generation_chain(g);

	compute_topological_levels(&ctx);
	if (ctx.write_generation_data)
		compute_generation_numbers(&ctx);

	if (ctx.changed_paths)
		compute_bloom_filters(&ctx);

	res = write_commit_graph_file(&ctx);

	if (ctx.changed_paths)
		deinit_bloom_filters();

	if (ctx.split)
		mark_commit_graphs(&ctx);

	expire_commit_graphs(&ctx);

cleanup:
	free(ctx.graph_name);
	free(ctx.base_graph_name);
	commit_stack_clear(&ctx.commits);
	oid_array_clear(&ctx.oids);
	clear_topo_level_slab(&topo_levels);

	if (ctx.r->objects->commit_graph) {
		struct commit_graph *g = ctx.r->objects->commit_graph;

		while (g) {
			g->topo_levels = NULL;
			g = g->base_graph;
		}
	}

	for (i = 0; i < ctx.num_commit_graphs_before; i++)
		free(ctx.commit_graph_filenames_before[i]);
	free(ctx.commit_graph_filenames_before);

	for (i = 0; i < ctx.num_commit_graphs_after; i++) {
		free(ctx.commit_graph_filenames_after[i]);
		free(ctx.commit_graph_hash_after[i]);
	}
	free(ctx.commit_graph_filenames_after);
	free(ctx.commit_graph_hash_after);

	return res;
}

#define VERIFY_COMMIT_GRAPH_ERROR_HASH 2
static int verify_commit_graph_error;

__attribute__((format (printf, 1, 2)))
static void graph_report(const char *fmt, ...)
{
	va_list ap;

	verify_commit_graph_error = 1;
	va_start(ap, fmt);
	vfprintf(stderr, fmt, ap);
	fprintf(stderr, "\n");
	va_end(ap);
}

static int commit_graph_checksum_valid(struct commit_graph *g)
{
	return hashfile_checksum_valid(g->hash_algo,
				       g->data, g->data_len);
}

static int verify_one_commit_graph(struct commit_graph *g,
				   struct progress *progress,
				   uint64_t *seen)
{
	struct repository *r = g->odb_source->odb->repo;
	uint32_t i, cur_fanout_pos = 0;
	struct object_id prev_oid, cur_oid;
	struct commit *seen_gen_zero = NULL;
	struct commit *seen_gen_non_zero = NULL;

	if (!commit_graph_checksum_valid(g)) {
		graph_report(_("the commit-graph file has incorrect checksum and is likely corrupt"));
		verify_commit_graph_error = VERIFY_COMMIT_GRAPH_ERROR_HASH;
	}

	for (i = 0; i < g->num_commits; i++) {
		struct commit *graph_commit;

		oidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_algo->rawsz, i),
			g->hash_algo);

		if (i && oidcmp(&prev_oid, &cur_oid) >= 0)
			graph_report(_("commit-graph has incorrect OID order: %s then %s"),
				     oid_to_hex(&prev_oid),
				     oid_to_hex(&cur_oid));

		oidcpy(&prev_oid, &cur_oid);

		while (cur_oid.hash[0] > cur_fanout_pos) {
			uint32_t fanout_value = get_be32(g->chunk_oid_fanout + cur_fanout_pos);

			if (i != fanout_value)
				graph_report(_("commit-graph has incorrect fanout value: fanout[%d] = %u != %u"),
					     cur_fanout_pos, fanout_value, i);
			cur_fanout_pos++;
		}

		graph_commit = lookup_commit(r, &cur_oid);
		if (!parse_commit_in_graph_one(g, graph_commit))
			graph_report(_("failed to parse commit %s from commit-graph"),
				     oid_to_hex(&cur_oid));
	}

	while (cur_fanout_pos < 256) {
		uint32_t fanout_value = get_be32(g->chunk_oid_fanout + cur_fanout_pos);

		if (g->num_commits != fanout_value)
			graph_report(_("commit-graph has incorrect fanout value: fanout[%d] = %u != %u"),
				     cur_fanout_pos, fanout_value, i);

		cur_fanout_pos++;
	}

	if (verify_commit_graph_error & ~VERIFY_COMMIT_GRAPH_ERROR_HASH)
		return verify_commit_graph_error;

	for (i = 0; i < g->num_commits; i++) {
		struct commit *graph_commit, *odb_commit;
		struct commit_list *graph_parents, *odb_parents;
		timestamp_t max_generation = 0;
		timestamp_t generation;

		display_progress(progress, ++(*seen));
		oidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_algo->rawsz, i),
			g->hash_algo);

		graph_commit = lookup_commit(r, &cur_oid);
		odb_commit = (struct commit *)create_object(r, &cur_oid, alloc_commit_node(r));
		if (repo_parse_commit_internal(r, odb_commit, 0, 0)) {
			graph_report(_("failed to parse commit %s from object database for commit-graph"),
				     oid_to_hex(&cur_oid));
			continue;
		}

		if (!oideq(&get_commit_tree_in_graph_one(g, graph_commit)->object.oid,
			   get_commit_tree_oid(odb_commit)))
			graph_report(_("root tree OID for commit %s in commit-graph is %s != %s"),
				     oid_to_hex(&cur_oid),
				     oid_to_hex(get_commit_tree_oid(graph_commit)),
				     oid_to_hex(get_commit_tree_oid(odb_commit)));

		graph_parents = graph_commit->parents;
		odb_parents = odb_commit->parents;

		while (graph_parents) {
			if (!odb_parents) {
				graph_report(_("commit-graph parent list for commit %s is too long"),
					     oid_to_hex(&cur_oid));
				break;
			}

			/* parse parent in case it is in a base graph */
			parse_commit_in_graph_one(g, graph_parents->item);

			if (!oideq(&graph_parents->item->object.oid, &odb_parents->item->object.oid))
				graph_report(_("commit-graph parent for %s is %s != %s"),
					     oid_to_hex(&cur_oid),
					     oid_to_hex(&graph_parents->item->object.oid),
					     oid_to_hex(&odb_parents->item->object.oid));

			generation = commit_graph_generation_from_graph(graph_parents->item);
			if (generation > max_generation)
				max_generation = generation;

			graph_parents = graph_parents->next;
			odb_parents = odb_parents->next;
		}

		if (odb_parents)
			graph_report(_("commit-graph parent list for commit %s terminates early"),
				     oid_to_hex(&cur_oid));

		if (commit_graph_generation_from_graph(graph_commit))
			seen_gen_non_zero = graph_commit;
		else
			seen_gen_zero = graph_commit;

		if (seen_gen_zero)
			continue;

		/*
		 * If we are using topological level and one of our parents has
		 * generation GENERATION_NUMBER_V1_MAX, then our generation is
		 * also GENERATION_NUMBER_V1_MAX. Decrement to avoid extra logic
		 * in the following condition.
		 */
		if (!g->read_generation_data && max_generation == GENERATION_NUMBER_V1_MAX)
			max_generation--;

		generation = commit_graph_generation(graph_commit);
		if (generation < max_generation + 1)
			graph_report(_("commit-graph generation for commit %s is %"PRItime" < %"PRItime),
				     oid_to_hex(&cur_oid),
				     generation,
				     max_generation + 1);

		if (graph_commit->date != odb_commit->date)
			graph_report(_("commit date for commit %s in commit-graph is %"PRItime" != %"PRItime),
				     oid_to_hex(&cur_oid),
				     graph_commit->date,
				     odb_commit->date);
	}

	if (seen_gen_zero && seen_gen_non_zero)
		graph_report(_("commit-graph has both zero and non-zero "
			       "generations (e.g., commits '%s' and '%s')"),
			     oid_to_hex(&seen_gen_zero->object.oid),
			     oid_to_hex(&seen_gen_non_zero->object.oid));

	return verify_commit_graph_error;
}

int verify_commit_graph(struct commit_graph *g, int flags)
{
	struct progress *progress = NULL;
	int local_error = 0;
	uint64_t seen = 0;

	if (!g) {
		graph_report("no commit-graph file loaded");
		return 1;
	}

	if (flags & COMMIT_GRAPH_WRITE_PROGRESS) {
		uint64_t total = g->num_commits;
		if (!(flags & COMMIT_GRAPH_VERIFY_SHALLOW))
			total += g->num_commits_in_base;

		progress = start_progress(g->odb_source->odb->repo,
					  _("Verifying commits in commit graph"),
					  total);
	}

	for (; g; g = g->base_graph) {
		local_error |= verify_one_commit_graph(g, progress, &seen);
		if (flags & COMMIT_GRAPH_VERIFY_SHALLOW)
			break;
	}

	stop_progress(&progress);

	return local_error;
}

void free_commit_graph(struct commit_graph *g)
{
	while (g) {
		struct commit_graph *next = g->base_graph;

		if (g->data)
			munmap((void *)g->data, g->data_len);
		free(g->filename);
		free(g->bloom_filter_settings);
		free(g);

		g = next;
	}
}

void disable_commit_graph(struct repository *r)
{
	r->commit_graph_disabled = 1;
}
