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

Re: [PATCH v8 4/4] graph: indent visual root in graph

From
Mirko Faina <mroik@delayed.space>
Date
Jul 10, 2026, 18:07 UTC
Message-ID
<alEroo_DhFaWm3DH@exploit>
In-Reply-To
<20260710-ps-pre-commit-indent-v8-4-d3b636463bf4@gmail.com>
On Fri, Jul 10, 2026 at 12:37:07PM +0200, Pablo Sabater wrote:
Show 63 quoted lines
> When rendering a graph, if the history contains multiple "visual roots",
> actual roots or commits that look like roots (i.e. have their parents
> filtered out) can end up being vertically adjacent to unrelated commits,
> falsely appearing to be related.
> 
> A fix for this issue was already attempted [1] a while ago.
> 
> This happens because the commits fill the space from left to right and
> when a visual root ends, its column becomes free for the following
> commit even if they are not related. Once this happens the unrelated
> commit is rendered below the visual root. Because there is no special
> character or way to identify when a visual root is rendered making the
> graph confusing.
> 
> By indenting the visual roots when there are still commits to show the
> vertical adjacency can be avoided.
> 
> Add is_visual_root flag to git_graph making it visible in all graph states,
> give graph_update() a new function, graph_is_visual_root() to know if the
> current commit is a visual root and set is_visual_root.
> The different handled cases are:
> 
> - If a visual root has children: similar to GRAPH_PRE_COMMIT state when
>   octopus merges need space, an edge row needs to be printed to connect
>   the child with the indented visual root. A new state GRAPH_PRE_ROOT is
>   needed to connect the child with the visual root:
> 
>     * child of the visual root
>      \ GRAPH_PRE_ROOT
>       * visual root indented
> 
> - If a visual root is child-less we can skip GRAPH_PRE_ROOT state and
>   render the indented commit directly.
> 
>       * visual root indented
>     * unrelated commit
> 
> - If two or more visual roots are adjacent: by having a lookahead to the
>   next commit that will be rendered, if the next commit is also a visual
>   root and we are on a visual root, meaning two visual root adjacent in
>   the history, the top one can omit the indent, making the one below to
>   indent only once, if there are more adjacent visual commits, the
>   indentation will increase for each adjacent one, cascading.
> 
>     * visual root
>       * visual root
>         * visual root
>     * last commit
> 
>   Even if the last commit is a root, because there is nothing that will be
>   rendered below we can omit the indentation on purpose.
> 
> [1]: https://lore.kernel.org/git/xmqqwnwajbuj.fsf@gitster.c.googlers.com/
> 
> Helped-by: Kristofer Karlsson <krka@spotify.com>
> Mentored-by: Karthik Nayak <karthik.188@gmail.com>
> Mentored-by: Chandra Pratap <chandrapratap3519@gmail.com>
> Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
> ---
>  graph.c                          | 235 +++++++++++++++++++
>  t/meson.build                    |   1 +
>  t/t4218-log-graph-indentation.sh | 473 +++++++++++++++++++++++++++++++++++++++
>  3 files changed, 709 insertions(+)
This doesn't seem to work for every visual root e.g.
    git log --graph --oneline --author="Mirko Faina"
The visual roots are not indented.
Show 26 quoted lines
> +/*
> + * A commit can be a visual root when:
> + *
> + * - It has no parents.
> + *
> + * - It has parents but they are all filtered out and
> + *   commit->parents arrives NULL.
> + *
> + * - It is not a boundary commit. Boundary commits also have no visible
> + *   parents, but they are not selected as visual roots because they cannot
> + *   cause the ambiguity of being vertically adjacent because:
> + *
> + *   1. A boundary only appears because an included commit is its child.
> + *      Children are always above, and the renderer draws an edge down to
> + *      the boundary from that child. Rather than starting a column like a
> + *      visual root would do, it inherits its child column.
> + *
> + *   2. Included commits cannot appear below a boundary. Boundaries are
> + *      ancestors of the exclusion point; if an included commit were an
> + *      ancestor of the boundary it would be excluded and not rendered.
> + *      Boundaries therefore always sink to the bottom.
> + */
> +static int graph_is_visual_root_candidate(struct commit *c)
> +{
> +	return c->parents == NULL && !(c->object.flags & BOUNDARY);
> +}
I suspect this behaviour is due to these assumptions being too strict.

When we use the --author option the parents are not filtered out, so it doesn't return NULL desipte being a visual root. We realize it is a visual root only on the next commit, but once we are on the next commit we can't indent as we have already printed this commit.

