[sorry for double post, forgot the mailing list...] To throw in a fourth option, this one adjusts the expansions' cached offsets when the magic makes it necessary. It's not necessary for '%-', because it only makes a difference when the expansion is empty, and in that case - add_again() doesn't consider it cached, - and even if it did, the offset of a zero-length string wouldn't matter. pretty.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/pretty.c b/pretty.c index d0f86f5d8..69c4f2a21 100644 --- a/pretty.c +++ b/pretty.c @@ -1066,9 +1066,17 @@ static size_t parse_padding_placeholder(struct strbuf *sb, return 0; } +enum format_commit_item_magic { + NO_MAGIC, + ADD_LF_BEFORE_NON_EMPTY, + DEL_LF_BEFORE_EMPTY, + ADD_SP_BEFORE_NON_EMPTY +}; + static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ const char *placeholder, - void *context) + void *context, + enum format_commit_item_magic magic) { struct format_commit_context *c = context; const struct commit *commit = c->commit; @@ -1155,6 +1163,8 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ 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; + if (magic == ADD_LF_BEFORE_NON_EMPTY || magic == ADD_SP_BEFORE_NON_EMPTY) + c->abbrev_commit_hash.off++; return 1; case 'T': /* tree hash */ strbuf_addstr(sb, oid_to_hex(&commit->tree->object.oid)); @@ -1165,6 +1175,8 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ 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; + if (magic == ADD_LF_BEFORE_NON_EMPTY || magic == ADD_SP_BEFORE_NON_EMPTY) + c->abbrev_tree_hash.off++; return 1; case 'P': /* parent hashes */ for (p = commit->parents; p; p = p->next) { @@ -1184,6 +1196,8 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ } c->abbrev_parent_hashes.len = sb->len - c->abbrev_parent_hashes.off; + if (magic == ADD_LF_BEFORE_NON_EMPTY || magic == ADD_SP_BEFORE_NON_EMPTY) + c->abbrev_parent_hashes.off++; return 1; case 'm': /* left/right/bottom */ strbuf_addstr(sb, get_revision_mark(NULL, commit)); @@ -1314,7 +1328,8 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ static size_t format_and_pad_commit(struct strbuf *sb, /* in UTF-8 */ const char *placeholder, - struct format_commit_context *c) + struct format_commit_context *c, + enum format_commit_item_magic magic) { struct strbuf local_sb = STRBUF_INIT; int total_consumed = 0, len, padding = c->padding; @@ -1329,7 +1344,7 @@ static size_t format_and_pad_commit(struct strbuf *sb, /* in UTF-8 */ } while (1) { int modifier = *placeholder == 'C'; - int consumed = format_commit_one(&local_sb, placeholder, c); + int consumed = format_commit_one(&local_sb, placeholder, c, magic); total_consumed += consumed; if (!modifier) @@ -1420,12 +1435,7 @@ static size_t format_commit_item(struct strbuf *sb, /* in UTF-8 */ { int consumed; size_t orig_len; - enum { - NO_MAGIC, - ADD_LF_BEFORE_NON_EMPTY, - DEL_LF_BEFORE_EMPTY, - ADD_SP_BEFORE_NON_EMPTY - } magic = NO_MAGIC; + enum format_commit_item_magic magic = NO_MAGIC; switch (placeholder[0]) { case '-': @@ -1445,9 +1455,9 @@ static size_t format_commit_item(struct strbuf *sb, /* in UTF-8 */ orig_len = sb->len; if (((struct format_commit_context *)context)->flush_type != no_flush) - consumed = format_and_pad_commit(sb, placeholder, context); + consumed = format_and_pad_commit(sb, placeholder, context, magic); else - consumed = format_commit_one(sb, placeholder, context); + consumed = format_commit_one(sb, placeholder, context, magic); if (magic == NO_MAGIC) return consumed; -- 2.13.1.438.gc638325b1