@matheusbsbs / matheus-bagliano / commits / 9fa708dab1
Fork 0

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