We realize only on the next commit after hitting simplify_commit(), it calls get_commit_action() and checks if should keep the commit based on the regex we provided. If the regex is not matched the commit is just ignored (we do not filter parents based on regex when we expand a topo walk).

At least that's what I gather, if anyone can confirm this...
Previous: Pablo SabaterNext: Pablo Sabater
Message 63 of 119 in “graph: add indentation for commits preceded by a root”
  1. 0/1 graph: add indentation for commits preceded by a rootPablo Sabater, Apr 2, 2026
  2. 1/1 graph: add indentation for commits preceded by a rootPablo Sabater, Apr 2, 2026
  3. Junio C HamanoApr 3, 2026
  4. PabloApr 3, 2026
  5. Junio C HamanoApr 3, 2026
  6. PabloApr 3, 2026
  7. 0/1 graph: add indentation for commits preceded by a parentless commitPablo Sabater, Apr 4, 2026
  8. 1/1 graph: add indentation for commits preceded by a parentless commitPablo Sabater, Apr 4, 2026
  9. PabloApr 10, 2026
  10. Junio C HamanoApr 10, 2026
  11. 0/1 graph: add indentation for commits preceded by a parentless commitPablo Sabater, Apr 27, 2026
  12. 1/1 graph: add indentation for commits preceded by a parentless commitPablo Sabater, Apr 27, 2026
  13. Jeff KingMay 13, 2026
  14. Pablo SabaterMay 14, 2026
  15. PabloApr 27, 2026
  16. 0/2 graph: indent visual roots in graphPablo Sabater, Jun 12, 2026
  17. 1/2 lib-log-graph: move check_graph functionPablo Sabater, Jun 12, 2026
  18. 2/2 graph: indent visual root in graphPablo Sabater, Jun 12, 2026
  19. Junio C HamanoJun 13, 2026
  20. 0/2 graph: indent visual roots in graphPablo Sabater, Jun 13, 2026
  21. 1/2 lib-log-graph: move check_graph functionPablo Sabater, Jun 13, 2026
  22. 2/2 graph: indent visual root in graphPablo Sabater, Jun 13, 2026
  23. Junio C HamanoJun 14, 2026
  24. Pablo SabaterJun 14, 2026
  25. Junio C HamanoJun 15, 2026
  26. Pablo SabaterJun 16, 2026
  27. Junio C HamanoJun 16, 2026
  28. Jeff KingJun 17, 2026
  29. Pablo SabaterJun 18, 2026
  30. Junio C HamanoJun 18, 2026
  31. Jeff KingJun 18, 2026
  32. Jeff KingJun 18, 2026
  33. Kristofer KarlssonJun 19, 2026
  34. Jeff KingJun 21, 2026
  35. Kristofer KarlssonJun 22, 2026
  36. Chandra PratapJun 17, 2026
  37. 0/3 graph: indent visual roots in graphPablo Sabater, Jun 20, 2026
  38. 1/3 lib-log-graph: move check_graph functionPablo Sabater, Jun 20, 2026
  39. 2/3 revision: add peek functions for lookaheadPablo Sabater, Jun 20, 2026
  40. Pablo SabaterJun 20, 2026
  41. Junio C HamanoJun 20, 2026
  42. Junio C HamanoJun 20, 2026
  43. Junio C HamanoJun 21, 2026
  44. Chandra PratapJun 21, 2026
  45. Kristofer KarlssonJun 22, 2026
  46. Junio C HamanoJun 29, 2026
  47. Pablo SabaterJun 29, 2026
  48. 3/3 graph: indent visual root in graphPablo Sabater, Jun 20, 2026
  49. 0/3 graph: indent visual roots in graphPablo Sabater, Jul 4, 2026
  50. 1/3 lib-log-graph: move check_graph functionPablo Sabater, Jul 4, 2026
  51. 2/3 graph: add a 2 commit buffer for lookaheadPablo Sabater, Jul 4, 2026
  52. Chandra PratapJul 6, 2026
  53. Kristofer KarlssonJul 6, 2026
  54. Chandra PratapJul 6, 2026
  55. Pablo SabaterJul 7, 2026
  56. Pablo SabaterJul 7, 2026
  57. 3/3 graph: indent visual root in graphPablo Sabater, Jul 4, 2026
  58. 0/4 graph: indent visual roots in graphPablo Sabater, Jul 10, 2026
  59. 1/4 lib-log-graph: move check_graph functionPablo Sabater, Jul 10, 2026
  60. 2/4 revision: add next_commit_to_show()Pablo Sabater, Jul 10, 2026
  61. 3/4 graph: add a 2 commit buffer for lookaheadPablo Sabater, Jul 10, 2026
  62. 4/4 graph: indent visual root in graphPablo Sabater, Jul 10, 2026
  63. Mirko FainaJul 10, 2026
  64. Pablo SabaterJul 10, 2026
  65. 0/4 graph: indent visual roots in graphPablo Sabater, Jul 11, 2026
  66. 1/4 lib-log-graph: move check_graph functionPablo Sabater, Jul 11, 2026
  67. 2/4 revision: add next_commit_to_show()Pablo Sabater, Jul 11, 2026
  68. 3/4 graph: add a 2 commit buffer for lookaheadPablo Sabater, Jul 11, 2026
  69. 4/4 graph: indent visual root in graphPablo Sabater, Jul 11, 2026
  70. Mirko FainaJul 11, 2026
  71. Pablo SabaterJul 11, 2026
  72. Mirko FainaJul 11, 2026
  73. Chandra PratapJul 12, 2026
  74. Mirko FainaJul 12, 2026
  75. Mirko FainaJul 12, 2026
  76. Pablo SabaterJul 12, 2026
  77. Mirko FainaJul 12, 2026
  78. Chandra PratapJul 13, 2026
  79. 0/7 graph: indent visual roots in graphPablo Sabater, Jul 13, 2026
  80. 1/7 lib-log-graph: move check_graph functionPablo Sabater, Jul 13, 2026
  81. 2/7 revision: add next_commit_to_show()Pablo Sabater, Jul 13, 2026
  82. 3/7 graph: add a 2 commit buffer for lookaheadPablo Sabater, Jul 13, 2026
  83. 4/7 graph: indent visual root in graphPablo Sabater, Jul 13, 2026
  84. 5/7 graph: wrap cascading commits after 4 columnsPablo Sabater, Jul 13, 2026
  85. 6/7 graph: move config reading into graph_read_config()Pablo Sabater, Jul 13, 2026
  86. 7/7 graph: add --[no-]graph-indent and log.graphIndentPablo Sabater, Jul 13, 2026
  87. Mirko FainaJul 13, 2026
  88. Pablo SabaterJul 13, 2026
  89. 0/7 graph: indent visual roots in graphPablo Sabater, Jul 13, 2026
  90. 1/7 lib-log-graph: move check_graph functionPablo Sabater, Jul 13, 2026
  91. 2/7 revision: add next_commit_to_show()Pablo Sabater, Jul 13, 2026
  92. 3/7 graph: add a 2 commit buffer for lookaheadPablo Sabater, Jul 13, 2026
  93. 4/7 graph: indent visual root in graphPablo Sabater, Jul 13, 2026
  94. 6/7 graph: move config reading into graph_read_config()Pablo Sabater, Jul 13, 2026
  95. 7/7 graph: add --[no-]graph-indent and log.graphIndentPablo Sabater, Jul 13, 2026
  96. Chandra PratapJul 14, 2026
  97. Pablo SabaterJul 14, 2026
  98. 5/7 graph: wrap cascading commits after 4 columnsPablo Sabater, Jul 13, 2026
  99. Junio C HamanoJul 13, 2026
  100. Pablo SabaterJul 13, 2026
  101. 0/7 graph: indent visual roots in graphPablo Sabater, Jul 14, 2026
  102. 1/7 lib-log-graph: move check_graph functionPablo Sabater, Jul 14, 2026
  103. 2/7 revision: add next_commit_to_show()Pablo Sabater, Jul 14, 2026
  104. 3/7 graph: add a 2 commit buffer for lookaheadPablo Sabater, Jul 14, 2026
  105. 4/7 graph: indent visual root in graphPablo Sabater, Jul 14, 2026
  106. 5/7 graph: wrap cascading commits after 4 columnsPablo Sabater, Jul 14, 2026
  107. 6/7 graph: move config reading into graph_read_config()Pablo Sabater, Jul 14, 2026
  108. 7/7 graph: add --[no-]graph-indent and log.graphIndentPablo Sabater, Jul 14, 2026
  109. Chandra PratapJul 15, 2026
  110. Phillip WoodMay 14, 2026
  111. Pablo SabaterMay 14, 2026
  112. Phillip WoodMay 15, 2026
  113. Chandra PratapMay 17, 2026
  114. Pablo SabaterMay 18, 2026
  115. Junio C HamanoMay 19, 2026
  116. Pablo SabaterMay 19, 2026
  117. Junio C HamanoJun 10, 2026
  118. Pablo SabaterJun 10, 2026
  119. Chandra PratapMay 19, 2026

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.