diff options
Diffstat (limited to 'pretty.c')
-rw-r--r-- | pretty.c | 86 |
1 files changed, 37 insertions, 49 deletions
@@ -1,4 +1,5 @@ #include "cache.h" +#include "config.h" #include "commit.h" #include "utf8.h" #include "diff.h" @@ -783,29 +784,9 @@ struct format_commit_context { size_t body_off; /* The following ones are relative to the result struct strbuf. */ - struct chunk abbrev_commit_hash; - struct chunk abbrev_tree_hash; - struct chunk abbrev_parent_hashes; size_t wrap_start; }; -static int add_again(struct strbuf *sb, struct chunk *chunk) -{ - if (chunk->len) { - strbuf_adddup(sb, chunk->off, chunk->len); - return 1; - } - - /* - * We haven't seen this chunk before. Our caller is surely - * going to add it the hard way now. Remember the most likely - * start of the to-be-added chunk: the current end of the - * struct strbuf. - */ - chunk->off = sb->len; - return 0; -} - static void parse_commit_header(struct format_commit_context *context) { const char *msg = context->message; @@ -890,16 +871,6 @@ const char *format_subject(struct strbuf *sb, const char *msg, return msg; } -static void format_trailers(struct strbuf *sb, const char *msg) -{ - struct trailer_info info; - - trailer_info_get(&info, msg); - strbuf_add(sb, info.trailer_start, - info.trailer_end - info.trailer_start); - trailer_info_release(&info); -} - static void parse_commit_message(struct format_commit_context *c) { const char *msg = c->message + c->message_off; @@ -966,6 +937,7 @@ static size_t parse_color(struct strbuf *sb, /* in UTF-8 */ struct format_commit_context *c) { const char *rest = placeholder; + const char *basic_color = NULL; if (placeholder[1] == '(') { const char *begin = placeholder + 2; @@ -974,23 +946,41 @@ static size_t parse_color(struct strbuf *sb, /* in UTF-8 */ if (!end) return 0; + if (skip_prefix(begin, "auto,", &begin)) { if (!want_color(c->pretty_ctx->color)) return end - placeholder + 1; + } else if (skip_prefix(begin, "always,", &begin)) { + /* nothing to do; we do not respect want_color at all */ + } else { + /* the default is the same as "auto" */ + if (!want_color(c->pretty_ctx->color)) + return end - placeholder + 1; } + if (color_parse_mem(begin, end - begin, color) < 0) die(_("unable to parse --pretty format")); strbuf_addstr(sb, color); return end - placeholder + 1; } + + /* + * We handle things like "%C(red)" above; for historical reasons, there + * are a few colors that can be specified without parentheses (and + * they cannot support things like "auto" or "always" at all). + */ if (skip_prefix(placeholder + 1, "red", &rest)) - strbuf_addstr(sb, GIT_COLOR_RED); + basic_color = GIT_COLOR_RED; else if (skip_prefix(placeholder + 1, "green", &rest)) - strbuf_addstr(sb, GIT_COLOR_GREEN); + basic_color = GIT_COLOR_GREEN; else if (skip_prefix(placeholder + 1, "blue", &rest)) - strbuf_addstr(sb, GIT_COLOR_BLUE); + basic_color = GIT_COLOR_BLUE; else if (skip_prefix(placeholder + 1, "reset", &rest)) - strbuf_addstr(sb, GIT_COLOR_RESET); + basic_color = GIT_COLOR_RESET; + + if (basic_color && want_color(c->pretty_ctx->color)) + strbuf_addstr(sb, basic_color); + return rest - placeholder; } @@ -1074,6 +1064,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ const struct commit *commit = c->commit; const char *msg = c->message; struct commit_list *p; + const char *arg; int ch; /* these are independent of the commit */ @@ -1147,24 +1138,16 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ return 1; case 'h': /* abbreviated commit hash */ strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_COMMIT)); - if (add_again(sb, &c->abbrev_commit_hash)) { - strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET)); - return 1; - } 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; case 'T': /* tree hash */ strbuf_addstr(sb, oid_to_hex(&commit->tree->object.oid)); return 1; case 't': /* abbreviated tree hash */ - if (add_again(sb, &c->abbrev_tree_hash)) - return 1; 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 */ for (p = commit->parents; p; p = p->next) { @@ -1174,16 +1157,12 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ } return 1; case 'p': /* abbreviated parent hashes */ - if (add_again(sb, &c->abbrev_parent_hashes)) - return 1; for (p = commit->parents; p; p = p->next) { if (p != commit->parents) strbuf_addch(sb, ' '); 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; return 1; case 'm': /* left/right/bottom */ strbuf_addstr(sb, get_revision_mark(NULL, commit)); @@ -1304,9 +1283,18 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ return 1; } - if (starts_with(placeholder, "(trailers)")) { - format_trailers(sb, msg + c->subject_off); - return strlen("(trailers)"); + if (skip_prefix(placeholder, "(trailers", &arg)) { + struct process_trailer_options opts = PROCESS_TRAILER_OPTIONS_INIT; + while (*arg == ':') { + if (skip_prefix(arg, ":only", &arg)) + opts.only_trailers = 1; + else if (skip_prefix(arg, ":unfold", &arg)) + opts.unfold = 1; + } + if (*arg == ')') { + format_trailers_from_commit(sb, msg + c->subject_off, &opts); + return arg - placeholder + 1; + } } return 0; /* unknown placeholder */ |