Merge branch 'jc/format-color-auto'
authorJunio C Hamano <gitster@pobox.com>
Sun, 6 Jan 2013 07:41:57 +0000 (23:41 -0800)
committerJunio C Hamano <gitster@pobox.com>
Sun, 6 Jan 2013 07:41:57 +0000 (23:41 -0800)
Introduce "log --format=%C(auto,blue)Foo%C(auto,reset)" that does
not color its output when writing to a non-terminal.

* jc/format-color-auto:
log --format: teach %C(auto,black) to respect color config
t6006: clean up whitespace

1  2 
commit.h
log-tree.c
pretty.c
diff --combined commit.h
index b6ad8f3f307a46cd5a0555ab346abaa20013b13a,73fd399b09ea9a60965d318e5d282c932a50f44e..0f469e507db7b8517e4f37107d855b7877176085
+++ b/commit.h
@@@ -86,9 -86,10 +86,10 @@@ struct pretty_print_context 
        enum date_mode date_mode;
        unsigned date_mode_explicit:1;
        int need_8bit_cte;
 -      int show_notes;
 +      char *notes_message;
        struct reflog_walk_info *reflog_info;
        const char *output_encoding;
+       int color;
  };
  
  struct userformat_want {
@@@ -99,6 -100,8 +100,6 @@@ extern int has_non_ascii(const char *te
  struct rev_info; /* in revision.h, it circularly uses enum cmit_fmt */
  extern char *logmsg_reencode(const struct commit *commit,
                             const char *output_encoding);
 -extern char *reencode_commit_message(const struct commit *commit,
 -                                   const char **encoding_p);
  extern void get_commit_format(const char *arg, struct rev_info *);
  extern const char *format_subject(struct strbuf *sb, const char *msg,
                                  const char *line_separator);
@@@ -220,8 -223,4 +221,8 @@@ struct commit *get_merge_parent(const c
  
  extern int parse_signed_commit(const unsigned char *sha1,
                               struct strbuf *message, struct strbuf *signature);
 +extern void print_commit_list(struct commit_list *list,
 +                            const char *format_cur,
 +                            const char *format_last);
 +
  #endif /* COMMIT_H */
diff --combined log-tree.c
index 4f86defe324bac8374585df5d9e8ef7b5f9a3524,7185bd65f2540d8c2c929d4f078e280f4d869712..8876c736d4afbb92d862598861145abe0f408cec
@@@ -540,6 -540,7 +540,6 @@@ void show_log(struct rev_info *opt
        struct pretty_print_context ctx = {0};
  
        opt->loginfo = NULL;
 -      ctx.show_notes = opt->show_notes;
        if (!opt->verbose_header) {
                graph_show_commit(opt->graph);
  
        if (!commit->buffer)
                return;
  
 +      if (opt->show_notes) {
 +              int raw;
 +              struct strbuf notebuf = STRBUF_INIT;
 +
 +              raw = (opt->commit_format == CMIT_FMT_USERFORMAT);
 +              format_display_notes(commit->object.sha1, &notebuf,
 +                                   get_log_output_encoding(), raw);
 +              ctx.notes_message = notebuf.len
 +                      ? strbuf_detach(&notebuf, NULL)
 +                      : xcalloc(1, 1);
 +      }
 +
        /*
         * And then the pretty-printed message itself
         */
        ctx.preserve_subject = opt->preserve_subject;
        ctx.reflog_info = opt->reflog_info;
        ctx.fmt = opt->commit_format;
+       ctx.color = opt->diffopt.use_color;
        pretty_print_commit(&ctx, commit, &msgbuf);
  
        if (opt->add_signoff)
                append_signoff(&msgbuf, opt->add_signoff);
 +
 +      if ((ctx.fmt != CMIT_FMT_USERFORMAT) &&
 +          ctx.notes_message && *ctx.notes_message) {
 +              if (ctx.fmt == CMIT_FMT_EMAIL) {
 +                      strbuf_addstr(&msgbuf, "---\n");
 +                      opt->shown_dashes = 1;
 +              }
 +              strbuf_addstr(&msgbuf, ctx.notes_message);
 +      }
 +
        if (opt->show_log_size) {
                printf("log size %i\n", (int)msgbuf.len);
                graph_show_oneline(opt->graph);
        }
  
        strbuf_release(&msgbuf);
 +      free(ctx.notes_message);
  }
  
  int log_tree_diff_flush(struct rev_info *opt)
  {
 +      opt->shown_dashes = 0;
        diffcore_std(&opt->diffopt);
  
        if (diff_queue_is_empty()) {
        }
  
        if (opt->loginfo && !opt->no_commit_id) {
 -              /* When showing a verbose header (i.e. log message),
 -               * and not in --pretty=oneline format, we would want
 -               * an extra newline between the end of log and the
 -               * output for readability.
 -               */
                show_log(opt);
                if ((opt->diffopt.output_format & ~DIFF_FORMAT_NO_OUTPUT) &&
                    opt->verbose_header &&
                    opt->commit_format != CMIT_FMT_ONELINE) {
 +                      /*
 +                       * When showing a verbose header (i.e. log message),
 +                       * and not in --pretty=oneline format, we would want
 +                       * an extra newline between the end of log and the
 +                       * diff/diffstat output for readability.
 +                       */
                        int pch = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_PATCH;
                        if (opt->diffopt.output_prefix) {
                                struct strbuf *msg = NULL;
                                        opt->diffopt.output_prefix_data);
                                fwrite(msg->buf, msg->len, 1, stdout);
                        }
 -                      if ((pch & opt->diffopt.output_format) == pch) {
 +
 +                      /*
 +                       * We may have shown three-dashes line early
 +                       * between notes and the log message, in which
 +                       * case we only want a blank line after the
 +                       * notes without (an extra) three-dashes line.
 +                       * Otherwise, we show the three-dashes line if
 +                       * we are showing the patch with diffstat, but
 +                       * in that case, there is no extra blank line
 +                       * after the three-dashes line.
 +                       */
 +                      if (!opt->shown_dashes &&
 +                          (pch & opt->diffopt.output_format) == pch)
                                printf("---");
 -                      }
                        putchar('\n');
                }
        }
diff --combined pretty.c
index 91bb2d3ef675b12ac5425ae71600e13c1adc34f9,63350af6145248aaaafc131ebbdb4e8a91ae7eb0..92c839fe641da15d05c2afe2b498a9fe390624c8
+++ b/pretty.c
@@@ -567,7 -567,7 +567,7 @@@ char *logmsg_reencode(const struct comm
        char *encoding;
        char *out;
  
 -      if (!*output_encoding)
 +      if (!output_encoding || !*output_encoding)
                return NULL;
        encoding = get_header(commit, "encoding");
        use_encoding = encoding ? encoding : utf8;
@@@ -960,12 -960,19 +960,19 @@@ static size_t format_commit_one(struct 
        switch (placeholder[0]) {
        case 'C':
                if (placeholder[1] == '(') {
-                       const char *end = strchr(placeholder + 2, ')');
+                       const char *begin = placeholder + 2;
+                       const char *end = strchr(begin, ')');
                        char color[COLOR_MAXLEN];
                        if (!end)
                                return 0;
-                       color_parse_mem(placeholder + 2,
-                                       end - (placeholder + 2),
+                       if (!memcmp(begin, "auto,", 5)) {
+                               if (!want_color(c->pretty_ctx->color))
+                                       return end - placeholder + 1;
+                               begin += 5;
+                       }
+                       color_parse_mem(begin,
+                                       end - begin,
                                        "--pretty format", color);
                        strbuf_addstr(sb, color);
                        return end - placeholder + 1;
                }
                return 0;       /* unknown %g placeholder */
        case 'N':
 -              if (c->pretty_ctx->show_notes) {
 -                      format_display_notes(commit->object.sha1, sb,
 -                                  get_log_output_encoding(), 0);
 +              if (c->pretty_ctx->notes_message) {
 +                      strbuf_addstr(sb, c->pretty_ctx->notes_message);
                        return 1;
                }
                return 0;
@@@ -1250,15 -1258,23 +1257,15 @@@ void format_commit_message(const struc
                           const struct pretty_print_context *pretty_ctx)
  {
        struct format_commit_context context;
 -      static const char utf8[] = "UTF-8";
        const char *output_enc = pretty_ctx->output_encoding;
  
        memset(&context, 0, sizeof(context));
        context.commit = commit;
        context.pretty_ctx = pretty_ctx;
        context.wrap_start = sb->len;
 -      context.message = commit->buffer;
 -      if (output_enc) {
 -              char *enc = get_header(commit, "encoding");
 -              if (strcmp(enc ? enc : utf8, output_enc)) {
 -                      context.message = logmsg_reencode(commit, output_enc);
 -                      if (!context.message)
 -                              context.message = commit->buffer;
 -              }
 -              free(enc);
 -      }
 +      context.message = logmsg_reencode(commit, output_enc);
 +      if (!context.message)
 +              context.message = commit->buffer;
  
        strbuf_expand(sb, format, format_commit_item, &context);
        rewrap_message_tail(sb, &context, 0, 0, 0);
@@@ -1405,6 -1421,16 +1412,6 @@@ void pp_remainder(const struct pretty_p
        }
  }
  
 -char *reencode_commit_message(const struct commit *commit, const char **encoding_p)
 -{
 -      const char *encoding;
 -
 -      encoding = get_log_output_encoding();
 -      if (encoding_p)
 -              *encoding_p = encoding;
 -      return logmsg_reencode(commit, encoding);
 -}
 -
  void pretty_print_commit(const struct pretty_print_context *pp,
                         const struct commit *commit,
                         struct strbuf *sb)
                return;
        }
  
 -      reencoded = reencode_commit_message(commit, &encoding);
 +      encoding = get_log_output_encoding();
 +      reencoded = logmsg_reencode(commit, encoding);
        if (reencoded) {
                msg = reencoded;
        }
        if (pp->fmt == CMIT_FMT_EMAIL && sb->len <= beginning_of_body)
                strbuf_addch(sb, '\n');
  
 -      if (pp->show_notes)
 -              format_display_notes(commit->object.sha1, sb, encoding,
 -                                   NOTES_SHOW_HEADER | NOTES_INDENT);
 -
        free(reencoded);
  }