Merge branch 'et/pretty-format-c-auto' into maint
authorJunio C Hamano <gitster@pobox.com>
Mon, 27 Jun 2016 16:56:23 +0000 (09:56 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 27 Jun 2016 16:56:23 +0000 (09:56 -0700)
The commands in `git log` family take %C(auto) in a custom format
string. This unconditionally turned the color on, ignoring
--no-color or with --color=auto when the output is not connected to
a tty; this was corrected to make the format truly behave as
"auto".

* et/pretty-format-c-auto:
format_commit_message: honor `color=auto` for `%C(auto)`

1  2 
pretty.c
diff --combined pretty.c
index 87c44971a1d2070e4d256818e96fccc29472ec4a,3908e8f100b4b26ff417890e1aceca54ce5310fd..c3ec430220a5667685dbdeca5252df48bd65cd41
+++ b/pretty.c
@@@ -16,7 -16,6 +16,7 @@@ static struct cmt_fmt_map 
        const char *name;
        enum cmit_fmt format;
        int is_tformat;
 +      int expand_tabs_in_log;
        int is_alias;
        const char *user_format;
  } *commit_formats;
@@@ -88,13 -87,13 +88,13 @@@ static int git_pretty_formats_config(co
  static void setup_commit_formats(void)
  {
        struct cmt_fmt_map builtin_formats[] = {
 -              { "raw",        CMIT_FMT_RAW,           0 },
 -              { "medium",     CMIT_FMT_MEDIUM,        0 },
 -              { "short",      CMIT_FMT_SHORT,         0 },
 -              { "email",      CMIT_FMT_EMAIL,         0 },
 -              { "fuller",     CMIT_FMT_FULLER,        0 },
 -              { "full",       CMIT_FMT_FULL,          0 },
 -              { "oneline",    CMIT_FMT_ONELINE,       1 }
 +              { "raw",        CMIT_FMT_RAW,           0,      0 },
 +              { "medium",     CMIT_FMT_MEDIUM,        0,      8 },
 +              { "short",      CMIT_FMT_SHORT,         0,      0 },
 +              { "email",      CMIT_FMT_EMAIL,         0,      0 },
 +              { "fuller",     CMIT_FMT_FULLER,        0,      8 },
 +              { "full",       CMIT_FMT_FULL,          0,      8 },
 +              { "oneline",    CMIT_FMT_ONELINE,       1,      0 }
        };
        commit_formats_len = ARRAY_SIZE(builtin_formats);
        builtin_formats_len = commit_formats_len;
@@@ -173,7 -172,6 +173,7 @@@ void get_commit_format(const char *arg
  
        rev->commit_format = commit_format->format;
        rev->use_terminator = commit_format->is_tformat;
 +      rev->expand_tabs_in_log_default = commit_format->expand_tabs_in_log;
        if (commit_format->format == CMIT_FMT_USERFORMAT) {
                save_user_format(rev, commit_format->user_format,
                                 commit_format->is_tformat);
@@@ -1063,7 -1061,7 +1063,7 @@@ static size_t format_commit_one(struct 
        switch (placeholder[0]) {
        case 'C':
                if (starts_with(placeholder + 1, "(auto)")) {
-                       c->auto_color = 1;
+                       c->auto_color = want_color(c->pretty_ctx->color);
                        return 7; /* consumed 7 bytes, "C(auto)" */
                } else {
                        int ret = parse_color(sb, placeholder, c);
@@@ -1631,72 -1629,6 +1631,72 @@@ void pp_title_line(struct pretty_print_
        strbuf_release(&title);
  }
  
 +static int pp_utf8_width(const char *start, const char *end)
 +{
 +      int width = 0;
 +      size_t remain = end - start;
 +
 +      while (remain) {
 +              int n = utf8_width(&start, &remain);
 +              if (n < 0 || !start)
 +                      return -1;
 +              width += n;
 +      }
 +      return width;
 +}
 +
 +static void strbuf_add_tabexpand(struct strbuf *sb, int tabwidth,
 +                               const char *line, int linelen)
 +{
 +      const char *tab;
 +
 +      while ((tab = memchr(line, '\t', linelen)) != NULL) {
 +              int width = pp_utf8_width(line, tab);
 +
 +              /*
 +               * If it wasn't well-formed utf8, or it
 +               * had characters with badly defined
 +               * width (control characters etc), just
 +               * give up on trying to align things.
 +               */
 +              if (width < 0)
 +                      break;
 +
 +              /* Output the data .. */
 +              strbuf_add(sb, line, tab - line);
 +
 +              /* .. and the de-tabified tab */
 +              strbuf_addchars(sb, ' ', tabwidth - (width % tabwidth));
 +
 +              /* Skip over the printed part .. */
 +              linelen -= tab + 1 - line;
 +              line = tab + 1;
 +      }
 +
 +      /*
 +       * Print out everything after the last tab without
 +       * worrying about width - there's nothing more to
 +       * align.
 +       */
 +      strbuf_add(sb, line, linelen);
 +}
 +
 +/*
 + * pp_handle_indent() prints out the intendation, and
 + * the whole line (without the final newline), after
 + * de-tabifying.
 + */
 +static void pp_handle_indent(struct pretty_print_context *pp,
 +                           struct strbuf *sb, int indent,
 +                           const char *line, int linelen)
 +{
 +      strbuf_addchars(sb, ' ', indent);
 +      if (pp->expand_tabs_in_log)
 +              strbuf_add_tabexpand(sb, pp->expand_tabs_in_log, line, linelen);
 +      else
 +              strbuf_add(sb, line, linelen);
 +}
 +
  void pp_remainder(struct pretty_print_context *pp,
                  const char **msg_p,
                  struct strbuf *sb,
  
                strbuf_grow(sb, linelen + indent + 20);
                if (indent)
 -                      strbuf_addchars(sb, ' ', indent);
 -              strbuf_add(sb, line, linelen);
 +                      pp_handle_indent(pp, sb, indent, line, linelen);
 +              else if (pp->expand_tabs_in_log)
 +                      strbuf_add_tabexpand(sb, pp->expand_tabs_in_log,
 +                                           line, linelen);
 +              else
 +                      strbuf_add(sb, line, linelen);
                strbuf_addch(sb, '\n');
        }
  }