commit-graph: return the prepared commit graph from `prepare_commit_graph()`

When making use of commit graphs, one needs to first prepare them by calling `prepare_commit_graph()`. Once that function was called and the commit graph was prepared successfully, the caller is now expected to access the graph directly via `struct object_database::commit_graph`. In a subsequent change, we're going to move the commit graph pointer from `struct object_database` into `struct odb_source`. With this change, semantics will change so that we use the commit graph of the first source that has one. Consequently, all callers that currently deference the `commit_graph` pointer would now have to loop around the list of sources to find the commit graph. This would become quite unwieldy. So instead of shifting the burden onto such callers, adapt `prepare_commit_graph()` to return the prepared commit graph, if any. Like this, callers are expected to call that function and then use the returned commit graph. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Sep 4, 2025 at 14:49 UTC 199d452758605a3ff15ac7d900653b4de7455e24
1 file changed +32 -50
commit-graph.c
+32 -50
@@ -735,7 +735,7 @@ struct commit_graph *read_commit_graph_one(struct odb_source *source)
735 * On the first invocation, this function attempts to load the commit
736 * graph if the repository is configured to have one.
737 */
738 -static int prepare_commit_graph(struct repository *r)
738 +static struct commit_graph *prepare_commit_graph(struct repository *r)
739 {
740 struct odb_source *source;
741
@@ -747,10 +747,10 @@ static int prepare_commit_graph(struct repository *r)
747 * we want to disable even an already-loaded graph file.
748 */
749 if (!r->gitdir || r->commit_graph_disabled)
750 - return 0;
750 + return NULL;
751
752 if (r->objects->commit_graph_attempted)
753 - return !!r->objects->commit_graph;
753 + return r->objects->commit_graph;
754 r->objects->commit_graph_attempted = 1;
755
756 prepare_repo_settings(r);
@@ -763,10 +763,10 @@ static int prepare_commit_graph(struct repository *r)
763 * so that commit graph loading is not attempted again for this
764 * repository.)
765 */
766 - return 0;
766 + return NULL;
767
768 if (!commit_graph_compatible(r))
769 - return 0;
769 + return NULL;
770
771 odb_prepare_alternates(r->objects);
772 for (source = r->objects->sources; source; source = source->next) {
@@ -775,20 +775,17 @@ static int prepare_commit_graph(struct repository *r)
775 break;
776 }
777
778 - return !!r->objects->commit_graph;
778 + return r->objects->commit_graph;
779 }
780
781 int generation_numbers_enabled(struct repository *r)
782 {
783 uint32_t first_generation;
784 struct commit_graph *g;
785 - if (!prepare_commit_graph(r))
786 - return 0;
785
788 - g = r->objects->commit_graph;
789 -
790 - if (!g->num_commits)
791 - return 0;
786 + g = prepare_commit_graph(r);
787 + if (!g || !g->num_commits)
788 + return 0;
789
790 first_generation = get_be32(g->chunk_commit_data +
791 g->hash_algo->rawsz + 8) >> 2;
@@ -799,12 +796,9 @@ int generation_numbers_enabled(struct repository *r)
796 int corrected_commit_dates_enabled(struct repository *r)
797 {
798 struct commit_graph *g;
802 - if (!prepare_commit_graph(r))
803 - return 0;
799
805 - g = r->objects->commit_graph;
806 -
807 - if (!g->num_commits)
800 + g = prepare_commit_graph(r);
801 + if (!g || !g->num_commits)
802 return 0;
803
804 return g->read_generation_data;
@@ -1012,23 +1006,26 @@ static int find_commit_pos_in_graph(struct commit *item, struct commit_graph *g,
1006 int repo_find_commit_pos_in_graph(struct repository *r, struct commit *c,
1007 uint32_t *pos)
1008 {
1015 - if (!prepare_commit_graph(r))
1009 + struct commit_graph *g = prepare_commit_graph(r);
1010 + if (!g)
1011 return 0;
1017 - return find_commit_pos_in_graph(c, r->objects->commit_graph, pos);
1012 + return find_commit_pos_in_graph(c, g, pos);
1013 }
1014
1015 struct commit *lookup_commit_in_graph(struct repository *repo, const struct object_id *id)
1016 {
1017 static int commit_graph_paranoia = -1;
1018 + struct commit_graph *g;
1019 struct commit *commit;
1020 uint32_t pos;
1021
1022 if (commit_graph_paranoia == -1)
1023 commit_graph_paranoia = git_env_bool(GIT_COMMIT_GRAPH_PARANOIA, 0);
1024
1029 - if (!prepare_commit_graph(repo))
1025 + g = prepare_commit_graph(repo);
1026 + if (!g)
1027 return NULL;
1031 - if (!search_commit_pos_in_graph(id, repo->objects->commit_graph, &pos))
1028 + if (!search_commit_pos_in_graph(id, g, &pos))
1029 return NULL;
1030 if (commit_graph_paranoia && !odb_has_object(repo->objects, id, 0))
1031 return NULL;
@@ -1039,7 +1036,7 @@ struct commit *lookup_commit_in_graph(struct repository *repo, const struct obje
1036 if (commit->object.parsed)
1037 return commit;
1038
1042 - if (!fill_commit_in_graph(commit, repo->objects->commit_graph, pos))
1039 + if (!fill_commit_in_graph(commit, g, pos))
1040 return NULL;
1041
1042 return commit;
@@ -1062,6 +1059,7 @@ static int parse_commit_in_graph_one(struct commit_graph *g,
1059 int parse_commit_in_graph(struct repository *r, struct commit *item)
1060 {
1061 static int checked_env = 0;
1062 + struct commit_graph *g;
1063
1064 if (!checked_env &&
1065 git_env_bool(GIT_TEST_COMMIT_GRAPH_DIE_ON_PARSE, 0))
@@ -1069,9 +1067,10 @@ int parse_commit_in_graph(struct repository *r, struct commit *item)
1067 GIT_TEST_COMMIT_GRAPH_DIE_ON_PARSE);
1068 checked_env = 1;
1069
1072 - if (!prepare_commit_graph(r))
1070 + g = prepare_commit_graph(r);
1071 + if (!g)
1072 return 0;
1074 - return parse_commit_in_graph_one(r->objects->commit_graph, item);
1073 + return parse_commit_in_graph_one(g, item);
1074 }
1075
1076 void load_commit_graph_info(struct repository *r, struct commit *item)
@@ -2519,6 +2518,7 @@ int write_commit_graph(struct odb_source *source,
2518 int replace = 0;
2519 struct bloom_filter_settings bloom_settings = DEFAULT_BLOOM_FILTER_SETTINGS;
2520 struct topo_level_slab topo_levels;
2521 + struct commit_graph *g;
2522
2523 prepare_repo_settings(r);
2524 if (!r->settings.core_commit_graph) {
@@ -2547,23 +2547,13 @@ int write_commit_graph(struct odb_source *source,
2547 init_topo_level_slab(&topo_levels);
2548 ctx.topo_levels = &topo_levels;
2549
2550 - prepare_commit_graph(ctx.r);
2551 - if (ctx.r->objects->commit_graph) {
2552 - struct commit_graph *g = ctx.r->objects->commit_graph;
2553 -
2554 - while (g) {
2555 - g->topo_levels = &topo_levels;
2556 - g = g->base_graph;
2557 - }
2558 - }
2550 + g = prepare_commit_graph(ctx.r);
2551 + for (struct commit_graph *chain = g; chain; chain = chain->base_graph)
2552 + g->topo_levels = &topo_levels;
2553
2554 if (flags & COMMIT_GRAPH_WRITE_BLOOM_FILTERS)
2555 ctx.changed_paths = 1;
2556 if (!(flags & COMMIT_GRAPH_NO_WRITE_BLOOM_FILTERS)) {
2563 - struct commit_graph *g;
2564 -
2565 - g = ctx.r->objects->commit_graph;
2566 -
2557 /* We have changed-paths already. Keep them in the next graph */
2558 if (g && g->bloom_filter_settings) {
2559 ctx.changed_paths = 1;
@@ -2580,22 +2570,15 @@ int write_commit_graph(struct odb_source *source,
2570 bloom_settings.hash_version = bloom_settings.hash_version == 2 ? 2 : 1;
2571
2572 if (ctx.split) {
2583 - struct commit_graph *g = ctx.r->objects->commit_graph;
2584 -
2585 - while (g) {
2573 + for (struct commit_graph *chain = g; chain; chain = chain->base_graph)
2574 ctx.num_commit_graphs_before++;
2587 - g = g->base_graph;
2588 - }
2575
2576 if (ctx.num_commit_graphs_before) {
2577 ALLOC_ARRAY(ctx.commit_graph_filenames_before, ctx.num_commit_graphs_before);
2578 i = ctx.num_commit_graphs_before;
2593 - g = ctx.r->objects->commit_graph;
2579
2595 - while (g) {
2596 - ctx.commit_graph_filenames_before[--i] = xstrdup(g->filename);
2597 - g = g->base_graph;
2598 - }
2580 + for (struct commit_graph *chain = g; chain; chain = chain->base_graph)
2581 + ctx.commit_graph_filenames_before[--i] = xstrdup(chain->filename);
2582 }
2583
2584 if (ctx.opts)
@@ -2604,8 +2587,7 @@ int write_commit_graph(struct odb_source *source,
2587
2588 ctx.approx_nr_objects = repo_approximate_object_count(r);
2589
2607 - if (ctx.append && ctx.r->objects->commit_graph) {
2608 - struct commit_graph *g = ctx.r->objects->commit_graph;
2590 + if (ctx.append && g) {
2591 for (i = 0; i < g->num_commits; i++) {
2592 struct object_id oid;
2593 oidread(&oid, g->chunk_oid_lookup + st_mult(g->hash_algo->rawsz, i),
@@ -2651,7 +2633,7 @@ int write_commit_graph(struct odb_source *source,
2633 } else
2634 ctx.num_commit_graphs_after = 1;
2635
2654 - ctx.trust_generation_numbers = validate_mixed_generation_chain(ctx.r->objects->commit_graph);
2636 + ctx.trust_generation_numbers = validate_mixed_generation_chain(g);
2637
2638 compute_topological_levels(&ctx);
2639 if (ctx.write_generation_data)