@@ -1443,8 +1443,8 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
14431443{
14441444 int i , len , add , del , adds = 0 , dels = 0 ;
14451445 uintmax_t max_change = 0 , max_len = 0 ;
1446- int total_files = data -> nr ;
1447- int width , name_width , graph_width , number_width = 4 , count ;
1446+ int total_files = data -> nr , count ;
1447+ int width , name_width , graph_width , number_width = 0 , bin_width = 0 ;
14481448 const char * reset , * add_c , * del_c ;
14491449 const char * line_prefix = "" ;
14501450 int extra_shown = 0 ;
@@ -1480,8 +1480,21 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
14801480 if (max_len < len )
14811481 max_len = len ;
14821482
1483- if (file -> is_binary || file -> is_unmerged )
1483+ if (file -> is_unmerged ) {
1484+ /* "Unmerged" is 8 characters */
1485+ bin_width = bin_width < 8 ? 8 : bin_width ;
14841486 continue ;
1487+ }
1488+ if (file -> is_binary ) {
1489+ /* "Bin XXX -> YYY bytes" */
1490+ int w = 14 + decimal_width (file -> added )
1491+ + decimal_width (file -> deleted );
1492+ bin_width = bin_width < w ? w : bin_width ;
1493+ /* Display change counts aligned with "Bin" */
1494+ number_width = 3 ;
1495+ continue ;
1496+ }
1497+
14851498 if (max_change < change )
14861499 max_change = change ;
14871500 }
@@ -1506,12 +1519,22 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
15061519 * stat_name_width fixes the maximum width of the filename,
15071520 * and is also used to divide available columns if there
15081521 * aren't enough.
1522+ *
1523+ * Binary files are displayed with "Bin XXX -> YYY bytes"
1524+ * instead of the change count and graph. This part is treated
1525+ * similarly to the graph part, except that it is not
1526+ * "scaled". If total width is too small to accomodate the
1527+ * guaranteed minimum width of the filename part and the
1528+ * separators and this message, this message will "overflow"
1529+ * making the line longer than the maximum width.
15091530 */
15101531
15111532 if (options -> stat_width == -1 )
15121533 width = term_columns () - options -> output_prefix_length ;
15131534 else
15141535 width = options -> stat_width ? options -> stat_width : 80 ;
1536+ number_width = decimal_width (max_change ) > number_width ?
1537+ decimal_width (max_change ) : number_width ;
15151538
15161539 if (options -> stat_graph_width == -1 )
15171540 options -> stat_graph_width = diff_stat_graph_width ;
@@ -1525,10 +1548,14 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
15251548
15261549 /*
15271550 * First assign sizes that are wanted, ignoring available width.
1551+ * strlen("Bin XXX -> YYY bytes") == bin_width, and the part
1552+ * starting from "XXX" should fit in graph_width.
15281553 */
1529- graph_width = (options -> stat_graph_width &&
1530- options -> stat_graph_width < max_change ) ?
1531- options -> stat_graph_width : max_change ;
1554+ graph_width = max_change + 4 > bin_width ? max_change : bin_width - 4 ;
1555+ if (options -> stat_graph_width &&
1556+ options -> stat_graph_width < graph_width )
1557+ graph_width = options -> stat_graph_width ;
1558+
15321559 name_width = (options -> stat_name_width > 0 &&
15331560 options -> stat_name_width < max_len ) ?
15341561 options -> stat_name_width : max_len ;
@@ -1587,7 +1614,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
15871614 if (data -> files [i ]-> is_binary ) {
15881615 fprintf (options -> file , "%s" , line_prefix );
15891616 show_name (options -> file , prefix , name , len );
1590- fprintf (options -> file , " Bin " );
1617+ fprintf (options -> file , " %*s " , number_width , "Bin " );
15911618 fprintf (options -> file , "%s%" PRIuMAX "%s" ,
15921619 del_c , deleted , reset );
15931620 fprintf (options -> file , " -> " );
@@ -1600,7 +1627,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
16001627 else if (data -> files [i ]-> is_unmerged ) {
16011628 fprintf (options -> file , "%s" , line_prefix );
16021629 show_name (options -> file , prefix , name , len );
1603- fprintf (options -> file , " Unmerged\n" );
1630+ fprintf (options -> file , " Unmerged\n" );
16041631 continue ;
16051632 }
16061633
@@ -1629,8 +1656,9 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
16291656 }
16301657 fprintf (options -> file , "%s" , line_prefix );
16311658 show_name (options -> file , prefix , name , len );
1632- fprintf (options -> file , "%5" PRIuMAX "%s" , added + deleted ,
1633- added + deleted ? " " : "" );
1659+ fprintf (options -> file , " %*" PRIuMAX "%s" ,
1660+ number_width , added + deleted ,
1661+ added + deleted ? " " : "" );
16341662 show_graph (options -> file , '+' , add , add_c , reset );
16351663 show_graph (options -> file , '-' , del , del_c , reset );
16361664 fprintf (options -> file , "\n" );
0 commit comments