Previously, the color escape codes were not printed again when a %+ placeholder was expanded, which could lead to missing colors. In particular, the following command on any commit history exercised the problem: git log --pretty=format:'%h%Cred%+d test' --graph The string 'test' should always be in red, but is not when commits have ref names associated and the %+d placeholder is expanded. This is also not a problem of any pager since the --graph option adds a colored pipe symbol at the beginning of the line, which makes re-setting the color again afterwards necessary. --- pretty.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/pretty.c b/pretty.c index ee6114e3f0..0aabba89ca 100644 --- a/pretty.c +++ b/pretty.c @@ -863,6 +863,7 @@ struct format_commit_context { size_t width, indent1, indent2; int auto_color; int padding; + char curr_color_escape[COLOR_MAXLEN]; /* These offsets are relative to the start of the commit message. */ struct chunk author; @@ -1050,6 +1051,7 @@ static size_t parse_color(struct strbuf *sb, /* in UTF-8 */ if (color_parse_mem(begin, end - begin, color) < 0) die(_("unable to parse --pretty format")); strbuf_addstr(sb, color); + strlcpy(c->curr_color_escape, color, COLOR_MAXLEN); return end - placeholder + 1; } @@ -1067,8 +1069,10 @@ static size_t parse_color(struct strbuf *sb, /* in UTF-8 */ else if (skip_prefix(placeholder + 1, "reset", &rest)) basic_color = GIT_COLOR_RESET; - if (basic_color && want_color(c->pretty_ctx->color)) + if (basic_color && want_color(c->pretty_ctx->color)) { strbuf_addstr(sb, basic_color); + strlcpy(c->curr_color_escape, basic_color, COLOR_MAXLEN); + } return rest - placeholder; } @@ -1360,8 +1364,10 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ case 'C': if (starts_with(placeholder + 1, "(auto)")) { c->auto_color = want_color(c->pretty_ctx->color); - if (c->auto_color && sb->len) + if (c->auto_color && sb->len) { strbuf_addstr(sb, GIT_COLOR_RESET); + c->curr_color_escape[0] = 0; + } return 7; /* consumed 7 bytes, "C(auto)" */ } else { int ret = parse_color(sb, placeholder, c); @@ -1813,9 +1819,11 @@ static size_t format_commit_item(struct strbuf *sb, /* in UTF-8 */ while (sb->len && sb->buf[sb->len - 1] == '\n') strbuf_setlen(sb, sb->len - 1); } else if (orig_len != sb->len) { - if (magic == ADD_LF_BEFORE_NON_EMPTY) + if (magic == ADD_LF_BEFORE_NON_EMPTY) { strbuf_insertstr(sb, orig_len, "\n"); - else if (magic == ADD_SP_BEFORE_NON_EMPTY) + strbuf_insertstr(sb, orig_len + 1, + ((struct format_commit_context *)context)->curr_color_escape); + } else if (magic == ADD_SP_BEFORE_NON_EMPTY) strbuf_insertstr(sb, orig_len, " "); } return consumed + 1; -- 2.35.1