From: Junio C Hamano Date: Thu, 6 Oct 2016 21:53:12 +0000 (-0700) Subject: Merge branch 'rs/c-auto-resets-attributes' X-Git-Tag: v2.11.0-rc0~77 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/578e6021c0819d7be1179e05e7ce0e6fdb2a01b7?ds=inline;hp=-c Merge branch 'rs/c-auto-resets-attributes' When "%C(auto)" appears at the very beginning of the pretty format string, it did not need to issue the reset sequence, but it did. * rs/c-auto-resets-attributes: pretty: avoid adding reset for %C(auto) if output is empty --- 578e6021c0819d7be1179e05e7ce0e6fdb2a01b7 diff --combined pretty.c index 493edb0a44,bad1bfb225..25efbcac92 --- a/pretty.c +++ 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,14 -87,13 +88,14 @@@ 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 }, + { "mboxrd", CMIT_FMT_MBOXRD, 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; @@@ -174,7 -172,6 +174,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); @@@ -445,7 -442,7 +445,7 @@@ void pp_user_info(struct pretty_print_c if (pp->mailmap) map_user(pp->mailmap, &mailbuf, &maillen, &namebuf, &namelen); - if (pp->fmt == CMIT_FMT_EMAIL) { + if (cmit_fmt_is_mail(pp->fmt)) { if (pp->from_ident && ident_cmp(pp->from_ident, &ident)) { struct strbuf buf = STRBUF_INIT; @@@ -495,7 -492,6 +495,7 @@@ show_ident_date(&ident, &pp->date_mode)); break; case CMIT_FMT_EMAIL: + case CMIT_FMT_MBOXRD: strbuf_addf(sb, "Date: %s\n", show_ident_date(&ident, DATE_MODE(RFC2822))); break; @@@ -509,7 -505,7 +509,7 @@@ } } -static int is_empty_line(const char *line, int *len_p) +static int is_blank_line(const char *line, int *len_p) { int len = *len_p; while (len && isspace(line[len - 1])) @@@ -518,14 -514,14 +518,14 @@@ return !len; } -static const char *skip_empty_lines(const char *msg) +const char *skip_blank_lines(const char *msg) { for (;;) { int linelen = get_one_line(msg); int ll = linelen; if (!linelen) break; - if (!is_empty_line(msg, &ll)) + if (!is_blank_line(msg, &ll)) break; msg += linelen; } @@@ -537,7 -533,7 +537,7 @@@ static void add_merge_info(const struc { struct commit_list *parent = commit->parents; - if ((pp->fmt == CMIT_FMT_ONELINE) || (pp->fmt == CMIT_FMT_EMAIL) || + if ((pp->fmt == CMIT_FMT_ONELINE) || (cmit_fmt_is_mail(pp->fmt)) || !parent || !parent->next) return; @@@ -877,7 -873,7 +877,7 @@@ const char *format_subject(struct strbu int linelen = get_one_line(line); msg += linelen; - if (!linelen || is_empty_line(line, &linelen)) + if (!linelen || is_blank_line(line, &linelen)) break; if (!sb) @@@ -896,11 -892,11 +896,11 @@@ static void parse_commit_message(struc const char *msg = c->message + c->message_off; const char *start = c->message; - msg = skip_empty_lines(msg); + msg = skip_blank_lines(msg); c->subject_off = msg - start; msg = format_subject(NULL, msg, NULL); - msg = skip_empty_lines(msg); + msg = skip_blank_lines(msg); c->body_off = msg - start; c->commit_message_parsed = 1; @@@ -1024,15 -1020,9 +1024,15 @@@ static size_t parse_padding_placeholder int width; if (!end || end == start) return 0; - width = strtoul(start, &next, 10); + width = strtol(start, &next, 10); if (next == start || width == 0) return 0; + if (width < 0) { + if (to_column) + width += term_columns(); + if (width < 0) + return 0; + } c->padding = to_column ? -width : width; c->flush_type = flush_type; @@@ -1065,14 -1055,14 +1065,14 @@@ static size_t format_commit_one(struct const struct commit *commit = c->commit; const char *msg = c->message; struct commit_list *p; - int h1, h2; + int ch; /* these are independent of the commit */ switch (placeholder[0]) { case 'C': if (starts_with(placeholder + 1, "(auto)")) { c->auto_color = want_color(c->pretty_ctx->color); - if (c->auto_color) + if (c->auto_color && sb->len) strbuf_addstr(sb, GIT_COLOR_RESET); return 7; /* consumed 7 bytes, "C(auto)" */ } else { @@@ -1091,11 -1081,14 +1091,11 @@@ return 1; case 'x': /* %x00 == NUL, %x0a == LF, etc. */ - if (0 <= (h1 = hexval_table[0xff & placeholder[1]]) && - h1 <= 16 && - 0 <= (h2 = hexval_table[0xff & placeholder[2]]) && - h2 <= 16) { - strbuf_addch(sb, (h1<<4)|h2); - return 3; - } else + ch = hex2chr(placeholder + 1); + if (ch < 0) return 0; + strbuf_addch(sb, ch); + return 3; case 'w': if (placeholder[1] == '(') { unsigned long width = 0, indent1 = 0, indent2 = 0; @@@ -1142,8 -1135,8 +1142,8 @@@ strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET)); return 1; } - strbuf_addstr(sb, find_unique_abbrev(commit->object.oid.hash, - c->pretty_ctx->abbrev)); + strbuf_add_unique_abbrev(sb, commit->object.oid.hash, + c->pretty_ctx->abbrev); strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET)); c->abbrev_commit_hash.len = sb->len - c->abbrev_commit_hash.off; return 1; @@@ -1153,8 -1146,8 +1153,8 @@@ case 't': /* abbreviated tree hash */ if (add_again(sb, &c->abbrev_tree_hash)) return 1; - strbuf_addstr(sb, find_unique_abbrev(commit->tree->object.oid.hash, - c->pretty_ctx->abbrev)); + strbuf_add_unique_abbrev(sb, commit->tree->object.oid.hash, + c->pretty_ctx->abbrev); c->abbrev_tree_hash.len = sb->len - c->abbrev_tree_hash.off; return 1; case 'P': /* parent hashes */ @@@ -1170,8 -1163,9 +1170,8 @@@ for (p = commit->parents; p; p = p->next) { if (p != commit->parents) strbuf_addch(sb, ' '); - strbuf_addstr(sb, find_unique_abbrev( - p->item->object.oid.hash, - c->pretty_ctx->abbrev)); + strbuf_add_unique_abbrev(sb, p->item->object.oid.hash, + c->pretty_ctx->abbrev); } c->abbrev_parent_hashes.len = sb->len - c->abbrev_parent_hashes.off; @@@ -1305,7 -1299,6 +1305,7 @@@ static size_t format_and_pad_commit(str if (!start) start = sb->buf; occupied = utf8_strnwidth(start, -1, 1); + occupied += c->pretty_ctx->graph_width; padding = (-padding) - occupied; } while (1) { @@@ -1621,7 -1614,7 +1621,7 @@@ void pp_title_line(struct pretty_print_ if (pp->after_subject) { strbuf_addstr(sb, pp->after_subject); } - if (pp->fmt == CMIT_FMT_EMAIL) { + if (cmit_fmt_is_mail(pp->fmt)) { strbuf_addch(sb, '\n'); } @@@ -1638,82 -1631,6 +1638,82 @@@ 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); +} + +static int is_mboxrd_from(const char *line, int len) +{ + /* + * a line matching /^From $/ here would only have len == 4 + * at this point because is_empty_line would've trimmed all + * trailing space + */ + return len > 4 && starts_with(line + strspn(line, ">"), "From "); +} + void pp_remainder(struct pretty_print_context *pp, const char **msg_p, struct strbuf *sb, @@@ -1728,7 -1645,7 +1728,7 @@@ if (!linelen) break; - if (is_empty_line(line, &linelen)) { + if (is_blank_line(line, &linelen)) { if (first) continue; if (pp->fmt == CMIT_FMT_SHORT) @@@ -1738,17 -1655,8 +1738,17 @@@ 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 { + if (pp->fmt == CMIT_FMT_MBOXRD && + is_mboxrd_from(line, linelen)) + strbuf_addch(sb, '>'); + + strbuf_add(sb, line, linelen); + } strbuf_addch(sb, '\n'); } } @@@ -1772,14 -1680,14 +1772,14 @@@ void pretty_print_commit(struct pretty_ encoding = get_log_output_encoding(); msg = reencoded = logmsg_reencode(commit, NULL, encoding); - if (pp->fmt == CMIT_FMT_ONELINE || pp->fmt == CMIT_FMT_EMAIL) + if (pp->fmt == CMIT_FMT_ONELINE || cmit_fmt_is_mail(pp->fmt)) indent = 0; /* * We need to check and emit Content-type: to mark it * as 8-bit if we haven't done so. */ - if (pp->fmt == CMIT_FMT_EMAIL && need_8bit_cte == 0) { + if (cmit_fmt_is_mail(pp->fmt) && need_8bit_cte == 0) { int i, ch, in_body; for (in_body = i = 0; (ch = msg[i]); i++) { @@@ -1804,10 -1712,10 +1804,10 @@@ } /* Skip excess blank lines at the beginning of body, if any... */ - msg = skip_empty_lines(msg); + msg = skip_blank_lines(msg); /* These formats treat the title line specially. */ - if (pp->fmt == CMIT_FMT_ONELINE || pp->fmt == CMIT_FMT_EMAIL) + if (pp->fmt == CMIT_FMT_ONELINE || cmit_fmt_is_mail(pp->fmt)) pp_title_line(pp, &msg, sb, encoding, need_8bit_cte); beginning_of_body = sb->len; @@@ -1824,7 -1732,7 +1824,7 @@@ * format. Make sure we did not strip the blank line * between the header and the body. */ - if (pp->fmt == CMIT_FMT_EMAIL && sb->len <= beginning_of_body) + if (cmit_fmt_is_mail(pp->fmt) && sb->len <= beginning_of_body) strbuf_addch(sb, '\n'); unuse_commit_buffer(commit, reencoded);