static const char *decorate_get_color(int decorate_use_color, enum decoration_type ix) { if (want_color(decorate_use_color)) return decoration_colors[ix]; return ""; }
static const char *get_color_code(int idx) { if (want_color(showbranch_use_color)) return column_colors_ansi[idx % column_colors_ansi_max]; return ""; }
static const char *get_color_reset_code(void) { if (want_color(showbranch_use_color)) return GIT_COLOR_RESET; return ""; }
static unsigned short graph_get_current_column_color(const struct git_graph *graph) { if (!want_color(graph->revs->diffopt.use_color)) return column_colors_max; return graph->default_column_color; }
static const char *branch_get_color(enum color_branch ix) { if (want_color(branch_use_color)) return branch_colors[ix]; return ""; }
static void fill_tracking_info(struct strbuf *stat, const char *branch_name, int show_upstream_ref) { int ours, theirs; char *ref = NULL; struct branch *branch = branch_get(branch_name); const char *upstream; struct strbuf fancy = STRBUF_INIT; int upstream_is_gone = 0; int added_decoration = 1; if (stat_tracking_info(branch, &ours, &theirs, &upstream) < 0) { if (!upstream) return; upstream_is_gone = 1; } if (show_upstream_ref) { ref = shorten_unambiguous_ref(upstream, 0); if (want_color(branch_use_color)) strbuf_addf(&fancy, "%s%s%s", branch_get_color(BRANCH_COLOR_UPSTREAM), ref, branch_get_color(BRANCH_COLOR_RESET)); else strbuf_addstr(&fancy, ref); } if (upstream_is_gone) { if (show_upstream_ref) strbuf_addf(stat, _("[%s: gone]"), fancy.buf); else added_decoration = 0; } else if (!ours && !theirs) { if (show_upstream_ref) strbuf_addf(stat, _("[%s]"), fancy.buf); else added_decoration = 0; } else if (!ours) { if (show_upstream_ref) strbuf_addf(stat, _("[%s: behind %d]"), fancy.buf, theirs); else strbuf_addf(stat, _("[behind %d]"), theirs); } else if (!theirs) { if (show_upstream_ref) strbuf_addf(stat, _("[%s: ahead %d]"), fancy.buf, ours); else strbuf_addf(stat, _("[ahead %d]"), ours); } else { if (show_upstream_ref) strbuf_addf(stat, _("[%s: ahead %d, behind %d]"), fancy.buf, ours, theirs); else strbuf_addf(stat, _("[ahead %d, behind %d]"), ours, theirs); } strbuf_release(&fancy); if (added_decoration) strbuf_addch(stat, ' '); free(ref); }
static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ const char *placeholder, void *context) { struct format_commit_context *c = context; const struct commit *commit = c->commit; const char *msg = c->message; struct commit_list *p; 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 && sb->len) strbuf_addstr(sb, GIT_COLOR_RESET); return 7; /* consumed 7 bytes, "C(auto)" */ } else { int ret = parse_color(sb, placeholder, c); if (ret) c->auto_color = 0; /* * Otherwise, we decided to treat %C<unknown> * as a literal string, and the previous * %C(auto) is still valid. */ return ret; } case 'n': /* newline */ strbuf_addch(sb, '\n'); return 1; case 'x': /* %x00 == NUL, %x0a == LF, etc. */ 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; char *next; const char *start = placeholder + 2; const char *end = strchr(start, ')'); if (!end) return 0; if (end > start) { width = strtoul(start, &next, 10); if (*next == ',') { indent1 = strtoul(next + 1, &next, 10); if (*next == ',') { indent2 = strtoul(next + 1, &next, 10); } } if (*next != ')') return 0; } rewrap_message_tail(sb, c, width, indent1, indent2); return end - placeholder + 1; } else return 0; case '<': case '>': return parse_padding_placeholder(sb, placeholder, c); } /* these depend on the commit */ if (!commit->object.parsed) parse_object(commit->object.oid.hash); switch (placeholder[0]) { case 'H': /* commit hash */ strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_COMMIT)); strbuf_addstr(sb, oid_to_hex(&commit->object.oid)); strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET)); 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) { if (p != commit->parents) strbuf_addch(sb, ' '); strbuf_addstr(sb, oid_to_hex(&p->item->object.oid)); } 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)); return 1; case 'd': load_ref_decorations(DECORATE_SHORT_REFS); format_decorations(sb, commit, c->auto_color); return 1; case 'D': load_ref_decorations(DECORATE_SHORT_REFS); format_decorations_extended(sb, commit, c->auto_color, "", ", ", ""); return 1; case 'g': /* reflog info */ switch(placeholder[1]) { case 'd': /* reflog selector */ case 'D': if (c->pretty_ctx->reflog_info) get_reflog_selector(sb, c->pretty_ctx->reflog_info, &c->pretty_ctx->date_mode, c->pretty_ctx->date_mode_explicit, (placeholder[1] == 'd')); return 2; case 's': /* reflog message */ if (c->pretty_ctx->reflog_info) get_reflog_message(sb, c->pretty_ctx->reflog_info); return 2; case 'n': case 'N': case 'e': case 'E': return format_reflog_person(sb, placeholder[1], c->pretty_ctx->reflog_info, &c->pretty_ctx->date_mode); } return 0; /* unknown %g placeholder */ case 'N': if (c->pretty_ctx->notes_message) { strbuf_addstr(sb, c->pretty_ctx->notes_message); return 1; } return 0; } if (placeholder[0] == 'G') { if (!c->signature_check.result) check_commit_signature(c->commit, &(c->signature_check)); switch (placeholder[1]) { case 'G': if (c->signature_check.gpg_output) strbuf_addstr(sb, c->signature_check.gpg_output); break; case '?': switch (c->signature_check.result) { case 'G': case 'B': case 'E': case 'U': case 'N': case 'X': case 'Y': case 'R': strbuf_addch(sb, c->signature_check.result); } break; case 'S': if (c->signature_check.signer) strbuf_addstr(sb, c->signature_check.signer); break; case 'K': if (c->signature_check.key) strbuf_addstr(sb, c->signature_check.key); break; default: return 0; } return 2; } /* For the rest we have to parse the commit header. */ if (!c->commit_header_parsed) parse_commit_header(c); switch (placeholder[0]) { case 'a': /* author ... */ return format_person_part(sb, placeholder[1], msg + c->author.off, c->author.len, &c->pretty_ctx->date_mode); case 'c': /* committer ... */ return format_person_part(sb, placeholder[1], msg + c->committer.off, c->committer.len, &c->pretty_ctx->date_mode); case 'e': /* encoding */ if (c->commit_encoding) strbuf_addstr(sb, c->commit_encoding); return 1; case 'B': /* raw body */ /* message_off is always left at the initial newline */ strbuf_addstr(sb, msg + c->message_off + 1); return 1; } /* Now we need to parse the commit message. */ if (!c->commit_message_parsed) parse_commit_message(c); switch (placeholder[0]) { case 's': /* subject */ format_subject(sb, msg + c->subject_off, " "); return 1; case 'f': /* sanitized subject */ format_sanitized_subject(sb, msg + c->subject_off); return 1; case 'b': /* body */ strbuf_addstr(sb, msg + c->body_off); return 1; } if (starts_with(placeholder, "(trailers)")) { format_trailers(sb, msg + c->subject_off); return strlen("(trailers)"); } return 0; /* unknown placeholder */ }
static size_t format_commit_one(struct strbuf *sb, const char *placeholder, void *context) { struct format_commit_context *c = context; const struct commit *commit = c->commit; const char *msg = c->message; struct commit_list *p; int h1, h2; /* these are independent of the commit */ switch (placeholder[0]) { case 'C': if (placeholder[1] == '(') { const char *begin = placeholder + 2; const char *end = strchr(begin, ')'); char color[COLOR_MAXLEN]; if (!end) return 0; if (!prefixcmp(begin, "auto,")) { 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; } if (!prefixcmp(placeholder + 1, "red")) { strbuf_addstr(sb, GIT_COLOR_RED); return 4; } else if (!prefixcmp(placeholder + 1, "green")) { strbuf_addstr(sb, GIT_COLOR_GREEN); return 6; } else if (!prefixcmp(placeholder + 1, "blue")) { strbuf_addstr(sb, GIT_COLOR_BLUE); return 5; } else if (!prefixcmp(placeholder + 1, "reset")) { strbuf_addstr(sb, GIT_COLOR_RESET); return 6; } else return 0; case 'n': /* newline */ strbuf_addch(sb, '\n'); 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 return 0; case 'w': if (placeholder[1] == '(') { unsigned long width = 0, indent1 = 0, indent2 = 0; char *next; const char *start = placeholder + 2; const char *end = strchr(start, ')'); if (!end) return 0; if (end > start) { width = strtoul(start, &next, 10); if (*next == ',') { indent1 = strtoul(next + 1, &next, 10); if (*next == ',') { indent2 = strtoul(next + 1, &next, 10); } } if (*next != ')') return 0; } rewrap_message_tail(sb, c, width, indent1, indent2); return end - placeholder + 1; } else return 0; } /* these depend on the commit */ if (!commit->object.parsed) parse_object(commit->object.sha1); switch (placeholder[0]) { case 'H': /* commit hash */ strbuf_addstr(sb, sha1_to_hex(commit->object.sha1)); return 1; case 'h': /* abbreviated commit hash */ if (add_again(sb, &c->abbrev_commit_hash)) return 1; strbuf_addstr(sb, find_unique_abbrev(commit->object.sha1, c->pretty_ctx->abbrev)); c->abbrev_commit_hash.len = sb->len - c->abbrev_commit_hash.off; return 1; case 'T': /* tree hash */ strbuf_addstr(sb, sha1_to_hex(commit->tree->object.sha1)); return 1; case 't': /* abbreviated tree hash */ if (add_again(sb, &c->abbrev_tree_hash)) return 1; strbuf_addstr(sb, find_unique_abbrev(commit->tree->object.sha1, 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) { if (p != commit->parents) strbuf_addch(sb, ' '); strbuf_addstr(sb, sha1_to_hex(p->item->object.sha1)); } 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_addstr(sb, find_unique_abbrev( p->item->object.sha1, 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)); return 1; case 'd': format_decoration(sb, commit); return 1; case 'g': /* reflog info */ switch(placeholder[1]) { case 'd': /* reflog selector */ case 'D': if (c->pretty_ctx->reflog_info) get_reflog_selector(sb, c->pretty_ctx->reflog_info, c->pretty_ctx->date_mode, c->pretty_ctx->date_mode_explicit, (placeholder[1] == 'd')); return 2; case 's': /* reflog message */ if (c->pretty_ctx->reflog_info) get_reflog_message(sb, c->pretty_ctx->reflog_info); return 2; case 'n': case 'N': case 'e': case 'E': return format_reflog_person(sb, placeholder[1], c->pretty_ctx->reflog_info, c->pretty_ctx->date_mode); } return 0; /* unknown %g placeholder */ case 'N': if (c->pretty_ctx->notes_message) { strbuf_addstr(sb, c->pretty_ctx->notes_message); return 1; } return 0; } if (placeholder[0] == 'G') { if (!c->commit_signature_parsed) parse_commit_signature(c); switch (placeholder[1]) { case 'G': if (c->signature.gpg_output) strbuf_addstr(sb, c->signature.gpg_output); break; case '?': switch (c->signature.good_bad) { case 'G': case 'B': strbuf_addch(sb, c->signature.good_bad); } break; case 'S': if (c->signature.signer) strbuf_addstr(sb, c->signature.signer); break; } return 2; } /* For the rest we have to parse the commit header. */ if (!c->commit_header_parsed) parse_commit_header(c); switch (placeholder[0]) { case 'a': /* author ... */ return format_person_part(sb, placeholder[1], msg + c->author.off, c->author.len, c->pretty_ctx->date_mode); case 'c': /* committer ... */ return format_person_part(sb, placeholder[1], msg + c->committer.off, c->committer.len, c->pretty_ctx->date_mode); case 'e': /* encoding */ strbuf_add(sb, msg + c->encoding.off, c->encoding.len); return 1; case 'B': /* raw body */ /* message_off is always left at the initial newline */ strbuf_addstr(sb, msg + c->message_off + 1); return 1; } /* Now we need to parse the commit message. */ if (!c->commit_message_parsed) parse_commit_message(c); switch (placeholder[0]) { case 's': /* subject */ format_subject(sb, msg + c->subject_off, " "); return 1; case 'f': /* sanitized subject */ format_sanitized_subject(sb, msg + c->subject_off); return 1; case 'b': /* body */ strbuf_addstr(sb, msg + c->body_off); return 1; } return 0; /* unknown placeholder */ }