git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 3/6] commit-graph: return the prepared commit graph from `prepare_commit_graph()`

From
Taylor Blau <me@ttaylorr.com>
Date
Sep 11, 2025, 22:25 UTC
Message-ID
<aMNMQdMk2S4MTARG@nand.local>
In-Reply-To
<20250904-b4-pks-commit-graph-via-source-v1-3-d932c2481e1a@pks.im>
On Thu, Sep 04, 2025 at 02:49:57PM +0200, Patrick Steinhardt wrote:
Show 11 quoted lines
> 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.

Hmmph. I see what you're saying, though I'm not sure I agree with the implication here. Presumably "r->objects->commit_graph" could be rewritten as "repo_commit_graph(r->objects->sources)" or similar. But I'm OK with this approach, too.

Show 13 quoted lines
>  int generation_numbers_enabled(struct repository *r)
>  {
>  	uint32_t first_generation;
>  	struct commit_graph *g;
> -	if (!prepare_commit_graph(r))
> -	       return 0;
>
> -	g = r->objects->commit_graph;
> -
> -	if (!g->num_commits)
> -		return 0;
> +	g = prepare_commit_graph(r);
> +	if (!g || !g->num_commits)

Makes sense; this isn't an exact translation, since the conditional now also checks for the NULL-ness of "g" first. But that's necessary, since if the (now-removed) earlier call to prepare_commit_graph() succeeded, we know that "g" is non-NULL here.

Since that function is now responsible for handing us the commit_graph itself, checking for success means that we have to see if "g" is non-NULL first before doing something with it.

Show 12 quoted lines
> @@ -799,12 +796,9 @@ int generation_numbers_enabled(struct repository *r)
>  int corrected_commit_dates_enabled(struct repository *r)
>  {
>  	struct commit_graph *g;
> -	if (!prepare_commit_graph(r))
> -		return 0;
>
> -	g = r->objects->commit_graph;
> -
> -	if (!g->num_commits)
> +	g = prepare_commit_graph(r);
> +	if (!g || !g->num_commits)
Same here.
Show 10 quoted lines
> @@ -1012,23 +1006,26 @@ static int find_commit_pos_in_graph(struct commit *item, struct commit_graph *g,
>  int repo_find_commit_pos_in_graph(struct repository *r, struct commit *c,
>  				  uint32_t *pos)
>  {
> -	if (!prepare_commit_graph(r))
> +	struct commit_graph *g = prepare_commit_graph(r);
> +	if (!g)
>  		return 0;
> -	return find_commit_pos_in_graph(c, r->objects->commit_graph, pos);
> +	return find_commit_pos_in_graph(c, g, pos);

These and other changes may have read a little bit cleaner if there were a preparatory commit which introduced "g" as a variable on the stack, since that would change:

    struct commit_graph *g;
    if (!prepare_commit_graph(r))
        return 0;
    g = the_repository->objects->commit_graph;
into:
    struct commit_graph *g = prepare_commit_graph(r);
    if (!g)
        return 0;

, without affecting the rest of the function, keeping the diff at least easier to read (or smaller) by eliminating the "r->objects->commit_graph" to "g" change.

Not a big deal at all, just a thought that I had while reviewing.
Show 24 quoted lines
> @@ -2519,6 +2518,7 @@ int write_commit_graph(struct odb_source *source,
>  	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) {
> @@ -2547,23 +2547,13 @@ int write_commit_graph(struct odb_source *source,
>  	init_topo_level_slab(&topo_levels);
>  	ctx.topo_levels = &topo_levels;
>
> -	prepare_commit_graph(ctx.r);
> -	if (ctx.r->objects->commit_graph) {
> -		struct commit_graph *g = ctx.r->objects->commit_graph;
> -
> -		while (g) {
> -			g->topo_levels = &topo_levels;
> -			g = g->base_graph;
> -		}
> -	}
> +	g = prepare_commit_graph(ctx.r);
> +	for (struct commit_graph *chain = g; chain; chain = chain->base_graph)
> +		g->topo_levels = &topo_levels;
Makes sense.
The rest looks all good.

Thanks, Taylor

Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 7 of 26 in “odb: track commit graphs via object source”
  1. 0/6 odb: track commit graphs via object sourcePatrick Steinhardt, Sep 4, 2025
  2. 1/6 blame: drop explicit check for commit graphPatrick Steinhardt, Sep 4, 2025
  3. Taylor BlauSep 11, 2025
  4. 2/6 revision: drop explicit check for commit graphPatrick Steinhardt, Sep 4, 2025
  5. Taylor BlauSep 11, 2025
  6. 3/6 commit-graph: return the prepared commit graph from `prepare_commit_graph()`Patrick Steinhardt, Sep 4, 2025
  7. Taylor BlauSep 11, 2025
  8. 4/6 commit-graph: return commit graph from `repo_find_commit_pos_in_graph()`Patrick Steinhardt, Sep 4, 2025
  9. Taylor BlauSep 11, 2025
  10. 5/6 commit-graph: pass graphs that are to be merged as parameterPatrick Steinhardt, Sep 4, 2025
  11. 6/6 odb: move commit-graph into the object sourcesPatrick Steinhardt, Sep 4, 2025
  12. Taylor BlauSep 11, 2025
  13. Junio C HamanoSep 4, 2025
  14. Derrick StoleeSep 5, 2025
  15. Patrick SteinhardtSep 8, 2025
  16. Derrick StoleeSep 8, 2025
  17. Patrick SteinhardtSep 10, 2025
  18. Junio C HamanoSep 25, 2025
  19. Patrick SteinhardtSep 26, 2025
  20. Patrick SteinhardtOct 2, 2025
  21. Patrick SteinhardtOct 2, 2025
  22. Junio C HamanoOct 2, 2025
  23. Derrick StoleeOct 3, 2025
  24. Taylor BlauSep 11, 2025
  25. Junio C HamanoSep 4, 2025
  26. Patrick SteinhardtSep 5, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.