graph: add truncation mark to capped lanes
When lanes are hidden by --graph-lane-limit, show a "~" truncation mark, so users know that there are lanes being truncated. The "~" is chosen because it is not used elsewhere in the graph and it is discrete. Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Pablo Sabater committed
Mar 28, 2026 at 01:11 UTC
9bab3ce5553b2333b8f8ee1aff27a9fe6a938f65
3 files changed
+52
-39
Documentation/rev-list-options.adoc
+3
-2
@@ -1261,8 +1261,9 @@ This implies the `--topo-order` option by default, but the
1261
1262
`--graph-lane-limit=<n>`::
1263
When `--graph` is used, limit the number of graph lanes to be shown.
1264
- Lanes over the limit are not shown. By default it is set to 0
1265
- (no limit), zero and negative values are ignored and treated as no limit.
1264
+ Lanes over the limit are replaced with a truncation mark '~'.
1265
+ By default it is set to 0 (no limit), zero and negative values
1266
+ are ignored and treated as no limit.
1267
1268
ifdef::git-rev-list[]
1269
`--count`::
graph.c
+17
-5
@@ -706,11 +706,11 @@ static void graph_update_columns(struct git_graph *graph)
706
}
707
708
/*
709
- * If graph_max_lanes is set, cap the width
709
+ * If graph_max_lanes is set, cap the width
710
*/
711
if (graph->revs->graph_max_lanes > 0) {
712
/*
713
- * Width is column index while a lane is half that.
713
+ * width of "| " per lanes plus truncation mark "~ ".
714
* Allow commits from merges to align to the merged lane.
715
*/
716
int max_width = graph->revs->graph_max_lanes * 2 + 2;
@@ -868,8 +868,10 @@ static void graph_output_padding_line(struct git_graph *graph,
868
* Output a padding row, that leaves all branch lines unchanged
869
*/
870
for (i = 0; i < graph->num_new_columns; i++) {
871
- if (graph_needs_truncation(graph, i))
871
+ if (graph_needs_truncation(graph, i)) {
872
+ graph_line_addstr(line, "~ ");
873
break;
874
+ }
875
graph_line_write_column(line, &graph->new_columns[i], '|');
876
graph_line_addch(line, ' ');
877
}
@@ -928,6 +930,7 @@ static void graph_output_pre_commit_line(struct git_graph *graph,
930
graph_line_write_column(line, col, '|');
931
graph_line_addchars(line, ' ', graph->expansion_row);
932
} else if (seen_this && graph_needs_truncation(graph, i)) {
933
+ graph_line_addstr(line, "~ ");
934
break;
935
} else if (seen_this && (graph->expansion_row == 0)) {
936
/*
@@ -1025,8 +1028,10 @@ static void graph_draw_octopus_merge(struct git_graph *graph, struct graph_line
1028
* Commit is at commit_index, each iteration move one lane to
1029
* the right from the commit.
1030
*/
1028
- if (graph_needs_truncation(graph, graph->commit_index + 1 + i))
1031
+ if (graph_needs_truncation(graph, graph->commit_index + 1 + i)) {
1032
+ graph_line_addstr(line, "~ ");
1033
break;
1034
+ }
1035
1036
graph_line_write_column(line, col, (i == dashed_parents - 1) ? '.' : '-');
1037
}
@@ -1070,6 +1075,7 @@ static void graph_output_commit_line(struct git_graph *graph, struct graph_line
1075
if (graph->num_parents > 2)
1076
graph_draw_octopus_merge(graph, line);
1077
} else if (graph_needs_truncation(graph, i)) {
1078
+ graph_line_addstr(line, "~ ");
1079
seen_this = 1;
1080
break;
1081
} else if (seen_this && (graph->edges_added > 1)) {
@@ -1203,6 +1209,7 @@ static void graph_output_post_merge_line(struct git_graph *graph, struct graph_l
1209
j / 2 + i <= graph->num_columns) {
1210
if ((j + i * 2) % 2 != 0)
1211
graph_line_addch(line, ' ');
1212
+ graph_line_addstr(line, "~ ");
1213
truncated = 1;
1214
break;
1215
}
@@ -1214,6 +1221,7 @@ static void graph_output_post_merge_line(struct git_graph *graph, struct graph_l
1221
*/
1222
if (graph_needs_truncation(graph, (j + 1) / 2 + i) &&
1223
j < graph->num_parents - 1) {
1224
+ graph_line_addstr(line, "~ ");
1225
truncated = 1;
1226
break;
1227
} else if (graph->edges_added > 0 || j < graph->num_parents - 1)
@@ -1228,6 +1236,7 @@ static void graph_output_post_merge_line(struct git_graph *graph, struct graph_l
1236
if (graph->edges_added == 0)
1237
graph_line_addch(line, ' ');
1238
} else if (graph_needs_truncation(graph, i)) {
1239
+ graph_line_addstr(line, "~ ");
1240
break;
1241
} else if (seen_this) {
1242
if (graph->edges_added > 0)
@@ -1388,6 +1397,7 @@ static void graph_output_collapsing_line(struct git_graph *graph, struct graph_l
1397
int target = graph->mapping[i];
1398
1399
if (!truncated && graph_needs_truncation(graph, i / 2)) {
1400
+ graph_line_addstr(line, "~ ");
1401
truncated = 1;
1402
}
1403
@@ -1487,8 +1497,10 @@ static void graph_padding_line(struct git_graph *graph, struct strbuf *sb)
1497
for (i = 0; i < graph->num_columns; i++) {
1498
struct column *col = &graph->columns[i];
1499
1490
- if (graph_needs_truncation(graph, i))
1500
+ if (graph_needs_truncation(graph, i)) {
1501
+ graph_line_addstr(&line, "~ ");
1502
break;
1503
+ }
1504
1505
graph_line_write_column(&line, col, '|');
1506
t/t4215-log-skewed-merges.sh
+32
-32
@@ -376,9 +376,9 @@ test_expect_success 'log --graph --graph-lane-limit=2 limited to two lanes' '
376
|\ \
377
| | * 7_G
378
| | * 7_F
379
- | * 7_E
380
- | * 7_D
381
- * | 7_C
379
+ | * ~ 7_E
380
+ | * ~ 7_D
381
+ * | ~ 7_C
382
| |/
383
|/|
384
* | 7_B
@@ -389,16 +389,16 @@ test_expect_success 'log --graph --graph-lane-limit=2 limited to two lanes' '
389
390
test_expect_success 'log --graph --graph-lane-limit=1 truncate mid octopus merge' '
391
check_graph --graph-lane-limit=1 M_7 <<-\EOF
392
- *- 7_M4
393
- |\
394
- | 7_G
395
- | 7_F
392
+ *-~ 7_M4
393
+ |\~
394
+ | ~ 7_G
395
+ | ~ 7_F
396
| * 7_E
397
| * 7_D
398
- * 7_C
399
- |
400
- |/
401
- * 7_B
398
+ * ~ 7_C
399
+ | ~
400
+ |/~
401
+ * ~ 7_B
402
|/
403
* 7_A
404
EOF
@@ -411,24 +411,24 @@ test_expect_success 'log --graph --graph-lane-limit=3 limited to three lanes' '
411
| | * 7_M2
412
| | |\
413
| | | * 7_H
414
- | | | 7_M3
415
- | | | 7_J
416
- | | | 7_I
417
- | | | 7_M4
418
- | |_|_
419
- |/| |
420
- | | |_
421
- | |/|
422
- | | |
423
- | | |/
424
- | | * 7_G
425
- | | |
426
- | | |/
427
- | | * 7_F
428
- | * | 7_E
429
- | | |/
430
- | |/|
431
- | * | 7_D
414
+ | | | ~ 7_M3
415
+ | | | ~ 7_J
416
+ | | | ~ 7_I
417
+ | | | ~ 7_M4
418
+ | |_|_~
419
+ |/| | ~
420
+ | | |_~
421
+ | |/| ~
422
+ | | | ~
423
+ | | |/~
424
+ | | * ~ 7_G
425
+ | | | ~
426
+ | | |/~
427
+ | | * ~ 7_F
428
+ | * | ~ 7_E
429
+ | | |/~
430
+ | |/| ~
431
+ | * | ~ 7_D
432
| | |/
433
| |/|
434
* | | 7_C
@@ -452,9 +452,9 @@ test_expect_success 'log --graph --graph-lane-limit=6 check if it only shows fir
452
| | | | | * 7_J
453
| | | | * | 7_I
454
| | | | | | * 7_M4
455
- | |_|_|_|_|/
456
- |/| | | | |/
457
- | | |_|_|/|
455
+ | |_|_|_|_|/~
456
+ |/| | | | |/~
457
+ | | |_|_|/| ~
458
| |/| | | |/
459
| | | |_|/|
460
| | |/| | |