Merge branch 'jk/graph-padding-fix'
authorJunio C Hamano <gitster@pobox.com>
Thu, 6 Oct 2016 21:53:11 +0000 (14:53 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 6 Oct 2016 21:53:11 +0000 (14:53 -0700)
The "graph" API used in "git log --graph" miscounted the number of
output columns consumed so far when drawing a padding line, which
has been fixed; this did not affect any existing code as nobody
tried to write anything after the padding on such a line, though.

* jk/graph-padding-fix:
graph: fix extra spaces in graph_padding_line

1  2 
graph.c
diff --combined graph.c
index 06f1139f2e201e1319bece3865ae95060ae2522c,5ad62b8a83d77a8f2cccf87f94a3240977ddb0f0..d4e8519c904df6e18869de527f7fe6d57adf2a26
+++ b/graph.c
@@@ -2,6 -2,7 +2,6 @@@
  #include "commit.h"
  #include "color.h"
  #include "graph.h"
 -#include "diff.h"
  #include "revision.h"
  
  /* Internal API */
@@@ -16,8 -17,8 +16,8 @@@
  static void graph_padding_line(struct git_graph *graph, struct strbuf *sb);
  
  /*
 - * Print a strbuf to stdout.  If the graph is non-NULL, all lines but the
 - * first will be prefixed with the graph output.
 + * Print a strbuf.  If the graph is non-NULL, all lines but the first will be
 + * prefixed with the graph output.
   *
   * If the strbuf ends with a newline, the output will end after this
   * newline.  A new graph line will not be printed after the final newline.
   * responsible for printing this line's graph (perhaps via
   * graph_show_commit() or graph_show_oneline()) before calling
   * graph_show_strbuf().
 + *
 + * Note that unlike some other graph display functions, you must pass the file
 + * handle directly. It is assumed that this is the same file handle as the
 + * file specified by the graph diff options. This is necessary so that
 + * graph_show_strbuf can be called even with a NULL graph.
   */
 -static void graph_show_strbuf(struct git_graph *graph, struct strbuf const *sb);
 +static void graph_show_strbuf(struct git_graph *graph,
 +                            FILE *file,
 +                            struct strbuf const *sb);
  
  /*
   * TODO:
@@@ -65,17 -59,6 +65,17 @@@ enum graph_state 
        GRAPH_COLLAPSING
  };
  
 +static void graph_show_line_prefix(const struct diff_options *diffopt)
 +{
 +      if (!diffopt || !diffopt->line_prefix)
 +              return;
 +
 +      fwrite(diffopt->line_prefix,
 +             sizeof(char),
 +             diffopt->line_prefix_length,
 +             diffopt->file);
 +}
 +
  static const char **column_colors;
  static unsigned short column_colors_max;
  
@@@ -212,28 -195,14 +212,28 @@@ static struct strbuf *diff_output_prefi
        static struct strbuf msgbuf = STRBUF_INIT;
  
        assert(opt);
 -      assert(graph);
  
 -      opt->output_prefix_length = graph->width;
        strbuf_reset(&msgbuf);
 -      graph_padding_line(graph, &msgbuf);
 +      if (opt->line_prefix)
 +              strbuf_add(&msgbuf, opt->line_prefix,
 +                         opt->line_prefix_length);
 +      if (graph)
 +              graph_padding_line(graph, &msgbuf);
        return &msgbuf;
  }
  
 +static const struct diff_options *default_diffopt;
 +
 +void graph_setup_line_prefix(struct diff_options *diffopt)
 +{
 +      default_diffopt = diffopt;
 +
 +      /* setup an output prefix callback if necessary */
 +      if (diffopt && !diffopt->output_prefix)
 +              diffopt->output_prefix = diff_output_prefix_callback;
 +}
 +
 +
  struct git_graph *graph_init(struct rev_info *opt)
  {
        struct git_graph *graph = xmalloc(sizeof(struct git_graph));
         */
        opt->diffopt.output_prefix = diff_output_prefix_callback;
        opt->diffopt.output_prefix_data = graph;
 -      opt->diffopt.output_prefix_length = 0;
  
        return graph;
  }
