@@ -317,6 +317,15 @@ struct git_graph {
317317 struct strbuf prefix_buf ;
318318};
319319
320+ static int graph_needs_truncation (struct git_graph * graph , int lane )
321+ {
322+ int max = graph -> revs -> graph_max_lanes ;
323+ /*
324+ * Ignore values <= 0, meaning no limit.
325+ */
326+ return max > 0 && lane >= max ;
327+ }
328+
320329static const char * diff_output_prefix_callback (struct diff_options * opt , void * data )
321330{
322331 struct git_graph * graph = data ;
@@ -696,6 +705,20 @@ static void graph_update_columns(struct git_graph *graph)
696705 }
697706 }
698707
708+ /*
709+ * If graph_max_lanes is set, cap the padding from the branches
710+ */
711+ if (graph -> revs -> graph_max_lanes > 0 ) {
712+ /*
713+ * Get the maximum width by multiplying the maximum number of
714+ * lanes by the size of the lane "| " and adds the truncation
715+ * mark ". "
716+ */
717+ int max_columns_width = graph -> revs -> graph_max_lanes * 2 + 2 ;
718+ if (graph -> width > max_columns_width )
719+ graph -> width = max_columns_width ;
720+ }
721+
699722 /*
700723 * Shrink mapping_size to be the minimum necessary
701724 */
@@ -846,6 +869,10 @@ static void graph_output_padding_line(struct git_graph *graph,
846869 * Output a padding row, that leaves all branch lines unchanged
847870 */
848871 for (i = 0 ; i < graph -> num_new_columns ; i ++ ) {
872+ if (graph_needs_truncation (graph , i )) {
873+ graph_line_addstr (line , ". " );
874+ break ;
875+ }
849876 graph_line_write_column (line , & graph -> new_columns [i ], '|' );
850877 graph_line_addch (line , ' ' );
851878 }
@@ -903,6 +930,9 @@ static void graph_output_pre_commit_line(struct git_graph *graph,
903930 seen_this = 1 ;
904931 graph_line_write_column (line , col , '|' );
905932 graph_line_addchars (line , ' ' , graph -> expansion_row );
933+ } else if (seen_this && graph_needs_truncation (graph , i )) {
934+ graph_line_addstr (line , ". " );
935+ break ;
906936 } else if (seen_this && (graph -> expansion_row == 0 )) {
907937 /*
908938 * This is the first line of the pre-commit output.
@@ -1013,6 +1043,7 @@ static void graph_output_commit_line(struct git_graph *graph, struct graph_line
10131043 * children that we have already processed.)
10141044 */
10151045 seen_this = 0 ;
1046+
10161047 for (i = 0 ; i <= graph -> num_columns ; i ++ ) {
10171048 struct column * col = & graph -> columns [i ];
10181049 struct commit * col_commit ;
@@ -1028,8 +1059,17 @@ static void graph_output_commit_line(struct git_graph *graph, struct graph_line
10281059 seen_this = 1 ;
10291060 graph_output_commit_char (graph , line );
10301061
1062+ if (graph_needs_truncation (graph , i )) {
1063+ graph_line_addch (line , ' ' );
1064+ break ;
1065+ }
1066+
10311067 if (graph -> num_parents > 2 )
10321068 graph_draw_octopus_merge (graph , line );
1069+ } else if (graph_needs_truncation (graph , i )) {
1070+ graph_line_addstr (line , ". " );
1071+ seen_this = 1 ;
1072+ break ;
10331073 } else if (seen_this && (graph -> edges_added > 1 )) {
10341074 graph_line_write_column (line , col , '\\' );
10351075 } else if (seen_this && (graph -> edges_added == 1 )) {
@@ -1065,10 +1105,32 @@ static void graph_output_commit_line(struct git_graph *graph, struct graph_line
10651105
10661106 /*
10671107 * Update graph->state
1108+ *
1109+ * If the commit is a merge and the first parent is in a visible lane,
1110+ * then the GRAPH_POST_MERGE is needed to draw the merge lane.
1111+ *
1112+ * If the commit is over the truncation limit, but the first parent is on
1113+ * a visible lane, then we still need the merge lane but truncated.
1114+ *
1115+ * If both commit and first parent are over the truncation limit, then
1116+ * there's no need to draw the merge lane because it would work as a
1117+ * padding lane.
10681118 */
1069- if (graph -> num_parents > 1 )
1070- graph_update_state (graph , GRAPH_POST_MERGE );
1071- else if (graph_is_mapping_correct (graph ))
1119+ if (graph -> num_parents > 1 ) {
1120+ if (!graph_needs_truncation (graph , graph -> commit_index )) {
1121+ graph_update_state (graph , GRAPH_POST_MERGE );
1122+ } else {
1123+ struct commit_list * first_parent = first_interesting_parent (graph );
1124+ int first_parent_col = graph_find_new_column_by_commit (graph , first_parent -> item );
1125+
1126+ if (!graph_needs_truncation (graph , first_parent_col ))
1127+ graph_update_state (graph , GRAPH_POST_MERGE );
1128+ else if (graph_is_mapping_correct (graph ))
1129+ graph_update_state (graph , GRAPH_PADDING );
1130+ else
1131+ graph_update_state (graph , GRAPH_COLLAPSING );
1132+ }
1133+ } else if (graph_is_mapping_correct (graph ))
10721134 graph_update_state (graph , GRAPH_PADDING );
10731135 else
10741136 graph_update_state (graph , GRAPH_COLLAPSING );
@@ -1109,14 +1171,28 @@ static void graph_output_post_merge_line(struct git_graph *graph, struct graph_l
11091171 int par_column ;
11101172 int idx = graph -> merge_layout ;
11111173 char c ;
1174+ int truncated = 0 ;
11121175 seen_this = 1 ;
11131176
11141177 for (j = 0 ; j < graph -> num_parents ; j ++ ) {
1178+ unsigned int truncation_max = i + (j > 1 ? j - 1 : 0 );
11151179 par_column = graph_find_new_column_by_commit (graph , parents -> item );
11161180 assert (par_column >= 0 );
11171181
11181182 c = merge_chars [idx ];
11191183 graph_line_write_column (line , & graph -> new_columns [par_column ], c );
1184+
1185+ if (j >= 2 )
1186+ truncation_max -= 1 ;
1187+
1188+ if (graph_needs_truncation (graph , truncation_max )) {
1189+ if (j > 0 && !(graph -> edges_added > 0 ))
1190+ graph_line_addch (line , ' ' );
1191+ graph_line_addstr (line , ". " );
1192+ truncated = 1 ;
1193+ break ;
1194+ }
1195+
11201196 if (idx == 2 ) {
11211197 if (graph -> edges_added > 0 || j < graph -> num_parents - 1 )
11221198 graph_line_addch (line , ' ' );
@@ -1125,15 +1201,24 @@ static void graph_output_post_merge_line(struct git_graph *graph, struct graph_l
11251201 }
11261202 parents = next_interesting_parent (graph , parents );
11271203 }
1204+ if (truncated )
1205+ break ;
11281206 if (graph -> edges_added == 0 )
11291207 graph_line_addch (line , ' ' );
1130-
1208+ } else if (graph_needs_truncation (graph , i )) {
1209+ graph_line_addstr (line , ". " );
1210+ break ;
11311211 } else if (seen_this ) {
11321212 if (graph -> edges_added > 0 )
11331213 graph_line_write_column (line , col , '\\' );
11341214 else
11351215 graph_line_write_column (line , col , '|' );
1136- graph_line_addch (line , ' ' );
1216+ /*
1217+ * If it's between two lanes and next would be truncated,
1218+ * don't add space padding.
1219+ */
1220+ if (!graph_needs_truncation (graph , i + 1 ))
1221+ graph_line_addch (line , ' ' );
11371222 } else {
11381223 graph_line_write_column (line , col , '|' );
11391224 if (graph -> merge_layout != 0 || i != graph -> commit_index - 1 ) {
@@ -1164,6 +1249,7 @@ static void graph_output_collapsing_line(struct git_graph *graph, struct graph_l
11641249 short used_horizontal = 0 ;
11651250 int horizontal_edge = -1 ;
11661251 int horizontal_edge_target = -1 ;
1252+ int truncated = 0 ;
11671253
11681254 /*
11691255 * Swap the mapping and old_mapping arrays
@@ -1279,26 +1365,35 @@ static void graph_output_collapsing_line(struct git_graph *graph, struct graph_l
12791365 */
12801366 for (i = 0 ; i < graph -> mapping_size ; i ++ ) {
12811367 int target = graph -> mapping [i ];
1282- if (target < 0 )
1283- graph_line_addch (line , ' ' );
1284- else if (target * 2 == i )
1285- graph_line_write_column (line , & graph -> new_columns [target ], '|' );
1286- else if (target == horizontal_edge_target &&
1287- i != horizontal_edge - 1 ) {
1368+
1369+ if (!truncated && graph_needs_truncation (graph , i / 2 )) {
1370+ graph_line_addstr (line , ". " );
1371+ truncated = 1 ;
1372+ }
1373+
1374+ if (target < 0 ) {
1375+ if (!truncated )
1376+ graph_line_addch (line , ' ' );
1377+ } else if (target * 2 == i ) {
1378+ if (!truncated )
1379+ graph_line_write_column (line , & graph -> new_columns [target ], '|' );
1380+ } else if (target == horizontal_edge_target &&
1381+ i != horizontal_edge - 1 ) {
12881382 /*
12891383 * Set the mappings for all but the
12901384 * first segment to -1 so that they
12911385 * won't continue into the next line.
12921386 */
12931387 if (i != (target * 2 )+ 3 )
12941388 graph -> mapping [i ] = -1 ;
1295- used_horizontal = 1 ;
1296- graph_line_write_column (line , & graph -> new_columns [target ], '_' );
1389+ used_horizontal = 1 ;
1390+ if (!truncated )
1391+ graph_line_write_column (line , & graph -> new_columns [target ], '_' );
12971392 } else {
12981393 if (used_horizontal && i < horizontal_edge )
12991394 graph -> mapping [i ] = -1 ;
1300- graph_line_write_column ( line , & graph -> new_columns [ target ], '/' );
1301-
1395+ if (! truncated )
1396+ graph_line_write_column ( line , & graph -> new_columns [ target ], '/' );
13021397 }
13031398 }
13041399
@@ -1347,7 +1442,6 @@ int graph_next_line(struct git_graph *graph, struct strbuf *sb)
13471442 graph_output_collapsing_line (graph , & line );
13481443 break ;
13491444 }
1350-
13511445 graph_pad_horizontally (graph , & line );
13521446 return shown_commit_line ;
13531447}
@@ -1372,6 +1466,11 @@ static void graph_padding_line(struct git_graph *graph, struct strbuf *sb)
13721466 for (i = 0 ; i < graph -> num_columns ; i ++ ) {
13731467 struct column * col = & graph -> columns [i ];
13741468
1469+ if (graph_needs_truncation (graph , i )) {
1470+ graph_line_addch (& line , '.' );
1471+ break ;
1472+ }
1473+
13751474 graph_line_write_column (& line , col , '|' );
13761475
13771476 if (col -> commit == graph -> commit && graph -> num_parents > 2 ) {
0 commit comments