All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lucian Poston <lucian.poston@gmail.com>
To: "Zbigniew Jędrzejewski-Szmek" <zbyszek@in.waw.pl>
Cc: git@vger.kernel.org, Junio C Hamano <gitster@pobox.com>
Subject: Re: [PATCH v2 2/3] Adjust stat width calculations to take --graph output into account
Date: Thu, 12 Apr 2012 00:47:50 -0700	[thread overview]
Message-ID: <CACz_eyc0AjvU0U2FGzqhUTZ_nncuFoAxZ6VGw0=7LVXH4SLqwA@mail.gmail.com> (raw)
In-Reply-To: <4F6C4C90.5050702@in.waw.pl>

On Fri, Mar 23, 2012 at 03:12, Zbigniew Jędrzejewski-Szmek
<zbyszek@in.waw.pl> wrote:
> On 03/23/2012 06:54 AM, Lucian Poston wrote:
>
>> diff --git a/diff.c b/diff.c
>> index 377ec1e..31ba10c 100644
>> --- a/diff.c
>> +++ b/diff.c
>> @@ -1383,6 +1383,8 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
>>       int width, name_width, graph_width, number_width = 4, count;
>>       const char *reset, *add_c, *del_c;
>>       const char *line_prefix = "";
>> +     int line_prefix_length = 0;
>> +     int reserved_character_count;
>>       int extra_shown = 0;
>>       struct strbuf *msg = NULL;
>>
>> @@ -1392,6 +1394,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
>>       if (options->output_prefix) {
>>               msg = options->output_prefix(options, options->output_prefix_data);
>>               line_prefix = msg->buf;
>> +             line_prefix_length = options->output_prefix_length;
>>       }
> Hi,
> line_prefix will only be used once. And options->output_prefix_length will
> be 0 if !options->output_prefix, so line_prefix variable can be eliminated
> and options->output_prefix_length used directly instead.

Rather than adding the line_prefix_length variable, the next patch
will use options->output_prefix_length directly.

>>       count = options->stat_count ? options->stat_count : data->nr;
>> @@ -1427,37 +1430,46 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
>>        * We have width = stat_width or term_columns() columns total.
>>        * We want a maximum of min(max_len, stat_name_width) for the name part.
>>        * We want a maximum of min(max_change, stat_graph_width) for the +- part.
>> -      * We also need 1 for " " and 4 + decimal_width(max_change)
>> -      * for " | NNNN " and one the empty column at the end, altogether
>> +      * Each line needs space for the following characters:
>> +      *   - 1 for the initial " "
>> +      *   - 4 + decimal_width(max_change) for " | NNNN "
>> +      *   - 1 for the empty column at the end,
>> +      * Altogether, the reserved_character_count totals
>>        * 6 + decimal_width(max_change).
>>        *
>> -      * If there's not enough space, we will use the smaller of
>> -      * stat_name_width (if set) and 5/8*width for the filename,
>> -      * and the rest for constant elements + graph part, but no more
>> -      * than stat_graph_width for the graph part.
>> -      * (5/8 gives 50 for filename and 30 for the constant parts + graph
>> -      * for the standard terminal size).
>> +      * Additionally, there may be a line_prefix, which reduces the available
>> +      * width by line_prefix_length.
>> +      *
>> +      * If there's not enough space, we will use the smaller of stat_name_width
>> +      * (if set) and 5/8*width for the filename, and the rest for the graph
>> +      * part, but no more than stat_graph_width for the graph part.
>> +      * Assuming the line prefix is empty, on a standard 80 column terminal
>> +      * this ratio results in 50 characters for the filename and 20 characters
>> +      * for the graph (plus the 10 reserved characters).
>>        *
>>        * In other words: stat_width limits the maximum width, and
>>        * stat_name_width fixes the maximum width of the filename,
>>        * and is also used to divide available columns if there
>>        * aren't enough.
>>        */
>> +     reserved_character_count = 6 + number_width;
>>
>>       if (options->stat_width == -1)
>>               width = term_columns();
>>       else
>>               width = options->stat_width ? options->stat_width : 80;
>>
>> +     width -= line_prefix_length;
>> +
>>       if (options->stat_graph_width == -1)
>>               options->stat_graph_width = diff_stat_graph_width;
>>
>>       /*
>> -      * Guarantee 3/8*16==6 for the graph part
>> -      * and 5/8*16==10 for the filename part
>> +      * Guarantees at least 6 characters for the graph part [16 * 3/8]
>> +      * and at least 10 for the filename part [16 * 5/8]
>>        */
>> -     if (width<  16 + 6 + number_width)
>> -             width = 16 + 6 + number_width;
>> +     if (width<  16 + reserved_character_count)
>> +             width = 16 + reserved_character_count;
>>
>>       /*
>>        * First assign sizes that are wanted, ignoring available width.
>> @@ -1472,16 +1484,36 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
>>       /*
>>        * Adjust adjustable widths not to exceed maximum width
>>        */
>
> In this part below, you add gratuitous braces around single line if-blocks.
> This makes the code (and the diff) longer with no gain.

I prefer gratuitous braces, particularly when conditionals are nested
as they are here. It helps later when maintaining the code if someone
wants to add a debug statement or comment out a line.

I'll remove braces from single line conditionals to keep with the
existing conventions.

