graph: add --[no-]graph-indent and log.graphIndent

Some users may prefer to not have graph indentation. Add "log.graphIndent" config variable to graph_read_config() to read the default preference. By default is graph indentation is true. Add --graph-indent and --no-graph-indent options to overwrite the default preference. Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Pablo Sabater committed Jul 14, 2026 at 14:09 UTC e9b5720bef6c7e2821d086a8c67a6404debef905
6 files changed +84 -2
Documentation/config/log.adoc
+4
@@ -59,6 +59,10 @@ This is the same as the `--decorate` option of the `git log`.
59 A list of colors, separated by commas, that can be used to draw
60 history lines in `git log --graph`.
61
62 +`log.graphIndent`::
63 + If `true`, indent visual roots when rendering the graphs with `--graph`.
64 + Set true by default. It can be overriden with `--[no-]graph-indent`.
65 +
66 `log.showRoot`::
67 If true, the initial commit will be shown as a big creation event.
68 This is equivalent to a diff against an empty tree.
Documentation/rev-list-options.adoc
+8
@@ -1269,6 +1269,14 @@ This implies the `--topo-order` option by default, but the
1269 By default it is set to 0 (no limit), zero and negative values
1270 are ignored and treated as no limit.
1271
1272 +`--no-graph-indent`::
1273 +`--graph-indent`::
1274 + When used with `--graph`, indent visual roots (commits with no parents
1275 + or whose parents are not shown) to differentiate them from commits that
1276 + are vertically adjacent but unrelated. Enabled by default. Use
1277 + `--no-graph-indent` to disable or set `log.graphIndent` to set a
1278 + default preference.
1279 +
1280 ifdef::git-rev-list[]
1281 `--count`::
1282 Print a number stating how many commits would have been
graph.c
+8 -2
@@ -419,6 +419,8 @@ void graph_setup_line_prefix(struct diff_options *diffopt)
419
420 static void graph_read_config(struct rev_info *revs)
421 {
422 + int val;
423 +
424 if (!column_colors) {
425 char *string;
426 if (repo_config_get_string(revs->repo, "log.graphcolors", &string)) {
@@ -435,6 +437,9 @@ static void graph_read_config(struct rev_info *revs)
437 custom_colors.nr - 1);
438 }
439 }
440 +
441 + if (!repo_config_get_bool(revs->repo, "log.graphIndent", &val))
442 + revs->no_graph_indent = !val;
443 }
444
445 struct git_graph *graph_init(struct rev_info *opt)
@@ -999,7 +1004,8 @@ static void graph_peek_next_visible(struct git_graph *graph,
1004 static int graph_needs_pre_root_line(struct git_graph *graph)
1005 {
1006 return graph->commit_in_columns && graph->is_visual_root &&
1002 - graph->num_columns > 0 && !graph->visual_root_cascade;
1007 + graph->num_columns > 0 && !graph->visual_root_cascade &&
1008 + !graph->revs->no_graph_indent;
1009 }
1010
1011 void graph_update(struct git_graph *graph, struct commit *commit)
@@ -1344,7 +1350,7 @@ static void graph_output_commit_line(struct git_graph *graph, struct graph_line
1350
1351 if (col_commit == graph->commit) {
1352 seen_this = 1;
1347 - if (graph->is_visual_root) {
1353 + if (graph->is_visual_root && !graph->revs->no_graph_indent) {
1354 int depth = graph->visual_root_depth;
1355 /*
1356 * Each visual column is 2 characters wide.
revision.c
+9
@@ -2627,6 +2627,12 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
2627 revs->graph = NULL;
2628 } else if (skip_prefix(arg, "--graph-lane-limit=", &optarg)) {
2629 revs->graph_max_lanes = parse_count(optarg);
2630 + } else if (!strcmp(arg, "--graph-indent")) {
2631 + revs->no_graph_indent = 0;
2632 + revs->graph_indent_set = 1;
2633 + } else if (!strcmp(arg, "--no-graph-indent")) {
2634 + revs->no_graph_indent = 1;
2635 + revs->graph_indent_set = 1;
2636 } else if (!strcmp(arg, "--encode-email-headers")) {
2637 revs->encode_email_headers = 1;
2638 } else if (!strcmp(arg, "--no-encode-email-headers")) {
@@ -3201,6 +3207,9 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
3207 if (revs->graph_max_lanes > 0 && !revs->graph)
3208 die(_("the option '%s' requires '%s'"), "--graph-lane-limit", "--graph");
3209
3210 + if (revs->graph_indent_set && !revs->graph)
3211 + die(_("the option '%s' requires '%s'"), "--[no-]graph-indent", "--graph");
3212 +
3213 if (!revs->reflog_info && revs->grep_filter.use_reflog_filter)
3214 die(_("the option '%s' requires '%s'"), "--grep-reflog", "--walk-reflogs");
3215
revision.h
+2
@@ -314,6 +314,8 @@ struct rev_info {
314 /* Display history graph */
315 struct git_graph *graph;
316 int graph_max_lanes;
317 + unsigned int no_graph_indent:1;
318 + unsigned int graph_indent_set:1;
319
320 /* special limits */
321 int skip_count;
t/t4218-log-graph-indentation.sh
+53
@@ -540,4 +540,57 @@ test_expect_success 'visual root cascading gets wrapped after 4 columns' '
540 EOF
541 '
542
543 +test_expect_success '--no-graph-indent disables indentation' '
544 + lib_test_check_graph --no-graph-indent _58 _59 _60 _61 _62 _63 _64 _65 _66 _67 <<-\EOF
545 + * 67_A
546 + * 66_A
547 + * 65_A
548 + * 64_A
549 + * 63_A
550 + * 62_A
551 + * 61_A
552 + * 60_A
553 + * 59_A
554 + * 58_B
555 + * 58_A
556 + EOF
557 +'
558 +
559 +test_expect_success 'log.graphIndent config disables indentation' '
560 + test_config log.graphIndent false &&
561 + lib_test_check_graph _58 _59 _60 _61 _62 _63 _64 _65 _66 _67 <<-\EOF
562 + * 67_A
563 + * 66_A
564 + * 65_A
565 + * 64_A
566 + * 63_A
567 + * 62_A
568 + * 61_A
569 + * 60_A
570 + * 59_A
571 + * 58_B
572 + * 58_A
573 + EOF
574 +'
575 +
576 +test_expect_success '--graph-indent forces indentation when graph.indent is unset' '
577 + test_config log.graphIndent false &&
578 + lib_test_check_graph --graph-indent _58 _59 _60 _61 _62 _63 _64 _65 _66 _67 <<-\EOF
579 + * 67_A
580 + * 66_A
581 + * 65_A
582 + * 64_A
583 + * 63_A
584 + * 62_A
585 + * 61_A
586 + * 60_A
587 + * 59_A
588 + * 58_B
589 + * 58_A
590 + EOF
591 +'
592 +
593 +# log.graphIndent unset and no --option (which activates graph indentation) is
594 +# the default state.
595 +
596 test_done