@@@ -699,13 -669,6 +699,13 @@@ static void graph_output_padding_line(s
        graph_pad_horizontally(graph, sb, graph->num_new_columns * 2);
  }
  
 +
 +int graph_width(struct git_graph *graph)
 +{
 +      return graph->width;
 +}
 +
 +
  static void graph_output_skip_line(struct git_graph *graph, struct strbuf *sb)
  {
        /*
@@@ -1175,6 -1138,7 +1175,7 @@@ int graph_next_line(struct git_graph *g
  static void graph_padding_line(struct git_graph *graph, struct strbuf *sb)
  {
        int i;
+       int chars_written = 0;
  
        if (graph->state != GRAPH_COMMIT) {
                graph_next_line(graph, sb);
         */
        for (i = 0; i < graph->num_columns; i++) {
                struct column *col = &graph->columns[i];
                strbuf_write_column(sb, col, '|');
-               if (col->commit == graph->commit && graph->num_parents > 2)
-                       strbuf_addchars(sb, ' ', (graph->num_parents - 2) * 2);
-               else
+               chars_written++;
+               if (col->commit == graph->commit && graph->num_parents > 2) {
+                       int len = (graph->num_parents - 2) * 2;
+                       strbuf_addchars(sb, ' ', len);
+                       chars_written += len;
+               } else {
                        strbuf_addch(sb, ' ');
+                       chars_written++;
+               }
        }
  
-       graph_pad_horizontally(graph, sb, graph->num_columns);
+       graph_pad_horizontally(graph, sb, chars_written);
  
        /*
         * Update graph->prev_state since we have output a padding line
@@@ -1215,8 -1186,6 +1223,8 @@@ void graph_show_commit(struct git_grap
        struct strbuf msgbuf = STRBUF_INIT;
        int shown_commit_line = 0;
  
 +      graph_show_line_prefix(default_diffopt);
 +
        if (!graph)
                return;
  
  
        while (!shown_commit_line && !graph_is_commit_finished(graph)) {
                shown_commit_line = graph_next_line(graph, &msgbuf);
 -              fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout);
 -              if (!shown_commit_line)
 -                      putchar('\n');
 +              fwrite(msgbuf.buf, sizeof(char), msgbuf.len,
 +                      graph->revs->diffopt.file);
 +              if (!shown_commit_line) {
 +                      putc('\n', graph->revs->diffopt.file);
 +                      graph_show_line_prefix(&graph->revs->diffopt);
 +              }
                strbuf_setlen(&msgbuf, 0);
        }
  
@@@ -1248,13 -1214,11 +1256,13 @@@ void graph_show_oneline(struct git_grap
  {
        struct strbuf msgbuf = STRBUF_INIT;
  
 +      graph_show_line_prefix(default_diffopt);
 +
        if (!graph)
                return;
  
        graph_next_line(graph, &msgbuf);
 -      fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout);
 +      fwrite(msgbuf.buf, sizeof(char), msgbuf.len, graph->revs->diffopt.file);
        strbuf_release(&msgbuf);
  }
  
@@@ -1262,13 -1226,11 +1270,13 @@@ void graph_show_padding(struct git_grap
  {
        struct strbuf msgbuf = STRBUF_INIT;
  
 +      graph_show_line_prefix(default_diffopt);
 +
        if (!graph)
                return;
  
        graph_padding_line(graph, &msgbuf);
 -      fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout);
 +      fwrite(msgbuf.buf, sizeof(char), msgbuf.len, graph->revs->diffopt.file);
        strbuf_release(&msgbuf);
  }
  
@@@ -1277,8 -1239,6 +1285,8 @@@ int graph_show_remainder(struct git_gra
        struct strbuf msgbuf = STRBUF_INIT;
        int shown = 0;
  
 +      graph_show_line_prefix(default_diffopt);
 +
        if (!graph)
                return 0;
  
  
        for (;;) {
                graph_next_line(graph, &msgbuf);
 -              fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout);
 +              fwrite(msgbuf.buf, sizeof(char), msgbuf.len,
 +                      graph->revs->diffopt.file);
                strbuf_setlen(&msgbuf, 0);
                shown = 1;
  
 -              if (!graph_is_commit_finished(graph))
 -                      putchar('\n');
 -              else
 +              if (!graph_is_commit_finished(graph)) {
 +                      putc('\n', graph->revs->diffopt.file);
 +                      graph_show_line_prefix(&graph->revs->diffopt);
 +              } else {
                        break;
 +              }
        }
        strbuf_release(&msgbuf);
  
        return shown;
  }
  
 -
 -static void graph_show_strbuf(struct git_graph *graph, struct strbuf const *sb)
 +static void graph_show_strbuf(struct git_graph *graph,
 +                            FILE *file,
 +                            struct strbuf const *sb)
  {
        char *p;
  
 -      if (!graph) {
 -              fwrite(sb->buf, sizeof(char), sb->len, stdout);
 -              return;
 -      }
 -
        /*
         * Print the strbuf line by line,
         * and display the graph info before each line but the first.
                } else {
                        len = (sb->buf + sb->len) - p;
                }
 -              fwrite(p, sizeof(char), len, stdout);
 +              fwrite(p, sizeof(char), len, file);
                if (next_p && *next_p != '\0')
                        graph_show_oneline(graph);
                p = next_p;
  }
  
  void graph_show_commit_msg(struct git_graph *graph,
 +                         FILE *file,
                           struct strbuf const *sb)
  {
        int newline_terminated;
  
 -      if (!graph) {
 -              /*
 -               * If there's no graph, just print the message buffer.
 -               *
 -               * The message buffer for CMIT_FMT_ONELINE and
 -               * CMIT_FMT_USERFORMAT are already missing a terminating
 -               * newline.  All of the other formats should have it.
 -               */
 -              fwrite(sb->buf, sizeof(char), sb->len, stdout);
 -              return;
 -      }
 -
 -      newline_terminated = (sb->len && sb->buf[sb->len - 1] == '\n');
 -
        /*
         * Show the commit message
         */
 -      graph_show_strbuf(graph, sb);
 +      graph_show_strbuf(graph, file, sb);
 +
 +      if (!graph)
 +              return;
 +
 +      newline_terminated = (sb->len && sb->buf[sb->len - 1] == '\n');
  
        /*
         * If there is more output needed for this commit, show it now
                 * new line.
                 */
                if (!newline_terminated)
 -                      putchar('\n');
 +                      putc('\n', file);
  
                graph_show_remainder(graph);
  
                 * If sb ends with a newline, our output should too.
                 */
                if (newline_terminated)
 -                      putchar('\n');
 +                      putc('\n', file);
        }
  }