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>
Junio C Hamano committed
Oct 4, 2009 at 23:43 UTC
9fa708dab1ccf8be69a606ca4eb58e62f3ef334a
3 files changed
+70
-2
Documentation/pretty-formats.txt
+8
@@ -132,6 +132,14 @@ The placeholders are:
132
- '%n': newline
133
- '%x00': print a byte from a hex code
134
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
+
143
* 'tformat:'
144
+
145
The 'tformat:' format works exactly like 'format:', except that it
pretty.c
+40
-2
@@ -595,8 +595,8 @@ static void format_decoration(struct strbuf *sb, const struct commit *commit)
595
strbuf_addch(sb, ')');
596
}
597
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)
600
{
601
struct format_commit_context *c = context;
602
const struct commit *commit = c->commit;
@@ -739,6 +739,44 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
739
return 0; /* unknown placeholder */
740
}
741
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
+
780
void format_commit_message(const struct commit *commit,
781
const void *format, struct strbuf *sb,
782
enum date_mode dmode)
t/t6006-rev-list-format.sh
+22
@@ -162,4 +162,26 @@ test_expect_success 'empty email' '
162
}
163
'
164
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
+
187
test_done