>> -     if (name_width + number_width + 6 + graph_width>  width) {
>> -             if (graph_width>  width * 3/8 - number_width - 6)
>> -                     graph_width = width * 3/8 - number_width - 6;
>> +     if (reserved_character_count + name_width + graph_width>  width) {
>> +             /*
>> +              * Reduce graph_width to be at most 3/8 of the unreserved space and no
>> +              * less than 6, which leaves at least 5/8 for the filename.
>> +              */
>> +             if (graph_width>  width * 3/8 - reserved_character_count) {
>> +                     graph_width = width * 3/8 - reserved_character_count;
>> +                     if (graph_width<  6) {
>> +                             graph_width = 6;
>> +                     }
>> +             }
> This extra test is not necessary. Above, after /* Guarantees at least 6 characters
> for the graph part [16 * 3/8] ... */, this should already by so that
> (width * 3/8 - reserved_character_count) is at least 6.

Ahh, this is because the calculations go haywire when the number of
columns is small. I briefly mentioned it here:
http://thread.gmane.org/gmane.comp.version-control.git/193694/focus=193744

graph_width actually can have a negative value under certain
conditions, and this check compensates for that edge case. My earlier
patches took a less conservative approach and adjusted the
calculations so that the value of graph_width would be at least 6, but
it caused several tests to regress. Since the intention of the
original graph_width calculation was place a lower bound of 6 on its
value, I simply enforce that here without affecting the general cases,
which will remain unmodified in order to prevent test regressions.

>> +
>> +             /*
>> +              * If the remaining unreserved space will not accomodate the
>> +              * filenames, adjust name_width to use all available remaining space.
>> +              * Otherwise, assign any extra space to graph_width.
>> +              */
>> +             if (name_width>  width - reserved_character_count - graph_width) {
>> +                     name_width = width - reserved_character_count - graph_width;
>> +             } else {
>> +                     graph_width = width - reserved_character_count - name_width;
>> +             }
>> +
>> +             /*
>> +              * If stat-graph-width was specified, limit graph_width to its value.
>> +              */
>>               if (options->stat_graph_width&&
>> -                 graph_width>  options->stat_graph_width)
>> +                             graph_width>  options->stat_graph_width) {
>>                       graph_width = options->stat_graph_width;
>> -             if (name_width>  width - number_width - 6 - graph_width)
>> -                     name_width = width - number_width - 6 - graph_width;
>> -             else
>> -                     graph_width = width - number_width - 6 - name_width;
>> +             }
> Here, the order of the two tests
> (1) if (options->stat_graph_width && graph_width > options->stat_graph_width)
> (2) if (name_width > width - number_width - 6 - graph_width)
> is reversed. This is not OK, because this means that
> options->stat_graph_width will be used unconditionally, while
> before it was subject to limiting by total width.

If options->stat_graph_width is specified, it should always limit the
value of graph_width, correct? Since (1) is the last test, it can only
decrease the value of graph_width, which would already be limited by
the total width.

I just noticed that name_width isn't being limited to stat_name_width,
if it is specified. I'll add a check for that.

> The tests:
> After the new tests are added, I see:
>
> ok 53 - format-patch ignores COLUMNS (long filename)
> ok 54 - diff respects COLUMNS (long filename)
> ok 55 - show respects COLUMNS (long filename)
> ok 56 - log respects COLUMNS (long filename)
> ok 57 - show respects 80 COLUMNS (long filename)  <=======
> ok 58 - log respects 80 COLUMNS (long filename)   <-------
> ok 59 - show respects 80 COLUMNS (long filename)  <=======
> ok 60 - log respects 80 COLUMNS (long filename)   <-------
>
> So some tests descriptions are duplicated. Also it would be
> nice to test with --graph in more places. I'm attaching a
> replacement patch which adds more tests. It should go *before*
> your series, and your series should  tweak the tests to pass,
> showing what changed.

Thanks, I'll add these.

  reply	other threads:[~2012-04-12  7:47 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-22 19:27 [PATCH v2 1/3] Add output_prefix_length to diff_options Lucian Poston
2012-03-22 19:27 ` [PATCH v2 2/3] Adjust stat width calculations to take --graph output into account Lucian Poston
2012-03-22 20:28   ` Zbigniew Jędrzejewski-Szmek
2012-03-23  4:38     ` Lucian Poston
2012-03-22 20:45   ` Junio C Hamano
2012-03-23  4:44     ` Lucian Poston
2012-03-23  5:54   ` Lucian Poston
2012-03-23 10:12     ` Zbigniew Jędrzejewski-Szmek
2012-04-12  7:47       ` Lucian Poston [this message]
2012-04-12 10:17         ` Zbigniew Jędrzejewski-Szmek
2012-04-16 11:04           ` Lucian Poston
2012-03-23 18:13     ` Junio C Hamano
2012-04-12  8:35       ` Lucian Poston
2012-03-22 19:27 ` [PATCH v2 3/3] t4052: Test that stat width is adjusted for prefixes Lucian Poston
2012-03-23  5:57   ` Lucian Poston

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='CACz_eyc0AjvU0U2FGzqhUTZ_nncuFoAxZ6VGw0=7LVXH4SLqwA@mail.gmail.com' \
    --to=lucian.poston@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=zbyszek@in.waw.pl \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.