Skip to content

Commit 9fa708d

Browse files
committed
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 <[email protected]>
1 parent a7aebb9 commit 9fa708d

File tree

3 files changed

+70
-2
lines changed

3 files changed

+70
-2
lines changed

Documentation/pretty-formats.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,14 @@ The placeholders are:
132132
- '%n': newline
133133
- '%x00': print a byte from a hex code
134134

135+
If you add a `{plus}` (plus sign) after '%' of a placeholder, a line-feed
136+
is inserted immediately before the expansion if and only if the
137+
placeholder expands to a non-empty string.
138+
139+
If you add a `-` (minus sign) after '%' of a placeholder, line-feeds that
140+
immediately precede the expansion are deleted if and only if the
141+
placeholder expands to an empty string.
142+
135143
* 'tformat:'
136144
+
137145
The 'tformat:' format works exactly like 'format:', except that it

pretty.c

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -595,8 +595,8 @@ static void format_decoration(struct strbuf *sb, const struct commit *commit)
595595
strbuf_addch(sb, ')');
596596
}
597597

598-
static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
599-
void *context)
598+
static size_t format_commit_one(struct strbuf *sb, const char *placeholder,
599+
void *context)
600600
{
601601
struct format_commit_context *c = context;
602602
const struct commit *commit = c->commit;
@@ -739,6 +739,44 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
739739
return 0; /* unknown placeholder */
740740
}
741741

742+
static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
743+
void *context)
744+
{
745+
int consumed;
746+
size_t orig_len;
747+
enum {
748+
NO_MAGIC,
749+
ADD_LF_BEFORE_NON_EMPTY,
750+
DEL_LF_BEFORE_EMPTY,
751+
} magic = NO_MAGIC;
752+
753+
switch (placeholder[0]) {
754+
case '-':
755+
magic = DEL_LF_BEFORE_EMPTY;
756+
break;
757+
case '+':
758+
magic = ADD_LF_BEFORE_NON_EMPTY;
759+
break;
760+
default:
761+
break;
762+
}
763+
if (magic != NO_MAGIC)
764+
placeholder++;
765+
766+
orig_len = sb->len;
767+
consumed = format_commit_one(sb, placeholder, context);
768+
if (magic == NO_MAGIC)
769+
return consumed;
770+
771+
if ((orig_len == sb->len) && magic == DEL_LF_BEFORE_EMPTY) {
772+
while (sb->len && sb->buf[sb->len - 1] == '\n')
773+
strbuf_setlen(sb, sb->len - 1);
774+
} else if ((orig_len != sb->len) && magic == ADD_LF_BEFORE_NON_EMPTY) {
775+
strbuf_insert(sb, orig_len, "\n", 1);
776+
}
777+
return consumed + 1;
778+
}
779+
742780
void format_commit_message(const struct commit *commit,
743781
const void *format, struct strbuf *sb,
744782
enum date_mode dmode)

t/t6006-rev-list-format.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,4 +162,26 @@ test_expect_success 'empty email' '
162162
}
163163
'
164164

165+
test_expect_success 'del LF before empty (1)' '
166+
git show -s --pretty=format:"%s%n%-b%nThanks%n" HEAD^^ >actual &&
167+
test $(wc -l <actual) = 2
168+
'
169+
170+
test_expect_success 'del LF before empty (2)' '
171+
git show -s --pretty=format:"%s%n%-b%nThanks%n" HEAD >actual &&
172+
test $(wc -l <actual) = 6 &&
173+
grep "^$" actual
174+
'
175+
176+
test_expect_success 'add LF before non-empty (1)' '
177+
git show -s --pretty=format:"%s%+b%nThanks%n" HEAD^^ >actual &&
178+
test $(wc -l <actual) = 2
179+
'
180+
181+
test_expect_success 'add LF before non-empty (2)' '
182+
git show -s --pretty=format:"%s%+b%nThanks%n" HEAD >actual &&
183+
test $(wc -l <actual) = 6 &&
184+
grep "^$" actual
185+
'
186+
165187
test_done

0 commit comments

Comments
 (0)