Pretty-format: %[+-]x to tweak inter-item newlines

This teaches the "pretty" machinery to expand '%+x' to a LF followed by
the expansion of '%x' if and only if '%x' expands to a non-empty string,
and to remove LFs before '%-x' if '%x' expands to an empty string.  This
works for any supported expansion placeholder 'x'.

This is expected to be immediately useful to reproduce the commit log
message with "%s%+b%n"; "%s%n%b%n" adds one extra LF if the log message is
a one-liner.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Junio C Hamano 2009-10-04 23:43:32 -07:00
parent a7aebb9d00
commit 9fa708dab1
3 changed files with 70 additions and 2 deletions

View File

@ -132,6 +132,14 @@ The placeholders are:
- '%n': newline
- '%x00': print a byte from a hex code
If you add a `{plus}` (plus sign) after '%' of a placeholder, a line-feed
is inserted immediately before the expansion if and only if the
placeholder expands to a non-empty string.
If you add a `-` (minus sign) after '%' of a placeholder, line-feeds that
immediately precede the expansion are deleted if and only if the
placeholder expands to an empty string.
* 'tformat:'
+
The 'tformat:' format works exactly like 'format:', except that it

View File

@ -595,8 +595,8 @@ static void format_decoration(struct strbuf *sb, const struct commit *commit)
strbuf_addch(sb, ')');
}
static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
void *context)
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;
@ -739,6 +739,44 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
return 0; /* unknown placeholder */
}
static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
void *context)
{
int consumed;
size_t orig_len;
enum {
NO_MAGIC,
ADD_LF_BEFORE_NON_EMPTY,
DEL_LF_BEFORE_EMPTY,
} magic = NO_MAGIC;
switch (placeholder[0]) {
case '-':
magic = DEL_LF_BEFORE_EMPTY;
break;
case '+':
magic = ADD_LF_BEFORE_NON_EMPTY;
break;
default:
break;
}
if (magic != NO_MAGIC)
placeholder++;
orig_len = sb->len;
consumed = format_commit_one(sb, placeholder, context);
if (magic == NO_MAGIC)
return consumed;
if ((orig_len == sb->len) && magic == DEL_LF_BEFORE_EMPTY) {
while (sb->len && sb->buf[sb->len - 1] == '\n')
strbuf_setlen(sb, sb->len - 1);
} else if ((orig_len != sb->len) && magic == ADD_LF_BEFORE_NON_EMPTY) {
strbuf_insert(sb, orig_len, "\n", 1);
}
return consumed + 1;
}
void format_commit_message(const struct commit *commit,
const void *format, struct strbuf *sb,
enum date_mode dmode)

View File

@ -162,4 +162,26 @@ test_expect_success 'empty email' '
}
'
test_expect_success 'del LF before empty (1)' '
git show -s --pretty=format:"%s%n%-b%nThanks%n" HEAD^^ >actual &&
test $(wc -l <actual) = 2
'
test_expect_success 'del LF before empty (2)' '
git show -s --pretty=format:"%s%n%-b%nThanks%n" HEAD >actual &&
test $(wc -l <actual) = 6 &&
grep "^$" actual
'
test_expect_success 'add LF before non-empty (1)' '
git show -s --pretty=format:"%s%+b%nThanks%n" HEAD^^ >actual &&
test $(wc -l <actual) = 2
'
test_expect_success 'add LF before non-empty (2)' '
git show -s --pretty=format:"%s%+b%nThanks%n" HEAD >actual &&
test $(wc -l <actual) = 6 &&
grep "^$" actual
'
test_done