From: Pablo Sabater <pabloosabaterr@gmail.com>
To: git@vger.kernel.org
Cc: pabloosabaterr@gmail.com, ayu.chandekar@gmail.com,
chandrapratap3519@gmail.com, christian.couder@gmail.com,
gitster@pobox.com, jltobler@gmail.com, karthik.188@gmail.com,
krka@spotify.com, mroik@delayed.space, peff@peff.net,
phillip.wood@dunelm.org.uk, siddharthasthana31@gmail.com
Subject: [PATCH v9 0/4] graph: indent visual roots in graph
Date: Sat, 11 Jul 2026 15:37:49 +0200 [thread overview]
Message-ID: <20260711-ps-pre-commit-indent-v9-0-eab6676e82f7@gmail.com> (raw)
In-Reply-To: <20260710-ps-pre-commit-indent-v8-0-d3b636463bf4@gmail.com>
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 series adds indentation to the visual root commits, so they cannot be
vertically adjacent anymore making it easier to identify them.
Before indentation:
* A
* B1
* B2
* C1
* C2
After indentation:
* A
* B1
\
* B2
* C1
* C2
Indents the visual root commits that have still commits to show after
them, and if they have children it connects them with an edge at a new
row.
If there are multiple visual roots adjacent in history, the indentation
starts with the second one, avoiding redundant indentation of the first
one and cascades after the second.
* A
* B
* C
* D1
* D2
This series first commit is a cleanup that brings a common function
from t4215 and t6016 to a graph functions file which they both use, so
the new test file for indentation, t4218, can use it as well.
GitHub CI: https://github.com/pabloosabaterr/git/actions/runs/29154333559
[1]: https://lore.kernel.org/git/xmqqwnwajbuj.fsf@gitster.c.googlers.com/
V8 DIFF:
- Checking if the parents of a commit are NULL is not enough to know if
the commit is a visual root due to options that filter the commit
parents but they do not remove them (--author, --grep, etc).
At graph_is_visual_root_candidate(), iterate the parents and call
graph_is_interesting() for each of them to know whether they will be
shown or not.
- Add a --author and a --grep test.
Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
---
Pablo Sabater (4):
lib-log-graph: move check_graph function
revision: add next_commit_to_show()
graph: add a 2 commit buffer for lookahead
graph: indent visual root in graph
graph.c | 295 +++++++++++++++++
graph.h | 17 +
revision.c | 48 ++-
t/lib-log-graph.sh | 5 +
t/meson.build | 1 +
t/t4215-log-skewed-merges.sh | 33 +-
t/t4218-log-graph-indentation.sh | 514 +++++++++++++++++++++++++++++
t/t6016-rev-list-graph-simplify-history.sh | 25 +-
8 files changed, 893 insertions(+), 45 deletions(-)
Range-diff versus v8:
1: ce4f6419c2 = 1: 22ab444372 lib-log-graph: move check_graph function
2: 8c7326745e = 2: ebb88c8b29 revision: add next_commit_to_show()
3: f2e895c72b = 3: 0705ee321e graph: add a 2 commit buffer for lookahead
4: 90d5d22344 ! 4: fa2e60fb3f graph: indent visual root in graph
@@ graph.c: void graph_push_lookahead(struct git_graph *graph, struct commit *c)
+ * - It has parents but they are all filtered out and
+ * commit->parents arrives NULL.
+ *
++ * - Its parents are uninteresting.
++ *
+ * - 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:
@@ graph.c: void graph_push_lookahead(struct git_graph *graph, struct commit *c)
+ * 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)
++static int graph_is_visual_root_candidate(struct commit *c, struct git_graph *graph)
+{
-+ return c->parents == NULL && !(c->object.flags & BOUNDARY);
++ struct commit_list *p;
++
++ if (c->object.flags & BOUNDARY)
++ return 0;
++ for (p = c->parents; p; p = p->next)
++ if (graph_is_interesting(graph, p->item))
++ return 0;
++ return 1;
+}
+
+static int graph_is_visual_root(struct git_graph *graph,
@@ graph.c: void graph_push_lookahead(struct git_graph *graph, struct commit *c)
+ * current commit has to act as the last commit and omit
+ * indentation.
+ */
-+ return graph_is_visual_root_candidate(graph->commit) &&
++ return graph_is_visual_root_candidate(graph->commit, graph) &&
+ !(graph->commit_in_columns &&
+ graph->columns[graph->commit_index].is_merge_parent) &&
+ flags->is_next_visible &&
@@ graph.c: void graph_push_lookahead(struct git_graph *graph, struct commit *c)
+ flags->next_has_column =
+ graph_find_new_column_by_commit(graph, graph->lookahead[0]) >= 0;
+
-+ if (!graph_is_visual_root_candidate(graph->lookahead[0]))
++ if (!graph_is_visual_root_candidate(graph->lookahead[0], graph))
+ return;
+
+ if (graph->lookahead_nr >= 2)
@@ t/t4218-log-graph-indentation.sh (new)
+ EOF
+'
+
++# when the graph commits are filtered with regex options like --author, the
++# commit parents do not come NULL so it is needed to check if the parents are
++# interesting.
++test_expect_success '--author skipped parent makes a visual root' '
++ create_orphan _55 &&
++ test_tick &&
++ git commit --allow-empty -m 55_A &&
++ create_orphan _54 &&
++ test_tick &&
++ git commit --allow-empty --author="Other <other@example.com>" -m 54_A &&
++ test_tick &&
++ git commit --allow-empty -m 54_B &&
++ test_tick &&
++ git commit --allow-empty -m 54_C &&
++ lib_test_check_graph --author="A U Thor" _54 _55 <<-\EOF
++ * 54_C
++ \
++ * 54_B
++ * 55_A
++ EOF
++'
++
++test_expect_success '--grep skipped parent makes a visual root' '
++ create_orphan _57 &&
++ test_tick &&
++ git commit --allow-empty -m 57_keep_A &&
++ create_orphan _56 &&
++ test_tick &&
++ git commit --allow-empty -m 56_skip &&
++ test_tick &&
++ git commit --allow-empty -m 56_keep_A &&
++ test_tick &&
++ git commit --allow-empty -m 56_keep_B &&
++ lib_test_check_graph --grep=keep _56 _57 <<-\EOF
++ * 56_keep_B
++ \
++ * 56_keep_A
++ * 57_keep_A
++ EOF
++'
++
+test_done
---
base-commit: f85a7e662054a7b0d9070e432508831afa214b47
next prev parent reply other threads:[~2026-07-11 13:38 UTC|newest]
Thread overview: 118+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-02 21:17 [GSoC RFC PATCH 0/1] graph: add indentation for commits preceded by a root Pablo Sabater
2026-04-02 21:17 ` [GSoC RFC PATCH 1/1] " Pablo Sabater
2026-04-03 17:55 ` Junio C Hamano
2026-04-03 18:07 ` Pablo
2026-04-03 5:04 ` [GSoC RFC PATCH 0/1] " Junio C Hamano
2026-04-03 8:25 ` Pablo
2026-04-04 9:24 ` [GSoC RFC PATCH v2 0/1] graph: add indentation for commits preceded by a parentless commit Pablo Sabater
2026-04-04 9:24 ` [GSoC RFC PATCH v2 1/1] " Pablo Sabater
2026-04-10 16:25 ` [GSoC RFC PATCH v2 0/1] " Pablo
2026-04-10 16:54 ` Junio C Hamano
2026-04-27 10:28 ` [GSoC PATCH v3 " Pablo Sabater
2026-04-27 10:28 ` [GSoC PATCH v3 1/1] " Pablo Sabater
2026-05-13 23:02 ` Jeff King
2026-05-14 10:19 ` Pablo Sabater
2026-04-27 10:35 ` [GSoC PATCH v3 0/1] " Pablo
2026-06-12 13:48 ` [PATCH v4 0/2] graph: indent visual roots in graph Pablo Sabater
2026-06-12 13:48 ` [PATCH v4 1/2] lib-log-graph: move check_graph function Pablo Sabater
2026-06-12 13:48 ` [PATCH v4 2/2] graph: indent visual root in graph Pablo Sabater
2026-06-13 3:01 ` [PATCH v4 0/2] graph: indent visual roots " Junio C Hamano
2026-06-13 19:09 ` [PATCH v5 " Pablo Sabater
2026-06-13 19:09 ` [PATCH v5 1/2] lib-log-graph: move check_graph function Pablo Sabater
2026-06-13 19:09 ` [PATCH v5 2/2] graph: indent visual root in graph Pablo Sabater
2026-06-14 4:05 ` Junio C Hamano
2026-06-14 5:28 ` Pablo Sabater
2026-06-15 15:42 ` Junio C Hamano
2026-06-16 13:06 ` Pablo Sabater
2026-06-16 16:36 ` Junio C Hamano
2026-06-17 20:27 ` Jeff King
2026-06-18 12:42 ` Pablo Sabater
2026-06-18 13:31 ` Junio C Hamano
2026-06-18 16:05 ` Jeff King
2026-06-18 16:07 ` Jeff King
2026-06-19 7:34 ` Kristofer Karlsson
2026-06-21 18:05 ` Jeff King
2026-06-22 8:29 ` Kristofer Karlsson
2026-06-17 10:33 ` [PATCH v5 0/2] graph: indent visual roots " Chandra Pratap
2026-06-20 10:11 ` [PATCH v6 0/3] " Pablo Sabater
2026-06-20 10:11 ` [PATCH v6 1/3] lib-log-graph: move check_graph function Pablo Sabater
2026-06-20 10:11 ` [PATCH v6 2/3] revision: add peek functions for lookahead Pablo Sabater
2026-06-20 10:18 ` Pablo Sabater
2026-06-20 14:56 ` Junio C Hamano
2026-06-20 15:15 ` Junio C Hamano
2026-06-21 1:48 ` Junio C Hamano
2026-06-21 6:42 ` Chandra Pratap
2026-06-22 8:28 ` Kristofer Karlsson
2026-06-29 21:56 ` Junio C Hamano
2026-06-29 23:29 ` Pablo Sabater
2026-06-20 10:11 ` [PATCH v6 3/3] graph: indent visual root in graph Pablo Sabater
2026-07-04 8:52 ` [PATCH v7 0/3] graph: indent visual roots " Pablo Sabater
2026-07-04 8:52 ` [PATCH v7 1/3] lib-log-graph: move check_graph function Pablo Sabater
2026-07-04 8:52 ` [PATCH v7 2/3] graph: add a 2 commit buffer for lookahead Pablo Sabater
2026-07-06 9:49 ` Chandra Pratap
2026-07-06 13:44 ` Kristofer Karlsson
2026-07-06 15:33 ` Chandra Pratap
2026-07-07 6:31 ` Pablo Sabater
2026-07-07 18:12 ` Pablo Sabater
2026-07-04 8:52 ` [PATCH v7 3/3] graph: indent visual root in graph Pablo Sabater
2026-07-10 10:37 ` [PATCH v8 0/4] graph: indent visual roots " Pablo Sabater
2026-07-10 10:37 ` [PATCH v8 1/4] lib-log-graph: move check_graph function Pablo Sabater
2026-07-10 10:37 ` [PATCH v8 2/4] revision: add next_commit_to_show() Pablo Sabater
2026-07-10 10:37 ` [PATCH v8 3/4] graph: add a 2 commit buffer for lookahead Pablo Sabater
2026-07-10 10:37 ` [PATCH v8 4/4] graph: indent visual root in graph Pablo Sabater
2026-07-10 18:07 ` Mirko Faina
2026-07-10 20:29 ` Pablo Sabater
2026-07-11 13:37 ` Pablo Sabater [this message]
2026-07-11 13:37 ` [PATCH v9 1/4] lib-log-graph: move check_graph function Pablo Sabater
2026-07-11 13:37 ` [PATCH v9 2/4] revision: add next_commit_to_show() Pablo Sabater
2026-07-11 13:37 ` [PATCH v9 3/4] graph: add a 2 commit buffer for lookahead Pablo Sabater
2026-07-11 13:37 ` [PATCH v9 4/4] graph: indent visual root in graph Pablo Sabater
2026-07-11 14:15 ` [PATCH v9 0/4] graph: indent visual roots " Mirko Faina
2026-07-11 15:41 ` Pablo Sabater
2026-07-11 16:25 ` Mirko Faina
2026-07-12 5:56 ` Chandra Pratap
2026-07-12 13:10 ` Mirko Faina
2026-07-12 13:12 ` Mirko Faina
2026-07-12 16:59 ` Pablo Sabater
2026-07-12 19:33 ` Mirko Faina
2026-07-13 7:41 ` Chandra Pratap
2026-07-13 10:44 ` [PATCH v10 0/7] " Pablo Sabater
2026-07-13 10:44 ` [PATCH v10 1/7] lib-log-graph: move check_graph function Pablo Sabater
2026-07-13 10:44 ` [PATCH v10 2/7] revision: add next_commit_to_show() Pablo Sabater
2026-07-13 10:44 ` [PATCH v10 3/7] graph: add a 2 commit buffer for lookahead Pablo Sabater
2026-07-13 10:44 ` [PATCH v10 4/7] graph: indent visual root in graph Pablo Sabater
2026-07-13 10:44 ` [PATCH v10 5/7] graph: wrap cascading commits after 4 columns Pablo Sabater
2026-07-13 10:44 ` [PATCH v10 6/7] graph: move config reading into graph_read_config() Pablo Sabater
2026-07-13 10:44 ` [PATCH v10 7/7] graph: add --[no-]graph-indent and log.graphIndent Pablo Sabater
2026-07-13 14:06 ` Mirko Faina
2026-07-13 16:16 ` Pablo Sabater
2026-07-13 16:43 ` [PATCH v11 0/7] graph: indent visual roots in graph Pablo Sabater
2026-07-13 16:43 ` [PATCH v11 1/7] lib-log-graph: move check_graph function Pablo Sabater
2026-07-13 16:43 ` [PATCH v11 2/7] revision: add next_commit_to_show() Pablo Sabater
2026-07-13 16:44 ` [PATCH v11 3/7] graph: add a 2 commit buffer for lookahead Pablo Sabater
2026-07-13 16:44 ` [PATCH v11 4/7] graph: indent visual root in graph Pablo Sabater
2026-07-13 16:44 ` [PATCH v11 5/7] graph: wrap cascading commits after 4 columns Pablo Sabater
2026-07-13 16:44 ` [PATCH v11 6/7] graph: move config reading into graph_read_config() Pablo Sabater
2026-07-13 16:44 ` [PATCH v11 7/7] graph: add --[no-]graph-indent and log.graphIndent Pablo Sabater
2026-07-14 10:19 ` Chandra Pratap
2026-07-14 11:47 ` Pablo Sabater
2026-07-13 20:28 ` [PATCH v11 0/7] graph: indent visual roots in graph Junio C Hamano
2026-07-13 20:51 ` Pablo Sabater
2026-07-14 12:09 ` [PATCH v12 " Pablo Sabater
2026-07-14 12:09 ` [PATCH v12 1/7] lib-log-graph: move check_graph function Pablo Sabater
2026-07-14 12:09 ` [PATCH v12 2/7] revision: add next_commit_to_show() Pablo Sabater
2026-07-14 12:09 ` [PATCH v12 3/7] graph: add a 2 commit buffer for lookahead Pablo Sabater
2026-07-14 12:09 ` [PATCH v12 4/7] graph: indent visual root in graph Pablo Sabater
2026-07-14 12:09 ` [PATCH v12 5/7] graph: wrap cascading commits after 4 columns Pablo Sabater
2026-07-14 12:09 ` [PATCH v12 6/7] graph: move config reading into graph_read_config() Pablo Sabater
2026-07-14 12:09 ` [PATCH v12 7/7] graph: add --[no-]graph-indent and log.graphIndent Pablo Sabater
2026-05-14 15:15 ` [GSoC RFC PATCH 0/1] graph: add indentation for commits preceded by a root Phillip Wood
2026-05-14 17:45 ` Pablo Sabater
2026-05-15 9:33 ` Phillip Wood
2026-05-17 6:31 ` Chandra Pratap
2026-05-18 13:26 ` Pablo Sabater
2026-05-19 0:03 ` Junio C Hamano
2026-05-19 5:59 ` Pablo Sabater
2026-06-10 15:21 ` Junio C Hamano
2026-06-10 15:28 ` Pablo Sabater
2026-05-19 10:39 ` Chandra Pratap
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260711-ps-pre-commit-indent-v9-0-eab6676e82f7@gmail.com \
--to=pabloosabaterr@gmail.com \
--cc=ayu.chandekar@gmail.com \
--cc=chandrapratap3519@gmail.com \
--cc=christian.couder@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=jltobler@gmail.com \
--cc=karthik.188@gmail.com \
--cc=krka@spotify.com \
--cc=mroik@delayed.space \
--cc=peff@peff.net \
--cc=phillip.wood@dunelm.org.uk \
--cc=siddharthasthana31@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox