]> git.ipfire.org Git - thirdparty/git.git/blame - pretty.c
The twentieth batch
[thirdparty/git.git] / pretty.c
CommitLineData
77f091ed 1#include "git-compat-util.h"
b2141fc1 2#include "config.h"
93fc05eb 3#include "commit.h"
32a8f510 4#include "environment.h"
f394e093 5#include "gettext.h"
df6e8744 6#include "hash.h"
41771fa4 7#include "hex.h"
93fc05eb
JS
8#include "utf8.h"
9#include "diff.h"
ca4eed70 10#include "pager.h"
93fc05eb 11#include "revision.h"
c455c87c 12#include "string-list.h"
e0cbc397 13#include "mailmap.h"
3b3d443f 14#include "log-tree.h"
a97a7468 15#include "notes.h"
c002922a 16#include "color.h"
8f8f5476 17#include "reflog-walk.h"
f6667c5e 18#include "gpg-interface.h"
d9f31fbf 19#include "trailer.h"
15ae82d5 20#include "run-command.h"
f9401850 21#include "object-name.h"
93fc05eb 22
304a50ad
PS
23/*
24 * The limit for formatting directives, which enable the caller to append
25 * arbitrarily many bytes to the formatted buffer. This includes padding
26 * and wrapping formatters.
27 */
28#define FORMATTING_LIMIT (16 * 1024)
29
93fc05eb 30static char *user_format;
40957891
WP
31static struct cmt_fmt_map {
32 const char *name;
33 enum cmit_fmt format;
34 int is_tformat;
0893eec8 35 int expand_tabs_in_log;
2d7671ef 36 int is_alias;
618a8550 37 enum date_mode_type default_date_mode_type;
2d7671ef 38 const char *user_format;
40957891 39} *commit_formats;
8028184e 40static size_t builtin_formats_len;
40957891 41static size_t commit_formats_len;
8028184e 42static size_t commit_formats_alloc;
40957891 43static struct cmt_fmt_map *find_commit_format(const char *sought);
93fc05eb 44
b9c7d6e4
JK
45int commit_format_is_empty(enum cmit_fmt fmt)
46{
47 return fmt == CMIT_FMT_USERFORMAT && !*user_format;
48}
49
36407548
NS
50static void save_user_format(struct rev_info *rev, const char *cp, int is_tformat)
51{
52 free(user_format);
53 user_format = xstrdup(cp);
54 if (is_tformat)
55 rev->use_terminator = 1;
56 rev->commit_format = CMIT_FMT_USERFORMAT;
57}
58
783a86c1 59static int git_pretty_formats_config(const char *var, const char *value,
a4e7e317 60 const struct config_context *ctx UNUSED,
5cf88fd8 61 void *cb UNUSED)
93fc05eb 62{
8028184e
WP
63 struct cmt_fmt_map *commit_format = NULL;
64 const char *name;
65 const char *fmt;
93fc05eb 66 int i;
8028184e 67
95b567c7 68 if (!skip_prefix(var, "pretty.", &name))
8028184e
WP
69 return 0;
70
8028184e
WP
71 for (i = 0; i < builtin_formats_len; i++) {
72 if (!strcmp(commit_formats[i].name, name))
73 return 0;
74 }
75
76 for (i = builtin_formats_len; i < commit_formats_len; i++) {
77 if (!strcmp(commit_formats[i].name, name)) {
78 commit_format = &commit_formats[i];
79 break;
80 }
81 }
82
83 if (!commit_format) {
84 ALLOC_GROW(commit_formats, commit_formats_len+1,
85 commit_formats_alloc);
86 commit_format = &commit_formats[commit_formats_len];
95a2618f 87 memset(commit_format, 0, sizeof(*commit_format));
8028184e
WP
88 commit_formats_len++;
89 }
90
91 commit_format->name = xstrdup(name);
92 commit_format->format = CMIT_FMT_USERFORMAT;
a26bc613
TA
93 if (git_config_string(&fmt, var, value))
94 return -1;
95
e3f1da98
RS
96 if (skip_prefix(fmt, "format:", &fmt))
97 commit_format->is_tformat = 0;
98 else if (skip_prefix(fmt, "tformat:", &fmt) || strchr(fmt, '%'))
8028184e
WP
99 commit_format->is_tformat = 1;
100 else
101 commit_format->is_alias = 1;
102 commit_format->user_format = fmt;
103
104 return 0;
105}
106
40957891 107static void setup_commit_formats(void)
93fc05eb 108{
40957891 109 struct cmt_fmt_map builtin_formats[] = {
0893eec8 110 { "raw", CMIT_FMT_RAW, 0, 0 },
fe37a9c5 111 { "medium", CMIT_FMT_MEDIUM, 0, 8 },
0893eec8
JH
112 { "short", CMIT_FMT_SHORT, 0, 0 },
113 { "email", CMIT_FMT_EMAIL, 0, 0 },
9f23e040 114 { "mboxrd", CMIT_FMT_MBOXRD, 0, 0 },
fe37a9c5
JH
115 { "fuller", CMIT_FMT_FULLER, 0, 8 },
116 { "full", CMIT_FMT_FULL, 0, 8 },
1f0fc1db
DL
117 { "oneline", CMIT_FMT_ONELINE, 1, 0 },
118 { "reference", CMIT_FMT_USERFORMAT, 1, 0,
119 0, DATE_SHORT, "%C(auto)%h (%s, %ad)" },
5a59a230
NTND
120 /*
121 * Please update $__git_log_pretty_formats in
122 * git-completion.bash when you add new formats.
123 */
4da45bef 124 };
40957891 125 commit_formats_len = ARRAY_SIZE(builtin_formats);
8028184e
WP
126 builtin_formats_len = commit_formats_len;
127 ALLOC_GROW(commit_formats, commit_formats_len, commit_formats_alloc);
921d49be
RS
128 COPY_ARRAY(commit_formats, builtin_formats,
129 ARRAY_SIZE(builtin_formats));
8028184e
WP
130
131 git_config(git_pretty_formats_config, NULL);
40957891
WP
132}
133
2d7671ef
WP
134static struct cmt_fmt_map *find_commit_format_recursive(const char *sought,
135 const char *original,
136 int num_redirections)
40957891
WP
137{
138 struct cmt_fmt_map *found = NULL;
139 size_t found_match_len = 0;
140 int i;
141
2d7671ef
WP
142 if (num_redirections >= commit_formats_len)
143 die("invalid --pretty format: "
144 "'%s' references an alias which points to itself",
145 original);
40957891
WP
146
147 for (i = 0; i < commit_formats_len; i++) {
148 size_t match_len;
149
f999d518 150 if (!istarts_with(commit_formats[i].name, sought))
40957891
WP
151 continue;
152
153 match_len = strlen(commit_formats[i].name);
154 if (found == NULL || found_match_len > match_len) {
155 found = &commit_formats[i];
156 found_match_len = match_len;
157 }
158 }
2d7671ef
WP
159
160 if (found && found->is_alias) {
161 found = find_commit_format_recursive(found->user_format,
162 original,
163 num_redirections+1);
164 }
165
40957891
WP
166 return found;
167}
168
2d7671ef
WP
169static struct cmt_fmt_map *find_commit_format(const char *sought)
170{
171 if (!commit_formats)
172 setup_commit_formats();
173
174 return find_commit_format_recursive(sought, sought, 0);
175}
176
40957891
WP
177void get_commit_format(const char *arg, struct rev_info *rev)
178{
179 struct cmt_fmt_map *commit_format;
93fc05eb 180
4da45bef 181 rev->use_terminator = 0;
c75e7ad2 182 if (!arg) {
4da45bef
JH
183 rev->commit_format = CMIT_FMT_DEFAULT;
184 return;
185 }
e3f1da98
RS
186 if (skip_prefix(arg, "format:", &arg)) {
187 save_user_format(rev, arg, 0);
4da45bef 188 return;
93fc05eb 189 }
40957891 190
e3f1da98 191 if (!*arg || skip_prefix(arg, "tformat:", &arg) || strchr(arg, '%')) {
36407548
NS
192 save_user_format(rev, arg, 1);
193 return;
194 }
93fc05eb 195
40957891
WP
196 commit_format = find_commit_format(arg);
197 if (!commit_format)
198 die("invalid --pretty format: %s", arg);
199
200 rev->commit_format = commit_format->format;
201 rev->use_terminator = commit_format->is_tformat;
0893eec8 202 rev->expand_tabs_in_log_default = commit_format->expand_tabs_in_log;
618a8550
DL
203 if (!rev->date_mode_explicit && commit_format->default_date_mode_type)
204 rev->date_mode.type = commit_format->default_date_mode_type;
8028184e
WP
205 if (commit_format->format == CMIT_FMT_USERFORMAT) {
206 save_user_format(rev, commit_format->user_format,
207 commit_format->is_tformat);
208 }
93fc05eb
JS
209}
210
211/*
212 * Generic support for pretty-printing the header
213 */
214static int get_one_line(const char *msg)
215{
216 int ret = 0;
217
218 for (;;) {
219 char c = *msg++;
220 if (!c)
221 break;
222 ret++;
223 if (c == '\n')
224 break;
225 }
226 return ret;
227}
228
229/* High bit set, or ISO-2022-INT */
cc571142 230static int non_ascii(int ch)
93fc05eb 231{
c2e9364a 232 return !isascii(ch) || ch == '\033';
93fc05eb
JS
233}
234
28e9cf65
JS
235int has_non_ascii(const char *s)
236{
237 int ch;
238 if (!s)
239 return 0;
240 while ((ch = *s++) != '\0') {
241 if (non_ascii(ch))
242 return 1;
243 }
244 return 0;
245}
246
4d03c18a
JK
247static int is_rfc822_special(char ch)
248{
249 switch (ch) {
250 case '(':
251 case ')':
252 case '<':
253 case '>':
254 case '[':
255 case ']':
256 case ':':
257 case ';':
258 case '@':
259 case ',':
260 case '.':
261 case '"':
262 case '\\':
263 return 1;
264 default:
265 return 0;
266 }
267}
268
41dd00ba 269static int needs_rfc822_quoting(const char *s, int len)
4d03c18a
JK
270{
271 int i;
272 for (i = 0; i < len; i++)
273 if (is_rfc822_special(s[i]))
274 return 1;
275 return 0;
276}
277
f9b7204b
JS
278static int last_line_length(struct strbuf *sb)
279{
280 int i;
281
282 /* How many bytes are already used on the last line? */
283 for (i = sb->len - 1; i >= 0; i--)
284 if (sb->buf[i] == '\n')
285 break;
286 return sb->len - (i + 1);
287}
288
4d03c18a
JK
289static void add_rfc822_quoted(struct strbuf *out, const char *s, int len)
290{
291 int i;
292
293 /* just a guess, we may have to also backslash-quote */
294 strbuf_grow(out, len + 2);
295
296 strbuf_addch(out, '"');
297 for (i = 0; i < len; i++) {
298 switch (s[i]) {
299 case '"':
300 case '\\':
301 strbuf_addch(out, '\\');
302 /* fall through */
303 default:
304 strbuf_addch(out, s[i]);
305 }
306 }
307 strbuf_addch(out, '"');
308}
309
0fcec2ce
JS
310enum rfc2047_type {
311 RFC2047_SUBJECT,
78273520 312 RFC2047_ADDRESS
0fcec2ce
JS
313};
314
315static int is_rfc2047_special(char ch, enum rfc2047_type type)
93fc05eb 316{
0fcec2ce
JS
317 /*
318 * rfc2047, section 4.2:
319 *
320 * 8-bit values which correspond to printable ASCII characters other
321 * than "=", "?", and "_" (underscore), MAY be represented as those
322 * characters. (But see section 5 for restrictions.) In
323 * particular, SPACE and TAB MUST NOT be represented as themselves
324 * within encoded words.
325 */
326
327 /*
328 * rule out non-ASCII characters and non-printable characters (the
329 * non-ASCII check should be redundant as isprint() is not localized
330 * and only knows about ASCII, but be defensive about that)
331 */
332 if (non_ascii(ch) || !isprint(ch))
333 return 1;
334
335 /*
336 * rule out special printable characters (' ' should be the only
337 * whitespace character considered printable, but be defensive and use
338 * isspace())
339 */
340 if (isspace(ch) || ch == '=' || ch == '?' || ch == '_')
94f6cdf6
JS
341 return 1;
342
0fcec2ce
JS
343 /*
344 * rfc2047, section 5.3:
345 *
346 * As a replacement for a 'word' entity within a 'phrase', for example,
347 * one that precedes an address in a From, To, or Cc header. The ABNF
348 * definition for 'phrase' from RFC 822 thus becomes:
349 *
350 * phrase = 1*( encoded-word / word )
351 *
352 * In this case the set of characters that may be used in a "Q"-encoded
353 * 'encoded-word' is restricted to: <upper and lower case ASCII
354 * letters, decimal digits, "!", "*", "+", "-", "/", "=", and "_"
355 * (underscore, ASCII 95.)>. An 'encoded-word' that appears within a
356 * 'phrase' MUST be separated from any adjacent 'word', 'text' or
357 * 'special' by 'linear-white-space'.
358 */
359
360 if (type != RFC2047_ADDRESS)
361 return 0;
362
363 /* '=' and '_' are special cases and have been checked above */
364 return !(isalnum(ch) || ch == '!' || ch == '*' || ch == '+' || ch == '-' || ch == '/');
93fc05eb
JS
365}
366
da55ff3d 367static int needs_rfc2047_encoding(const char *line, int len)
93fc05eb 368{
a1f6baa5 369 int i;
93fc05eb
JS
370
371 for (i = 0; i < len; i++) {
372 int ch = line[i];
c22e7de3 373 if (non_ascii(ch) || ch == '\n')
41dd00ba 374 return 1;
93fc05eb 375 if ((i + 1 < len) && (ch == '=' && line[i+1] == '?'))
41dd00ba 376 return 1;
93fc05eb 377 }
93fc05eb 378
41dd00ba
JS
379 return 0;
380}
381
6cd3c053 382static void add_rfc2047(struct strbuf *sb, const char *line, size_t len,
41dd00ba
JS
383 const char *encoding, enum rfc2047_type type)
384{
385 static const int max_encoded_length = 76; /* per rfc2047 */
386 int i;
387 int line_len = last_line_length(sb);
388
93fc05eb
JS
389 strbuf_grow(sb, len * 3 + strlen(encoding) + 100);
390 strbuf_addf(sb, "=?%s?q?", encoding);
a1f6baa5 391 line_len += strlen(encoding) + 5; /* 5 for =??q? */
6cd3c053
KS
392
393 while (len) {
394 /*
395 * RFC 2047, section 5 (3):
396 *
397 * Each 'encoded-word' MUST represent an integral number of
398 * characters. A multi-octet character may not be split across
399 * adjacent 'encoded- word's.
400 */
401 const unsigned char *p = (const unsigned char *)line;
402 int chrlen = mbs_chrlen(&line, &len, encoding);
403 int is_special = (chrlen > 1) || is_rfc2047_special(*p, type);
404
405 /* "=%02X" * chrlen, or the byte itself */
406 const char *encoded_fmt = is_special ? "=%02X" : "%c";
407 int encoded_len = is_special ? 3 * chrlen : 1;
94f6cdf6
JS
408
409 /*
410 * According to RFC 2047, we could encode the special character
411 * ' ' (space) with '_' (underscore) for readability. But many
412 * programs do not understand this and just leave the
413 * underscore in place. Thus, we do nothing special here, which
414 * causes ' ' to be encoded as '=20', avoiding this problem.
415 */
a1f6baa5 416
6cd3c053
KS
417 if (line_len + encoded_len + 2 > max_encoded_length) {
418 /* It won't fit with trailing "?=" --- break the line */
a1f6baa5
JK
419 strbuf_addf(sb, "?=\n =?%s?q?", encoding);
420 line_len = strlen(encoding) + 5 + 1; /* =??q? plus SP */
421 }
422
6cd3c053
KS
423 for (i = 0; i < chrlen; i++)
424 strbuf_addf(sb, encoded_fmt, p[i]);
425 line_len += encoded_len;
93fc05eb 426 }
93fc05eb
JS
427 strbuf_addstr(sb, "?=");
428}
429
d1053246 430const char *show_ident_date(const struct ident_split *ident,
9720d23e 431 struct date_mode mode)
9dbe7c3d 432{
dddbad72 433 timestamp_t date = 0;
3f419d45 434 long tz = 0;
9dbe7c3d
RS
435
436 if (ident->date_begin && ident->date_end)
1aeb7e75 437 date = parse_timestamp(ident->date_begin, NULL, 10);
1dca155f
JK
438 if (date_overflows(date))
439 date = 0;
440 else {
441 if (ident->tz_begin && ident->tz_end)
442 tz = strtol(ident->tz_begin, NULL, 10);
3f419d45 443 if (tz >= INT_MAX || tz <= INT_MIN)
1dca155f
JK
444 tz = 0;
445 }
9dbe7c3d
RS
446 return show_date(date, tz, mode);
447}
448
6a5c3379
HM
449static inline void strbuf_add_with_color(struct strbuf *sb, const char *color,
450 const char *buf, size_t buflen)
451{
452 strbuf_addstr(sb, color);
453 strbuf_add(sb, buf, buflen);
454 if (*color)
455 strbuf_addstr(sb, GIT_COLOR_RESET);
456}
457
458static void append_line_with_color(struct strbuf *sb, struct grep_opt *opt,
459 const char *line, size_t linelen,
460 int color, enum grep_context ctx,
461 enum grep_header_field field)
462{
463 const char *buf, *eol, *line_color, *match_color;
464 regmatch_t match;
465 int eflags = 0;
466
467 buf = line;
468 eol = buf + linelen;
469
470 if (!opt || !want_color(color) || opt->invert)
471 goto end;
472
473 line_color = opt->colors[GREP_COLOR_SELECTED];
474 match_color = opt->colors[GREP_COLOR_MATCH_SELECTED];
475
476 while (grep_next_match(opt, buf, eol, ctx, &match, field, eflags)) {
477 if (match.rm_so == match.rm_eo)
478 break;
479
480 strbuf_add_with_color(sb, line_color, buf, match.rm_so);
481 strbuf_add_with_color(sb, match_color, buf + match.rm_so,
482 match.rm_eo - match.rm_so);
483 buf += match.rm_eo;
484 eflags = REG_NOTBOL;
485 }
486
487 if (eflags)
488 strbuf_add_with_color(sb, line_color, buf, eol - buf);
489 else {
490end:
491 strbuf_add(sb, buf, eol - buf);
492 }
493}
494
b84d0139
JH
495static int use_in_body_from(const struct pretty_print_context *pp,
496 const struct ident_split *ident)
497{
34bc1b10
JH
498 if (pp->rev && pp->rev->force_in_body_from)
499 return 1;
b84d0139
JH
500 if (ident_cmp(pp->from_ident, ident))
501 return 1;
502 return 0;
503}
504
10f2fbff 505void pp_user_info(struct pretty_print_context *pp,
6bf13944
JK
506 const char *what, struct strbuf *sb,
507 const char *line, const char *encoding)
93fc05eb 508{
3c020bd5 509 struct ident_split ident;
9dbe7c3d 510 char *line_end;
dffd325f
AP
511 const char *mailbuf, *namebuf;
512 size_t namelen, maillen;
41dd00ba 513 int max_length = 78; /* per rfc2822 */
93fc05eb 514
6bf13944 515 if (pp->fmt == CMIT_FMT_ONELINE)
93fc05eb 516 return;
3c020bd5 517
30e77bcb
RS
518 line_end = strchrnul(line, '\n');
519 if (split_ident_line(&ident, line, line_end - line))
93fc05eb 520 return;
3c020bd5 521
dffd325f
AP
522 mailbuf = ident.mail_begin;
523 maillen = ident.mail_end - ident.mail_begin;
524 namebuf = ident.name_begin;
525 namelen = ident.name_end - ident.name_begin;
526
527 if (pp->mailmap)
528 map_user(pp->mailmap, &mailbuf, &maillen, &namebuf, &namelen);
529
9f23e040 530 if (cmit_fmt_is_mail(pp->fmt)) {
b84d0139 531 if (pp->from_ident && use_in_body_from(pp, &ident)) {
a9080475
JK
532 struct strbuf buf = STRBUF_INIT;
533
534 strbuf_addstr(&buf, "From: ");
535 strbuf_add(&buf, namebuf, namelen);
536 strbuf_addstr(&buf, " <");
537 strbuf_add(&buf, mailbuf, maillen);
538 strbuf_addstr(&buf, ">\n");
539 string_list_append(&pp->in_body_headers,
540 strbuf_detach(&buf, NULL));
541
542 mailbuf = pp->from_ident->mail_begin;
543 maillen = pp->from_ident->mail_end - mailbuf;
544 namebuf = pp->from_ident->name_begin;
545 namelen = pp->from_ident->name_end - namebuf;
546 }
547
93fc05eb 548 strbuf_addstr(sb, "From: ");
19d097e3
EB
549 if (pp->encode_email_headers &&
550 needs_rfc2047_encoding(namebuf, namelen)) {
a0511b39 551 add_rfc2047(sb, namebuf, namelen,
dffd325f 552 encoding, RFC2047_ADDRESS);
41dd00ba 553 max_length = 76; /* per rfc2047 */
a0511b39 554 } else if (needs_rfc822_quoting(namebuf, namelen)) {
4d03c18a 555 struct strbuf quoted = STRBUF_INIT;
a0511b39 556 add_rfc822_quoted(&quoted, namebuf, namelen);
41dd00ba
JS
557 strbuf_add_wrapped_bytes(sb, quoted.buf, quoted.len,
558 -6, 1, max_length);
4d03c18a 559 strbuf_release(&quoted);
41dd00ba 560 } else {
a0511b39 561 strbuf_add_wrapped_bytes(sb, namebuf, namelen,
dffd325f 562 -6, 1, max_length);
4d03c18a 563 }
dffd325f 564
97a17e77
RS
565 if (max_length <
566 last_line_length(sb) + strlen(" <") + maillen + strlen(">"))
567 strbuf_addch(sb, '\n');
a0511b39 568 strbuf_addf(sb, " <%.*s>\n", (int)maillen, mailbuf);
93fc05eb 569 } else {
6a5c3379
HM
570 struct strbuf id = STRBUF_INIT;
571 enum grep_header_field field = GREP_HEADER_FIELD_MAX;
572 struct grep_opt *opt = pp->rev ? &pp->rev->grep_filter : NULL;
573
574 if (!strcmp(what, "Author"))
575 field = GREP_HEADER_AUTHOR;
576 else if (!strcmp(what, "Commit"))
577 field = GREP_HEADER_COMMITTER;
578
579 strbuf_addf(sb, "%s: ", what);
580 if (pp->fmt == CMIT_FMT_FULLER)
581 strbuf_addchars(sb, ' ', 4);
582
583 strbuf_addf(&id, "%.*s <%.*s>", (int)namelen, namebuf,
584 (int)maillen, mailbuf);
585
586 append_line_with_color(sb, opt, id.buf, id.len, pp->color,
587 GREP_CONTEXT_HEAD, field);
588 strbuf_addch(sb, '\n');
589 strbuf_release(&id);
93fc05eb 590 }
dffd325f 591
6bf13944 592 switch (pp->fmt) {
93fc05eb 593 case CMIT_FMT_MEDIUM:
9dbe7c3d 594 strbuf_addf(sb, "Date: %s\n",
9720d23e 595 show_ident_date(&ident, pp->date_mode));
93fc05eb
JS
596 break;
597 case CMIT_FMT_EMAIL:
9f23e040 598 case CMIT_FMT_MBOXRD:
9dbe7c3d 599 strbuf_addf(sb, "Date: %s\n",
a5481a6c 600 show_ident_date(&ident, DATE_MODE(RFC2822)));
93fc05eb
JS
601 break;
602 case CMIT_FMT_FULLER:
9dbe7c3d 603 strbuf_addf(sb, "%sDate: %s\n", what,
9720d23e 604 show_ident_date(&ident, pp->date_mode));
93fc05eb
JS
605 break;
606 default:
607 /* notin' */
608 break;
609 }
610}
611
77356122 612static int is_blank_line(const char *line, int *len_p)
93fc05eb
JS
613{
614 int len = *len_p;
35b2fa5b 615 while (len && isspace(line[len - 1]))
93fc05eb
JS
616 len--;
617 *len_p = len;
618 return !len;
619}
620
77356122 621const char *skip_blank_lines(const char *msg)
a0109668
RS
622{
623 for (;;) {
624 int linelen = get_one_line(msg);
625 int ll = linelen;
626 if (!linelen)
627 break;
77356122 628 if (!is_blank_line(msg, &ll))
a0109668
RS
629 break;
630 msg += linelen;
631 }
632 return msg;
633}
634
6bf13944
JK
635static void add_merge_info(const struct pretty_print_context *pp,
636 struct strbuf *sb, const struct commit *commit)
93fc05eb
JS
637{
638 struct commit_list *parent = commit->parents;
639
9f23e040 640 if ((pp->fmt == CMIT_FMT_ONELINE) || (cmit_fmt_is_mail(pp->fmt)) ||
93fc05eb
JS
641 !parent || !parent->next)
642 return;
643
644 strbuf_addstr(sb, "Merge:");
645
646 while (parent) {
a94bb683
RS
647 struct object_id *oidp = &parent->item->object.oid;
648 strbuf_addch(sb, ' ');
6bf13944 649 if (pp->abbrev)
30e677e0 650 strbuf_add_unique_abbrev(sb, oidp, pp->abbrev);
a94bb683
RS
651 else
652 strbuf_addstr(sb, oid_to_hex(oidp));
93fc05eb 653 parent = parent->next;
93fc05eb
JS
654 }
655 strbuf_addch(sb, '\n');
656}
657
fe6eb7f2 658static char *get_header(const char *msg, const char *key)
93fc05eb 659{
fe6eb7f2
JK
660 size_t len;
661 const char *v = find_commit_header(msg, key, &len);
662 return v ? xmemdupz(v, len) : NULL;
93fc05eb
JS
663}
664
665static char *replace_encoding_header(char *buf, const char *encoding)
666{
f285a2d7 667 struct strbuf tmp = STRBUF_INIT;
93fc05eb
JS
668 size_t start, len;
669 char *cp = buf;
670
671 /* guess if there is an encoding header before a \n\n */
68d6d6eb 672 while (!starts_with(cp, "encoding ")) {
93fc05eb
JS
673 cp = strchr(cp, '\n');
674 if (!cp || *++cp == '\n')
675 return buf;
676 }
677 start = cp - buf;
678 cp = strchr(cp, '\n');
679 if (!cp)
680 return buf; /* should not happen but be defensive */
681 len = cp + 1 - (buf + start);
682
93fc05eb
JS
683 strbuf_attach(&tmp, buf, strlen(buf), strlen(buf) + 1);
684 if (is_encoding_utf8(encoding)) {
685 /* we have re-coded to UTF-8; drop the header */
686 strbuf_remove(&tmp, start, len);
687 } else {
688 /* just replaces XXXX in 'encoding XXXX\n' */
689 strbuf_splice(&tmp, start + strlen("encoding "),
690 len - strlen("encoding \n"),
691 encoding, strlen(encoding));
692 }
693 return strbuf_detach(&tmp, NULL);
694}
695
424510ed
SB
696const char *repo_logmsg_reencode(struct repository *r,
697 const struct commit *commit,
698 char **commit_encoding,
699 const char *output_encoding)
93fc05eb 700{
330db18c 701 static const char *utf8 = "UTF-8";
93fc05eb
JS
702 const char *use_encoding;
703 char *encoding;
424510ed 704 const char *msg = repo_get_commit_buffer(r, commit, NULL);
93fc05eb
JS
705 char *out;
706
5a10d236
NTND
707 if (!output_encoding || !*output_encoding) {
708 if (commit_encoding)
fe6eb7f2 709 *commit_encoding = get_header(msg, "encoding");
dd0d388c 710 return msg;
5a10d236 711 }
fe6eb7f2 712 encoding = get_header(msg, "encoding");
5a10d236
NTND
713 if (commit_encoding)
714 *commit_encoding = encoding;
93fc05eb 715 use_encoding = encoding ? encoding : utf8;
be5c9fb9
JK
716 if (same_encoding(use_encoding, output_encoding)) {
717 /*
718 * No encoding work to be done. If we have no encoding header
719 * at all, then there's nothing to do, and we can return the
720 * message verbatim (whether newly allocated or not).
721 */
722 if (!encoding)
723 return msg;
724
725 /*
726 * Otherwise, we still want to munge the encoding header in the
727 * result, which will be done by modifying the buffer. If we
728 * are using a fresh copy, we can reuse it. But if we are using
c7c33f50 729 * the cached copy from repo_get_commit_buffer, we need to duplicate it
b66103c3 730 * to avoid munging the cached copy.
be5c9fb9 731 */
424510ed 732 if (msg == get_cached_commit_buffer(r, commit, NULL))
b66103c3
JK
733 out = xstrdup(msg);
734 else
735 out = (char *)msg;
be5c9fb9
JK
736 }
737 else {
738 /*
739 * There's actual encoding work to do. Do the reencoding, which
740 * still leaves the header to be replaced in the next step. At
741 * this point, we are done with msg. If we allocated a fresh
742 * copy, we can free it.
743 */
744 out = reencode_string(msg, output_encoding, use_encoding);
b66103c3 745 if (out)
424510ed 746 repo_unuse_commit_buffer(r, commit, msg);
be5c9fb9
JK
747 }
748
749 /*
750 * This replacement actually consumes the buffer we hand it, so we do
751 * not have to worry about freeing the old "out" here.
752 */
93fc05eb
JS
753 if (out)
754 out = replace_encoding_header(out, output_encoding);
755
5a10d236
NTND
756 if (!commit_encoding)
757 free(encoding);
dd0d388c
JK
758 /*
759 * If the re-encoding failed, out might be NULL here; in that
760 * case we just return the commit message verbatim.
761 */
0988e665 762 return out ? out : msg;
dd0d388c
JK
763}
764
ea02ffa3
AP
765static int mailmap_name(const char **email, size_t *email_len,
766 const char **name, size_t *name_len)
e0cbc397 767{
c455c87c 768 static struct string_list *mail_map;
e0cbc397 769 if (!mail_map) {
ca56dadb 770 CALLOC_ARRAY(mail_map, 1);
4e168333 771 read_mailmap(mail_map);
e0cbc397 772 }
d20d654f 773 return mail_map->nr && map_user(mail_map, email, email_len, name, name_len);
e0cbc397
JS
774}
775
c3a670de 776static size_t format_person_part(struct strbuf *sb, char part,
a5481a6c 777 const char *msg, int len,
9720d23e 778 struct date_mode dmode)
93fc05eb 779{
c3a670de
MC
780 /* currently all placeholders have same length */
781 const int placeholder_len = 2;
4b340cfa 782 struct ident_split s;
ea02ffa3
AP
783 const char *name, *mail;
784 size_t maillen, namelen;
93fc05eb 785
4b340cfa 786 if (split_ident_line(&s, msg, len) < 0)
c3a670de
MC
787 goto skip;
788
ea02ffa3
AP
789 name = s.name_begin;
790 namelen = s.name_end - s.name_begin;
791 mail = s.mail_begin;
792 maillen = s.mail_end - s.mail_begin;
793
d8b8217c 794 if (part == 'N' || part == 'E' || part == 'L') /* mailmap lookup */
ea02ffa3 795 mailmap_name(&mail, &maillen, &name, &namelen);
e0cbc397 796 if (part == 'n' || part == 'N') { /* name */
ea02ffa3 797 strbuf_add(sb, name, namelen);
c3a670de 798 return placeholder_len;
cde75e59 799 }
d20d654f 800 if (part == 'e' || part == 'E') { /* email */
ea02ffa3 801 strbuf_add(sb, mail, maillen);
c3a670de 802 return placeholder_len;
cde75e59 803 }
d8b8217c
PB
804 if (part == 'l' || part == 'L') { /* local-part */
805 const char *at = memchr(mail, '@', maillen);
806 if (at)
807 maillen = at - mail;
808 strbuf_add(sb, mail, maillen);
809 return placeholder_len;
810 }
93fc05eb 811
4b340cfa 812 if (!s.date_begin)
c3a670de 813 goto skip;
93fc05eb 814
cde75e59 815 if (part == 't') { /* date, UNIX timestamp */
4b340cfa 816 strbuf_add(sb, s.date_begin, s.date_end - s.date_begin);
c3a670de 817 return placeholder_len;
cde75e59 818 }
93fc05eb 819
cde75e59
RS
820 switch (part) {
821 case 'd': /* date */
9dbe7c3d 822 strbuf_addstr(sb, show_ident_date(&s, dmode));
c3a670de 823 return placeholder_len;
cde75e59 824 case 'D': /* date, RFC2822 style */
a5481a6c 825 strbuf_addstr(sb, show_ident_date(&s, DATE_MODE(RFC2822)));
c3a670de 826 return placeholder_len;
cde75e59 827 case 'r': /* date, relative */
a5481a6c 828 strbuf_addstr(sb, show_ident_date(&s, DATE_MODE(RELATIVE)));
c3a670de 829 return placeholder_len;
466fb674 830 case 'i': /* date, ISO 8601-like */
a5481a6c 831 strbuf_addstr(sb, show_ident_date(&s, DATE_MODE(ISO8601)));
c3a670de 832 return placeholder_len;
466fb674 833 case 'I': /* date, ISO 8601 strict */
a5481a6c 834 strbuf_addstr(sb, show_ident_date(&s, DATE_MODE(ISO8601_STRICT)));
466fb674 835 return placeholder_len;
b722d456
ZH
836 case 'h': /* date, human */
837 strbuf_addstr(sb, show_ident_date(&s, DATE_MODE(HUMAN)));
838 return placeholder_len;
0df62117
RS
839 case 's':
840 strbuf_addstr(sb, show_ident_date(&s, DATE_MODE(SHORT)));
841 return placeholder_len;
cde75e59 842 }
c3a670de
MC
843
844skip:
845 /*
4b340cfa
JH
846 * reading from either a bogus commit, or a reflog entry with
847 * %gn, %ge, etc.; 'sb' cannot be updated, but we still need
848 * to compute a valid return value.
c3a670de
MC
849 */
850 if (part == 'n' || part == 'e' || part == 't' || part == 'd'
851 || part == 'D' || part == 'r' || part == 'i')
852 return placeholder_len;
853
854 return 0; /* unknown placeholder */
93fc05eb
JS
855}
856
f29d5958
RS
857struct chunk {
858 size_t off;
859 size_t len;
860};
861
a5752342
NTND
862enum flush_type {
863 no_flush,
864 flush_right,
865 flush_left,
1640632b 866 flush_left_and_steal,
a5752342
NTND
867 flush_both
868};
869
a7f01c6b
NTND
870enum trunc_type {
871 trunc_none,
872 trunc_left,
873 trunc_middle,
874 trunc_right
875};
876
f29d5958 877struct format_commit_context {
018b9deb 878 struct repository *repository;
f29d5958 879 const struct commit *commit;
dd2e794a 880 const struct pretty_print_context *pretty_ctx;
f53bd743
RS
881 unsigned commit_header_parsed:1;
882 unsigned commit_message_parsed:1;
ffb6d7d5 883 struct signature_check signature_check;
a5752342 884 enum flush_type flush_type;
a7f01c6b 885 enum trunc_type truncate;
b000c59b 886 const char *message;
0940a76d 887 char *commit_encoding;
02edd56b 888 size_t width, indent1, indent2;
a95f067e 889 int auto_color;
a5752342 890 int padding;
f29d5958
RS
891
892 /* These offsets are relative to the start of the commit message. */
f29d5958
RS
893 struct chunk author;
894 struct chunk committer;
f53bd743
RS
895 size_t message_off;
896 size_t subject_off;
f29d5958 897 size_t body_off;
b9c62321
RS
898
899 /* The following ones are relative to the result struct strbuf. */
02edd56b 900 size_t wrap_start;
f29d5958
RS
901};
902
903static void parse_commit_header(struct format_commit_context *context)
93fc05eb 904{
177b29dc 905 const char *msg = context->message;
93fc05eb 906 int i;
f29d5958 907
f53bd743 908 for (i = 0; msg[i]; i++) {
e3f1da98 909 const char *name;
f29d5958
RS
910 int eol;
911 for (eol = i; msg[eol] && msg[eol] != '\n'; eol++)
912 ; /* do nothing */
913
f29d5958 914 if (i == eol) {
f53bd743 915 break;
e3f1da98
RS
916 } else if (skip_prefix(msg + i, "author ", &name)) {
917 context->author.off = name - msg;
918 context->author.len = msg + eol - name;
919 } else if (skip_prefix(msg + i, "committer ", &name)) {
920 context->committer.off = name - msg;
921 context->committer.len = msg + eol - name;
f29d5958
RS
922 }
923 i = eol;
924 }
f53bd743 925 context->message_off = i;
f29d5958
RS
926 context->commit_header_parsed = 1;
927}
928
46d164b0
SB
929static int istitlechar(char c)
930{
931 return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
932 (c >= '0' && c <= '9') || c == '.' || c == '_';
933}
934
47d4676a 935void format_sanitized_subject(struct strbuf *sb, const char *msg, size_t len)
46d164b0
SB
936{
937 size_t trimlen;
871d21d4 938 size_t start_len = sb->len;
46d164b0 939 int space = 2;
47d4676a 940 int i;
46d164b0 941
47d4676a
HV
942 for (i = 0; i < len; i++) {
943 if (istitlechar(msg[i])) {
46d164b0
SB
944 if (space == 1)
945 strbuf_addch(sb, '-');
946 space = 0;
47d4676a
HV
947 strbuf_addch(sb, msg[i]);
948 if (msg[i] == '.')
949 while (msg[i+1] == '.')
950 i++;
46d164b0
SB
951 } else
952 space |= 1;
953 }
954
955 /* trim any trailing '.' or '-' characters */
956 trimlen = 0;
871d21d4
SB
957 while (sb->len - trimlen > start_len &&
958 (sb->buf[sb->len - 1 - trimlen] == '.'
959 || sb->buf[sb->len - 1 - trimlen] == '-'))
46d164b0
SB
960 trimlen++;
961 strbuf_remove(sb, sb->len - trimlen, trimlen);
962}
963
cec08717
RS
964const char *format_subject(struct strbuf *sb, const char *msg,
965 const char *line_separator)
88c44735
RS
966{
967 int first = 1;
968
969 for (;;) {
970 const char *line = msg;
971 int linelen = get_one_line(line);
972
973 msg += linelen;
77356122 974 if (!linelen || is_blank_line(line, &linelen))
88c44735
RS
975 break;
976
f53bd743
RS
977 if (!sb)
978 continue;
88c44735
RS
979 strbuf_grow(sb, linelen + 2);
980 if (!first)
981 strbuf_addstr(sb, line_separator);
982 strbuf_add(sb, line, linelen);
983 first = 0;
984 }
985 return msg;
986}
987
f53bd743
RS
988static void parse_commit_message(struct format_commit_context *c)
989{
177b29dc
PN
990 const char *msg = c->message + c->message_off;
991 const char *start = c->message;
f53bd743 992
77356122 993 msg = skip_blank_lines(msg);
f53bd743
RS
994 c->subject_off = msg - start;
995
996 msg = format_subject(NULL, msg, NULL);
77356122 997 msg = skip_blank_lines(msg);
f53bd743
RS
998 c->body_off = msg - start;
999
1000 c->commit_message_parsed = 1;
1001}
1002
02edd56b
RS
1003static void strbuf_wrap(struct strbuf *sb, size_t pos,
1004 size_t width, size_t indent1, size_t indent2)
1005{
1006 struct strbuf tmp = STRBUF_INIT;
1007
1008 if (pos)
1009 strbuf_add(&tmp, sb->buf, pos);
1010 strbuf_add_wrapped_text(&tmp, sb->buf + pos,
48050c42
PS
1011 cast_size_t_to_int(indent1),
1012 cast_size_t_to_int(indent2),
1013 cast_size_t_to_int(width));
02edd56b
RS
1014 strbuf_swap(&tmp, sb);
1015 strbuf_release(&tmp);
1016}
1017
1018static void rewrap_message_tail(struct strbuf *sb,
1019 struct format_commit_context *c,
1020 size_t new_width, size_t new_indent1,
1021 size_t new_indent2)
1022{
1023 if (c->width == new_width && c->indent1 == new_indent1 &&
1024 c->indent2 == new_indent2)
1025 return;
32ca4249 1026 if (c->wrap_start < sb->len)
02edd56b
RS
1027 strbuf_wrap(sb, c->wrap_start, c->width, c->indent1, c->indent2);
1028 c->wrap_start = sb->len;
1029 c->width = new_width;
1030 c->indent1 = new_indent1;
1031 c->indent2 = new_indent2;
1032}
1033
cd1957f5
JK
1034static int format_reflog_person(struct strbuf *sb,
1035 char part,
1036 struct reflog_walk_info *log,
9720d23e 1037 struct date_mode dmode)
cd1957f5
JK
1038{
1039 const char *ident;
1040
1041 if (!log)
1042 return 2;
1043
1044 ident = get_reflog_ident(log);
1045 if (!ident)
1046 return 2;
1047
1048 return format_person_part(sb, part, ident, strlen(ident), dmode);
1049}
1050
fcabc2d9
NTND
1051static size_t parse_color(struct strbuf *sb, /* in UTF-8 */
1052 const char *placeholder,
1053 struct format_commit_context *c)
1054{
e3f1da98 1055 const char *rest = placeholder;
18fb7ffc 1056 const char *basic_color = NULL;
e3f1da98 1057
fcabc2d9
NTND
1058 if (placeholder[1] == '(') {
1059 const char *begin = placeholder + 2;
1060 const char *end = strchr(begin, ')');
1061 char color[COLOR_MAXLEN];
1062
1063 if (!end)
1064 return 0;
18fb7ffc 1065
e3f1da98 1066 if (skip_prefix(begin, "auto,", &begin)) {
fcabc2d9
NTND
1067 if (!want_color(c->pretty_ctx->color))
1068 return end - placeholder + 1;
18fb7ffc
JK
1069 } else if (skip_prefix(begin, "always,", &begin)) {
1070 /* nothing to do; we do not respect want_color at all */
1071 } else {
1072 /* the default is the same as "auto" */
1073 if (!want_color(c->pretty_ctx->color))
1074 return end - placeholder + 1;
fcabc2d9 1075 }
18fb7ffc 1076
f6c5a296
JK
1077 if (color_parse_mem(begin, end - begin, color) < 0)
1078 die(_("unable to parse --pretty format"));
fcabc2d9
NTND
1079 strbuf_addstr(sb, color);
1080 return end - placeholder + 1;
1081 }
18fb7ffc
JK
1082
1083 /*
1084 * We handle things like "%C(red)" above; for historical reasons, there
1085 * are a few colors that can be specified without parentheses (and
1086 * they cannot support things like "auto" or "always" at all).
1087 */
e3f1da98 1088 if (skip_prefix(placeholder + 1, "red", &rest))
18fb7ffc 1089 basic_color = GIT_COLOR_RED;
e3f1da98 1090 else if (skip_prefix(placeholder + 1, "green", &rest))
18fb7ffc 1091 basic_color = GIT_COLOR_GREEN;
e3f1da98 1092 else if (skip_prefix(placeholder + 1, "blue", &rest))
18fb7ffc 1093 basic_color = GIT_COLOR_BLUE;
e3f1da98 1094 else if (skip_prefix(placeholder + 1, "reset", &rest))
18fb7ffc
JK
1095 basic_color = GIT_COLOR_RESET;
1096
1097 if (basic_color && want_color(c->pretty_ctx->color))
1098 strbuf_addstr(sb, basic_color);
1099
e3f1da98 1100 return rest - placeholder;
fcabc2d9
NTND
1101}
1102
9a1180fc 1103static size_t parse_padding_placeholder(const char *placeholder,
a5752342
NTND
1104 struct format_commit_context *c)
1105{
1106 const char *ch = placeholder;
1107 enum flush_type flush_type;
1108 int to_column = 0;
1109
1110 switch (*ch++) {
1111 case '<':
1112 flush_type = flush_right;
1113 break;
1114 case '>':
1115 if (*ch == '<') {
1116 flush_type = flush_both;
1117 ch++;
1640632b
NTND
1118 } else if (*ch == '>') {
1119 flush_type = flush_left_and_steal;
1120 ch++;
a5752342
NTND
1121 } else
1122 flush_type = flush_left;
1123 break;
1124 default:
1125 return 0;
1126 }
1127
1128 /* the next value means "wide enough to that column" */
1129 if (*ch == '|') {
1130 to_column = 1;
1131 ch++;
1132 }
1133
1134 if (*ch == '(') {
1135 const char *start = ch + 1;
a7f01c6b 1136 const char *end = start + strcspn(start, ",)");
a5752342
NTND
1137 char *next;
1138 int width;
f6e0b9f3 1139 if (!*end || end == start)
a5752342 1140 return 0;
066790d7 1141 width = strtol(start, &next, 10);
304a50ad
PS
1142
1143 /*
1144 * We need to limit the amount of padding, or otherwise this
1145 * would allow the user to pad the buffer by arbitrarily many
1146 * bytes and thus cause resource exhaustion.
1147 */
1148 if (width < -FORMATTING_LIMIT || width > FORMATTING_LIMIT)
1149 return 0;
1150
a5752342
NTND
1151 if (next == start || width == 0)
1152 return 0;
066790d7
NTND
1153 if (width < 0) {
1154 if (to_column)
1155 width += term_columns();
1156 if (width < 0)
1157 return 0;
1158 }
a5752342
NTND
1159 c->padding = to_column ? -width : width;
1160 c->flush_type = flush_type;
a7f01c6b
NTND
1161
1162 if (*end == ',') {
1163 start = end + 1;
1164 end = strchr(start, ')');
1165 if (!end || end == start)
1166 return 0;
59556548 1167 if (starts_with(start, "trunc)"))
a7f01c6b 1168 c->truncate = trunc_right;
59556548 1169 else if (starts_with(start, "ltrunc)"))
a7f01c6b 1170 c->truncate = trunc_left;
59556548 1171 else if (starts_with(start, "mtrunc)"))
a7f01c6b
NTND
1172 c->truncate = trunc_middle;
1173 else
1174 return 0;
1175 } else
1176 c->truncate = trunc_none;
1177
a5752342
NTND
1178 return end - placeholder + 1;
1179 }
1180 return 0;
1181}
1182
4f732e0f
AW
1183static int match_placeholder_arg_value(const char *to_parse, const char *candidate,
1184 const char **end, const char **valuestart,
1185 size_t *valuelen)
84ff053d
TB
1186{
1187 const char *p;
1188
1189 if (!(skip_prefix(to_parse, candidate, &p)))
1190 return 0;
4f732e0f
AW
1191 if (valuestart) {
1192 if (*p == '=') {
1193 *valuestart = p + 1;
1194 *valuelen = strcspn(*valuestart, ",)");
1195 p = *valuestart + *valuelen;
1196 } else {
1197 if (*p != ',' && *p != ')')
1198 return 0;
1199 *valuestart = NULL;
1200 *valuelen = 0;
1201 }
1202 }
84ff053d
TB
1203 if (*p == ',') {
1204 *end = p + 1;
1205 return 1;
1206 }
1207 if (*p == ')') {
1208 *end = p;
1209 return 1;
1210 }
1211 return 0;
1212}
1213
4f732e0f
AW
1214static int match_placeholder_bool_arg(const char *to_parse, const char *candidate,
1215 const char **end, int *val)
1216{
1217 const char *argval;
1218 char *strval;
1219 size_t arglen;
1220 int v;
1221
1222 if (!match_placeholder_arg_value(to_parse, candidate, end, &argval, &arglen))
1223 return 0;
1224
1225 if (!argval) {
1226 *val = 1;
1227 return 1;
1228 }
1229
1230 strval = xstrndup(argval, arglen);
1231 v = git_parse_maybe_bool(strval);
1232 free(strval);
1233
1234 if (v == -1)
1235 return 0;
1236
1237 *val = v;
1238
1239 return 1;
1240}
1241
250bea0c
AW
1242static int format_trailer_match_cb(const struct strbuf *key, void *ud)
1243{
1244 const struct string_list *list = ud;
1245 const struct string_list_item *item;
1246
1247 for_each_string_list_item (item, list) {
1248 if (key->len == (uintptr_t)item->util &&
1249 !strncasecmp(item->string, key->buf, key->len))
1250 return 1;
1251 }
1252 return 0;
1253}
1254
a58dd835
AK
1255static struct strbuf *expand_string_arg(struct strbuf *sb,
1256 const char *argval, size_t arglen)
3c3d0c42
RS
1257{
1258 char *fmt = xstrndup(argval, arglen);
6f1e2d52 1259 const char *format = fmt;
3c3d0c42
RS
1260
1261 strbuf_reset(sb);
6f1e2d52
RS
1262 while (strbuf_expand_step(sb, &format)) {
1263 size_t len;
1264
1265 if (skip_prefix(format, "%", &format))
1266 strbuf_addch(sb, '%');
4416b86c 1267 else if ((len = strbuf_expand_literal(sb, format)))
6f1e2d52
RS
1268 format += len;
1269 else
1270 strbuf_addch(sb, '%');
1271 }
3c3d0c42
RS
1272 free(fmt);
1273 return sb;
1274}
1275
90563aed
HV
1276int format_set_trailers_options(struct process_trailer_options *opts,
1277 struct string_list *filter_list,
1278 struct strbuf *sepbuf,
1279 struct strbuf *kvsepbuf,
636a0aee
HV
1280 const char **arg,
1281 char **invalid_arg)
90563aed
HV
1282{
1283 for (;;) {
1284 const char *argval;
1285 size_t arglen;
1286
636a0aee
HV
1287 if (**arg == ')')
1288 break;
1289
90563aed
HV
1290 if (match_placeholder_arg_value(*arg, "key", arg, &argval, &arglen)) {
1291 uintptr_t len = arglen;
1292
1293 if (!argval)
1294 return -1;
1295
1296 if (len && argval[len - 1] == ':')
1297 len--;
1298 string_list_append(filter_list, argval)->util = (char *)len;
1299
1300 opts->filter = format_trailer_match_cb;
1301 opts->filter_data = filter_list;
1302 opts->only_trailers = 1;
1303 } else if (match_placeholder_arg_value(*arg, "separator", arg, &argval, &arglen)) {
a58dd835 1304 opts->separator = expand_string_arg(sepbuf, argval, arglen);
90563aed 1305 } else if (match_placeholder_arg_value(*arg, "key_value_separator", arg, &argval, &arglen)) {
a58dd835 1306 opts->key_value_separator = expand_string_arg(kvsepbuf, argval, arglen);
90563aed
HV
1307 } else if (!match_placeholder_bool_arg(*arg, "only", arg, &opts->only_trailers) &&
1308 !match_placeholder_bool_arg(*arg, "unfold", arg, &opts->unfold) &&
1309 !match_placeholder_bool_arg(*arg, "keyonly", arg, &opts->key_only) &&
636a0aee
HV
1310 !match_placeholder_bool_arg(*arg, "valueonly", arg, &opts->value_only)) {
1311 if (invalid_arg) {
1312 size_t len = strcspn(*arg, ",)");
1313 *invalid_arg = xstrndup(*arg, len);
1314 }
1315 return -1;
1316 }
90563aed
HV
1317 }
1318 return 0;
1319}
1320
b081547e
RS
1321static size_t parse_describe_args(const char *start, struct strvec *args)
1322{
3c6eb4ec
ES
1323 struct {
1324 char *name;
1325 enum {
1d517cea 1326 DESCRIBE_ARG_BOOL,
eccd97d0 1327 DESCRIBE_ARG_INTEGER,
3c6eb4ec
ES
1328 DESCRIBE_ARG_STRING,
1329 } type;
1330 } option[] = {
1d517cea 1331 { "tags", DESCRIBE_ARG_BOOL},
eccd97d0 1332 { "abbrev", DESCRIBE_ARG_INTEGER },
3c6eb4ec
ES
1333 { "exclude", DESCRIBE_ARG_STRING },
1334 { "match", DESCRIBE_ARG_STRING },
1335 };
b081547e
RS
1336 const char *arg = start;
1337
1338 for (;;) {
3c6eb4ec 1339 int found = 0;
b081547e
RS
1340 const char *argval;
1341 size_t arglen = 0;
1d517cea 1342 int optval = 0;
b081547e
RS
1343 int i;
1344
3c6eb4ec
ES
1345 for (i = 0; !found && i < ARRAY_SIZE(option); i++) {
1346 switch (option[i].type) {
1d517cea
ES
1347 case DESCRIBE_ARG_BOOL:
1348 if (match_placeholder_bool_arg(arg, option[i].name, &arg, &optval)) {
1349 if (optval)
1350 strvec_pushf(args, "--%s", option[i].name);
1351 else
1352 strvec_pushf(args, "--no-%s", option[i].name);
1353 found = 1;
1354 }
1355 break;
eccd97d0
ES
1356 case DESCRIBE_ARG_INTEGER:
1357 if (match_placeholder_arg_value(arg, option[i].name, &arg,
1358 &argval, &arglen)) {
1359 char *endptr;
1360 if (!arglen)
1361 return 0;
1362 strtol(argval, &endptr, 10);
1363 if (endptr - argval != arglen)
1364 return 0;
1365 strvec_pushf(args, "--%s=%.*s", option[i].name, (int)arglen, argval);
1366 found = 1;
1367 }
1368 break;
3c6eb4ec
ES
1369 case DESCRIBE_ARG_STRING:
1370 if (match_placeholder_arg_value(arg, option[i].name, &arg,
1371 &argval, &arglen)) {
1372 if (!arglen)
1373 return 0;
1374 strvec_pushf(args, "--%s=%.*s", option[i].name, (int)arglen, argval);
1375 found = 1;
1376 }
b081547e
RS
1377 break;
1378 }
1379 }
3c6eb4ec 1380 if (!found)
b081547e
RS
1381 break;
1382
b081547e
RS
1383 }
1384 return arg - start;
1385}
1386
a58dd835
AK
1387
1388static int parse_decoration_option(const char **arg,
1389 const char *name,
1390 char **opt)
1391{
1392 const char *argval;
1393 size_t arglen;
1394
1395 if (match_placeholder_arg_value(*arg, name, arg, &argval, &arglen)) {
1396 struct strbuf sb = STRBUF_INIT;
1397
1398 expand_string_arg(&sb, argval, arglen);
1399 *opt = strbuf_detach(&sb, NULL);
1400 return 1;
1401 }
1402 return 0;
1403}
1404
1405static void parse_decoration_options(const char **arg,
1406 struct decoration_options *opts)
1407{
1408 while (parse_decoration_option(arg, "prefix", &opts->prefix) ||
1409 parse_decoration_option(arg, "suffix", &opts->suffix) ||
f1f8a258
AK
1410 parse_decoration_option(arg, "separator", &opts->separator) ||
1411 parse_decoration_option(arg, "pointer", &opts->pointer) ||
1412 parse_decoration_option(arg, "tag", &opts->tag))
a58dd835
AK
1413 ;
1414}
1415
1416static void free_decoration_options(const struct decoration_options *opts)
1417{
1418 free(opts->prefix);
1419 free(opts->suffix);
1420 free(opts->separator);
f1f8a258
AK
1421 free(opts->pointer);
1422 free(opts->tag);
a58dd835
AK
1423}
1424
7e77df39
NTND
1425static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
1426 const char *placeholder,
9fa708da 1427 void *context)
f29d5958
RS
1428{
1429 struct format_commit_context *c = context;
1430 const struct commit *commit = c->commit;
177b29dc 1431 const char *msg = c->message;
f29d5958 1432 struct commit_list *p;
47d4676a 1433 const char *arg, *eol;
fd2015b3 1434 size_t res;
ad6f028f 1435 char **slot;
93fc05eb 1436
93fc05eb 1437 /* these are independent of the commit */
4416b86c 1438 res = strbuf_expand_literal(sb, placeholder);
fd2015b3
AW
1439 if (res)
1440 return res;
1441
cde75e59
RS
1442 switch (placeholder[0]) {
1443 case 'C':
59556548 1444 if (starts_with(placeholder + 1, "(auto)")) {
b15a3e00 1445 c->auto_color = want_color(c->pretty_ctx->color);
82b83da8 1446 if (c->auto_color && sb->len)
c99ad274 1447 strbuf_addstr(sb, GIT_COLOR_RESET);
a95f067e
NTND
1448 return 7; /* consumed 7 bytes, "C(auto)" */
1449 } else {
1450 int ret = parse_color(sb, placeholder, c);
1451 if (ret)
1452 c->auto_color = 0;
1453 /*
1454 * Otherwise, we decided to treat %C<unknown>
1455 * as a literal string, and the previous
1456 * %C(auto) is still valid.
1457 */
1458 return ret;
c002922a 1459 }
02edd56b
RS
1460 case 'w':
1461 if (placeholder[1] == '(') {
1462 unsigned long width = 0, indent1 = 0, indent2 = 0;
1463 char *next;
1464 const char *start = placeholder + 2;
1465 const char *end = strchr(start, ')');
1466 if (!end)
1467 return 0;
1468 if (end > start) {
1469 width = strtoul(start, &next, 10);
1470 if (*next == ',') {
1471 indent1 = strtoul(next + 1, &next, 10);
1472 if (*next == ',') {
1473 indent2 = strtoul(next + 1,
1474 &next, 10);
1475 }
1476 }
1477 if (*next != ')')
1478 return 0;
1479 }
304a50ad
PS
1480
1481 /*
1482 * We need to limit the format here as it allows the
1483 * user to prepend arbitrarily many bytes to the buffer
1484 * when rewrapping.
1485 */
1486 if (width > FORMATTING_LIMIT ||
1487 indent1 > FORMATTING_LIMIT ||
1488 indent2 > FORMATTING_LIMIT)
1489 return 0;
02edd56b
RS
1490 rewrap_message_tail(sb, c, width, indent1, indent2);
1491 return end - placeholder + 1;
1492 } else
1493 return 0;
a5752342
NTND
1494
1495 case '<':
1496 case '>':
9a1180fc 1497 return parse_padding_placeholder(placeholder, c);
cde75e59 1498 }
93fc05eb 1499
b081547e 1500 if (skip_prefix(placeholder, "(describe", &arg)) {
15ae82d5
RS
1501 struct child_process cmd = CHILD_PROCESS_INIT;
1502 struct strbuf out = STRBUF_INIT;
1503 struct strbuf err = STRBUF_INIT;
96099726
RS
1504 struct pretty_print_describe_status *describe_status;
1505
1506 describe_status = c->pretty_ctx->describe_status;
1507 if (describe_status) {
1508 if (!describe_status->max_invocations)
1509 return 0;
1510 describe_status->max_invocations--;
1511 }
15ae82d5
RS
1512
1513 cmd.git_cmd = 1;
1514 strvec_push(&cmd.args, "describe");
b081547e
RS
1515
1516 if (*arg == ':') {
1517 arg++;
1518 arg += parse_describe_args(arg, &cmd.args);
1519 }
1520
1521 if (*arg != ')') {
1522 child_process_clear(&cmd);
1523 return 0;
1524 }
1525
15ae82d5
RS
1526 strvec_push(&cmd.args, oid_to_hex(&commit->object.oid));
1527 pipe_command(&cmd, NULL, 0, &out, 0, &err, 0);
1528 strbuf_rtrim(&out);
1529 strbuf_addbuf(sb, &out);
1530 strbuf_release(&out);
1531 strbuf_release(&err);
b081547e 1532 return arg - placeholder + 1;
15ae82d5
RS
1533 }
1534
93fc05eb
JS
1535 /* these depend on the commit */
1536 if (!commit->object.parsed)
109cd76d 1537 parse_object(the_repository, &commit->object.oid);
93fc05eb 1538
cde75e59
RS
1539 switch (placeholder[0]) {
1540 case 'H': /* commit hash */
a95f067e 1541 strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_COMMIT));
f2fd0760 1542 strbuf_addstr(sb, oid_to_hex(&commit->object.oid));
a95f067e 1543 strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET));
c3a670de 1544 return 1;
cde75e59 1545 case 'h': /* abbreviated commit hash */
a95f067e 1546 strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_COMMIT));
30e677e0 1547 strbuf_add_unique_abbrev(sb, &commit->object.oid,
1eb47f16 1548 c->pretty_ctx->abbrev);
a95f067e 1549 strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET));
c3a670de 1550 return 1;
cde75e59 1551 case 'T': /* tree hash */
2e27bd77 1552 strbuf_addstr(sb, oid_to_hex(get_commit_tree_oid(commit)));
c3a670de 1553 return 1;
cde75e59 1554 case 't': /* abbreviated tree hash */
2e27bd77 1555 strbuf_add_unique_abbrev(sb,
c89b6e13 1556 get_commit_tree_oid(commit),
1eb47f16 1557 c->pretty_ctx->abbrev);
c3a670de 1558 return 1;
cde75e59
RS
1559 case 'P': /* parent hashes */
1560 for (p = commit->parents; p; p = p->next) {
1561 if (p != commit->parents)
1562 strbuf_addch(sb, ' ');
f2fd0760 1563 strbuf_addstr(sb, oid_to_hex(&p->item->object.oid));
cde75e59 1564 }
c3a670de 1565 return 1;
cde75e59
RS
1566 case 'p': /* abbreviated parent hashes */
1567 for (p = commit->parents; p; p = p->next) {
1568 if (p != commit->parents)
1569 strbuf_addch(sb, ' ');
30e677e0 1570 strbuf_add_unique_abbrev(sb, &p->item->object.oid,
1eb47f16 1571 c->pretty_ctx->abbrev);
cde75e59 1572 }
c3a670de 1573 return 1;
cde75e59 1574 case 'm': /* left/right/bottom */
1df2d656 1575 strbuf_addstr(sb, get_revision_mark(NULL, commit));
c3a670de 1576 return 1;
3b3d443f 1577 case 'd':
a3883a65 1578 format_decorations(sb, commit, c->auto_color, NULL);
3b3d443f 1579 return 1;
9271095c 1580 case 'D':
a3883a65
AK
1581 {
1582 const struct decoration_options opts = {
1583 .prefix = "",
1584 .suffix = ""
1585 };
1586
1587 format_decorations(sb, commit, c->auto_color, &opts);
1588 return 1;
1589 }
ad6f028f
IT
1590 case 'S': /* tag/branch like --source */
1591 if (!(c->pretty_ctx->rev && c->pretty_ctx->rev->sources))
1592 return 0;
1593 slot = revision_sources_at(c->pretty_ctx->rev->sources, commit);
1594 if (!(slot && *slot))
1595 return 0;
1596 strbuf_addstr(sb, *slot);
1597 return 1;
8f8f5476
TR
1598 case 'g': /* reflog info */
1599 switch(placeholder[1]) {
1600 case 'd': /* reflog selector */
1601 case 'D':
1602 if (c->pretty_ctx->reflog_info)
1603 get_reflog_selector(sb,
1604 c->pretty_ctx->reflog_info,
9720d23e 1605 c->pretty_ctx->date_mode,
55ccf85a 1606 c->pretty_ctx->date_mode_explicit,
8f8f5476
TR
1607 (placeholder[1] == 'd'));
1608 return 2;
1609 case 's': /* reflog message */
1610 if (c->pretty_ctx->reflog_info)
1611 get_reflog_message(sb, c->pretty_ctx->reflog_info);
1612 return 2;
cd1957f5
JK
1613 case 'n':
1614 case 'N':
1615 case 'e':
1616 case 'E':
1617 return format_reflog_person(sb,
1618 placeholder[1],
1619 c->pretty_ctx->reflog_info,
9720d23e 1620 c->pretty_ctx->date_mode);
8f8f5476
TR
1621 }
1622 return 0; /* unknown %g placeholder */
8b208f02 1623 case 'N':
ddf333f6
JH
1624 if (c->pretty_ctx->notes_message) {
1625 strbuf_addstr(sb, c->pretty_ctx->notes_message);
5b163603
JG
1626 return 1;
1627 }
1628 return 0;
cde75e59
RS
1629 }
1630
f6667c5e 1631 if (placeholder[0] == 'G') {
ffb6d7d5
SG
1632 if (!c->signature_check.result)
1633 check_commit_signature(c->commit, &(c->signature_check));
f6667c5e
JH
1634 switch (placeholder[1]) {
1635 case 'G':
b5726a5d
FS
1636 if (c->signature_check.output)
1637 strbuf_addstr(sb, c->signature_check.output);
f6667c5e
JH
1638 break;
1639 case '?':
ffb6d7d5 1640 switch (c->signature_check.result) {
f6667c5e 1641 case 'G':
54887b46
HJI
1642 switch (c->signature_check.trust_level) {
1643 case TRUST_UNDEFINED:
1644 case TRUST_NEVER:
1645 strbuf_addch(sb, 'U');
1646 break;
1647 default:
1648 strbuf_addch(sb, 'G');
1649 break;
1650 }
1651 break;
f6667c5e 1652 case 'B':
661a1806 1653 case 'E':
e290c4b9 1654 case 'N':
661a1806
MG
1655 case 'X':
1656 case 'Y':
1657 case 'R':
ffb6d7d5 1658 strbuf_addch(sb, c->signature_check.result);
f6667c5e
JH
1659 }
1660 break;
1661 case 'S':
ffb6d7d5
SG
1662 if (c->signature_check.signer)
1663 strbuf_addstr(sb, c->signature_check.signer);
f6667c5e 1664 break;
0174eeaa 1665 case 'K':
ffb6d7d5
SG
1666 if (c->signature_check.key)
1667 strbuf_addstr(sb, c->signature_check.key);
0174eeaa 1668 break;
3daaaabe
MG
1669 case 'F':
1670 if (c->signature_check.fingerprint)
1671 strbuf_addstr(sb, c->signature_check.fingerprint);
1672 break;
4de9394d
MG
1673 case 'P':
1674 if (c->signature_check.primary_key_fingerprint)
1675 strbuf_addstr(sb, c->signature_check.primary_key_fingerprint);
1676 break;
54887b46 1677 case 'T':
803978da 1678 strbuf_addstr(sb, gpg_trust_level_to_str(c->signature_check.trust_level));
54887b46 1679 break;
aa4b78d4
JK
1680 default:
1681 return 0;
f6667c5e
JH
1682 }
1683 return 2;
1684 }
1685
a58dd835
AK
1686 if (skip_prefix(placeholder, "(decorate", &arg)) {
1687 struct decoration_options opts = { NULL };
1688 size_t ret = 0;
1689
1690 if (*arg == ':') {
1691 arg++;
1692 parse_decoration_options(&arg, &opts);
1693 }
1694 if (*arg == ')') {
1695 format_decorations(sb, commit, c->auto_color, &opts);
1696 ret = arg - placeholder + 1;
1697 }
1698
1699 free_decoration_options(&opts);
1700 return ret;
1701 }
1702
cde75e59 1703 /* For the rest we have to parse the commit header. */
018b9deb
JK
1704 if (!c->commit_header_parsed) {
1705 msg = c->message =
1706 repo_logmsg_reencode(c->repository, commit,
1707 &c->commit_encoding, "UTF-8");
f29d5958 1708 parse_commit_header(c);
018b9deb 1709 }
93fc05eb 1710
f29d5958 1711 switch (placeholder[0]) {
c3a670de
MC
1712 case 'a': /* author ... */
1713 return format_person_part(sb, placeholder[1],
d36f8679 1714 msg + c->author.off, c->author.len,
9720d23e 1715 c->pretty_ctx->date_mode);
c3a670de
MC
1716 case 'c': /* committer ... */
1717 return format_person_part(sb, placeholder[1],
d36f8679 1718 msg + c->committer.off, c->committer.len,
9720d23e 1719 c->pretty_ctx->date_mode);
c3a670de 1720 case 'e': /* encoding */
0940a76d
NTND
1721 if (c->commit_encoding)
1722 strbuf_addstr(sb, c->commit_encoding);
c3a670de 1723 return 1;
1367b12a
EB
1724 case 'B': /* raw body */
1725 /* message_off is always left at the initial newline */
1726 strbuf_addstr(sb, msg + c->message_off + 1);
1727 return 1;
f53bd743
RS
1728 }
1729
1730 /* Now we need to parse the commit message. */
1731 if (!c->commit_message_parsed)
1732 parse_commit_message(c);
1733
1734 switch (placeholder[0]) {
1735 case 's': /* subject */
1736 format_subject(sb, msg + c->subject_off, " ");
1737 return 1;
46d164b0 1738 case 'f': /* sanitized subject */
47d4676a
HV
1739 eol = strchrnul(msg + c->subject_off, '\n');
1740 format_sanitized_subject(sb, msg + c->subject_off, eol - (msg + c->subject_off));
46d164b0 1741 return 1;
c3a670de 1742 case 'b': /* body */
f29d5958 1743 strbuf_addstr(sb, msg + c->body_off);
c3a670de 1744 return 1;
93fc05eb 1745 }
d9f31fbf 1746
58311c66 1747 if (skip_prefix(placeholder, "(trailers", &arg)) {
a388b10f 1748 struct process_trailer_options opts = PROCESS_TRAILER_OPTIONS_INIT;
250bea0c 1749 struct string_list filter_list = STRING_LIST_INIT_NODUP;
0b691d86 1750 struct strbuf sepbuf = STRBUF_INIT;
058761f1 1751 struct strbuf kvsepbuf = STRBUF_INIT;
3e3f3478 1752 size_t ret = 0;
e5fba5d5
JK
1753
1754 opts.no_divider = 1;
1755
84ff053d
TB
1756 if (*arg == ':') {
1757 arg++;
636a0aee 1758 if (format_set_trailers_options(&opts, &filter_list, &sepbuf, &kvsepbuf, &arg, NULL))
90563aed 1759 goto trailer_out;
58311c66
JK
1760 }
1761 if (*arg == ')') {
0383dc56 1762 format_trailers_from_commit(&opts, msg + c->subject_off, sb);
3e3f3478 1763 ret = arg - placeholder + 1;
58311c66 1764 }
250bea0c
AW
1765 trailer_out:
1766 string_list_clear(&filter_list, 0);
0b691d86 1767 strbuf_release(&sepbuf);
3e3f3478 1768 return ret;
d9f31fbf
JK
1769 }
1770
c3a670de 1771 return 0; /* unknown placeholder */
cde75e59
RS
1772}
1773
a5752342
NTND
1774static size_t format_and_pad_commit(struct strbuf *sb, /* in UTF-8 */
1775 const char *placeholder,
1776 struct format_commit_context *c)
1777{
1778 struct strbuf local_sb = STRBUF_INIT;
81dc898d
PS
1779 size_t total_consumed = 0;
1780 int len, padding = c->padding;
1781
a5752342
NTND
1782 if (padding < 0) {
1783 const char *start = strrchr(sb->buf, '\n');
1784 int occupied;
1785 if (!start)
1786 start = sb->buf;
522cc87f 1787 occupied = utf8_strnwidth(start, strlen(start), 1);
3ad87c80 1788 occupied += c->pretty_ctx->graph_width;
a5752342
NTND
1789 padding = (-padding) - occupied;
1790 }
1791 while (1) {
1792 int modifier = *placeholder == 'C';
81dc898d 1793 size_t consumed = format_commit_one(&local_sb, placeholder, c);
a5752342
NTND
1794 total_consumed += consumed;
1795
1796 if (!modifier)
1797 break;
1798
1799 placeholder += consumed;
1800 if (*placeholder != '%')
1801 break;
1802 placeholder++;
1803 total_consumed++;
1804 }
522cc87f 1805 len = utf8_strnwidth(local_sb.buf, local_sb.len, 1);
1640632b
NTND
1806
1807 if (c->flush_type == flush_left_and_steal) {
1808 const char *ch = sb->buf + sb->len - 1;
1809 while (len > padding && ch > sb->buf) {
1810 const char *p;
1811 if (*ch == ' ') {
1812 ch--;
1813 padding++;
1814 continue;
1815 }
1816 /* check for trailing ansi sequences */
1817 if (*ch != 'm')
1818 break;
1819 p = ch - 1;
b49f309a 1820 while (p > sb->buf && ch - p < 10 && *p != '\033')
1640632b
NTND
1821 p--;
1822 if (*p != '\033' ||
1823 ch + 1 - p != display_mode_esc_sequence_len(p))
1824 break;
1825 /*
1826 * got a good ansi sequence, put it back to
1827 * local_sb as we're cutting sb
1828 */
1829 strbuf_insert(&local_sb, 0, p, ch + 1 - p);
1830 ch = p - 1;
1831 }
1832 strbuf_setlen(sb, ch + 1 - sb->buf);
1833 c->flush_type = flush_left;
1834 }
1835
a7f01c6b
NTND
1836 if (len > padding) {
1837 switch (c->truncate) {
1838 case trunc_left:
1839 strbuf_utf8_replace(&local_sb,
1840 0, len - (padding - 2),
1841 "..");
1842 break;
1843 case trunc_middle:
1844 strbuf_utf8_replace(&local_sb,
1845 padding / 2 - 1,
1846 len - (padding - 2),
1847 "..");
1848 break;
1849 case trunc_right:
1850 strbuf_utf8_replace(&local_sb,
1851 padding - 2, len - (padding - 2),
1852 "..");
1853 break;
1854 case trunc_none:
1855 break;
1856 }
e992d1eb 1857 strbuf_addbuf(sb, &local_sb);
a7f01c6b 1858 } else {
81dc898d 1859 size_t sb_len = sb->len, offset = 0;
a5752342
NTND
1860 if (c->flush_type == flush_left)
1861 offset = padding - len;
1862 else if (c->flush_type == flush_both)
1863 offset = (padding - len) / 2;
1864 /*
1865 * we calculate padding in columns, now
1866 * convert it back to chars
1867 */
1868 padding = padding - len + local_sb.len;
415792ed 1869 strbuf_addchars(sb, ' ', padding);
a5752342
NTND
1870 memcpy(sb->buf + sb_len + offset, local_sb.buf,
1871 local_sb.len);
1872 }
1873 strbuf_release(&local_sb);
1874 c->flush_type = no_flush;
1875 return total_consumed;
1876}
1877
7e77df39
NTND
1878static size_t format_commit_item(struct strbuf *sb, /* in UTF-8 */
1879 const char *placeholder,
6f1e2d52 1880 struct format_commit_context *context)
9fa708da 1881{
81dc898d 1882 size_t consumed, orig_len;
9fa708da
JH
1883 enum {
1884 NO_MAGIC,
1885 ADD_LF_BEFORE_NON_EMPTY,
1886 DEL_LF_BEFORE_EMPTY,
223a923c 1887 ADD_SP_BEFORE_NON_EMPTY
9fa708da
JH
1888 } magic = NO_MAGIC;
1889
1890 switch (placeholder[0]) {
1891 case '-':
1892 magic = DEL_LF_BEFORE_EMPTY;
1893 break;
1894 case '+':
1895 magic = ADD_LF_BEFORE_NON_EMPTY;
1896 break;
7b88176e
MG
1897 case ' ':
1898 magic = ADD_SP_BEFORE_NON_EMPTY;
1899 break;
9fa708da
JH
1900 default:
1901 break;
1902 }
1de69c0c 1903 if (magic != NO_MAGIC) {
9fa708da
JH
1904 placeholder++;
1905
1de69c0c
PS
1906 switch (placeholder[0]) {
1907 case 'w':
1908 /*
1909 * `%+w()` cannot ever expand to a non-empty string,
1910 * and it potentially changes the layout of preceding
1911 * contents. We're thus not able to handle the magic in
1912 * this combination and refuse the pattern.
1913 */
1914 return 0;
1915 };
1916 }
1917
9fa708da 1918 orig_len = sb->len;
1dd14e8e 1919 if (context->flush_type == no_flush)
a5752342 1920 consumed = format_commit_one(sb, placeholder, context);
1dd14e8e
RS
1921 else
1922 consumed = format_and_pad_commit(sb, placeholder, context);
9fa708da
JH
1923 if (magic == NO_MAGIC)
1924 return consumed;
1925
1926 if ((orig_len == sb->len) && magic == DEL_LF_BEFORE_EMPTY) {
1927 while (sb->len && sb->buf[sb->len - 1] == '\n')
1928 strbuf_setlen(sb, sb->len - 1);
7b88176e
MG
1929 } else if (orig_len != sb->len) {
1930 if (magic == ADD_LF_BEFORE_NON_EMPTY)
a91cc7fa 1931 strbuf_insertstr(sb, orig_len, "\n");
7b88176e 1932 else if (magic == ADD_SP_BEFORE_NON_EMPTY)
a91cc7fa 1933 strbuf_insertstr(sb, orig_len, " ");
9fa708da
JH
1934 }
1935 return consumed + 1;
1936}
1937
5b163603
JG
1938void userformat_find_requirements(const char *fmt, struct userformat_want *w)
1939{
5b163603
JG
1940 if (!fmt) {
1941 if (!user_format)
1942 return;
1943 fmt = user_format;
1944 }
bd19ee9c
RS
1945 while ((fmt = strchr(fmt, '%'))) {
1946 fmt++;
6f1e2d52
RS
1947 if (skip_prefix(fmt, "%", &fmt))
1948 continue;
1949
1950 if (*fmt == '+' || *fmt == '-' || *fmt == ' ')
1951 fmt++;
1952
1953 switch (*fmt) {
1954 case 'N':
1955 w->notes = 1;
1956 break;
1957 case 'S':
1958 w->source = 1;
1959 break;
1960 case 'd':
1961 case 'D':
1962 w->decorate = 1;
1963 break;
2b09d16a
AK
1964 case '(':
1965 if (starts_with(fmt + 1, "decorate"))
1966 w->decorate = 1;
1967 break;
6f1e2d52
RS
1968 }
1969 }
5b163603
JG
1970}
1971
f54fbf5e
SB
1972void repo_format_commit_message(struct repository *r,
1973 const struct commit *commit,
1974 const char *format, struct strbuf *sb,
1975 const struct pretty_print_context *pretty_ctx)
cde75e59 1976{
3e8ed3b9 1977 struct format_commit_context context = {
018b9deb 1978 .repository = r,
3e8ed3b9
DL
1979 .commit = commit,
1980 .pretty_ctx = pretty_ctx,
1981 .wrap_start = sb->len
1982 };
177b29dc 1983 const char *output_enc = pretty_ctx->output_encoding;
7e77df39 1984 const char *utf8 = "UTF-8";
f29d5958 1985
6f1e2d52
RS
1986 while (strbuf_expand_step(sb, &format)) {
1987 size_t len;
1988
1989 if (skip_prefix(format, "%", &format))
1990 strbuf_addch(sb, '%');
1991 else if ((len = format_commit_item(sb, format, &context)))
1992 format += len;
1993 else
1994 strbuf_addch(sb, '%');
1995 }
02edd56b 1996 rewrap_message_tail(sb, &context, 0, 0, 0);
177b29dc 1997
018b9deb
JK
1998 /*
1999 * Convert output to an actual output encoding; note that
2000 * format_commit_item() will always use UTF-8, so we don't
2001 * have to bother if that's what the output wants.
2002 */
7e77df39
NTND
2003 if (output_enc) {
2004 if (same_encoding(utf8, output_enc))
2005 output_enc = NULL;
2006 } else {
2007 if (context.commit_encoding &&
2008 !same_encoding(context.commit_encoding, utf8))
2009 output_enc = context.commit_encoding;
2010 }
2011
2012 if (output_enc) {
c7d017d7 2013 size_t outsz;
7e77df39
NTND
2014 char *out = reencode_string_len(sb->buf, sb->len,
2015 output_enc, utf8, &outsz);
2016 if (out)
2017 strbuf_attach(sb, out, outsz, outsz + 1);
2018 }
2019
0940a76d 2020 free(context.commit_encoding);
f54fbf5e 2021 repo_unuse_commit_buffer(r, commit, context.message);
93fc05eb
JS
2022}
2023
10f2fbff 2024static void pp_header(struct pretty_print_context *pp,
93fc05eb
JS
2025 const char *encoding,
2026 const struct commit *commit,
2027 const char **msg_p,
2028 struct strbuf *sb)
2029{
2030 int parents_shown = 0;
2031
2032 for (;;) {
e3f1da98 2033 const char *name, *line = *msg_p;
93fc05eb
JS
2034 int linelen = get_one_line(*msg_p);
2035
2036 if (!linelen)
2037 return;
2038 *msg_p += linelen;
2039
2040 if (linelen == 1)
2041 /* End of header */
2042 return;
2043
6bf13944 2044 if (pp->fmt == CMIT_FMT_RAW) {
93fc05eb
JS
2045 strbuf_add(sb, line, linelen);
2046 continue;
2047 }
2048
59556548 2049 if (starts_with(line, "parent ")) {
580f0980 2050 if (linelen != the_hash_algo->hexsz + 8)
93fc05eb
JS
2051 die("bad parent line in commit");
2052 continue;
2053 }
2054
2055 if (!parents_shown) {
4bbaa1eb 2056 unsigned num = commit_list_count(commit->parents);
93fc05eb 2057 /* with enough slop */
580f0980 2058 strbuf_grow(sb, num * (GIT_MAX_HEXSZ + 10) + 20);
6bf13944 2059 add_merge_info(pp, sb, commit);
93fc05eb
JS
2060 parents_shown = 1;
2061 }
2062
2063 /*
2064 * MEDIUM == DEFAULT shows only author with dates.
2065 * FULL shows both authors but not dates.
2066 * FULLER shows both authors and dates.
2067 */
e3f1da98 2068 if (skip_prefix(line, "author ", &name)) {
93fc05eb 2069 strbuf_grow(sb, linelen + 80);
e3f1da98 2070 pp_user_info(pp, "Author", sb, name, encoding);
93fc05eb 2071 }
e3f1da98 2072 if (skip_prefix(line, "committer ", &name) &&
6bf13944 2073 (pp->fmt == CMIT_FMT_FULL || pp->fmt == CMIT_FMT_FULLER)) {
93fc05eb 2074 strbuf_grow(sb, linelen + 80);
e3f1da98 2075 pp_user_info(pp, "Commit", sb, name, encoding);
93fc05eb
JS
2076 }
2077 }
2078}
2079
69aff620
JK
2080void pp_email_subject(struct pretty_print_context *pp,
2081 const char **msg_p,
2082 struct strbuf *sb,
2083 const char *encoding,
2084 int need_8bit_cte)
93fc05eb 2085{
41dd00ba 2086 static const int max_length = 78; /* per rfc2047 */
93fc05eb
JS
2087 struct strbuf title;
2088
2089 strbuf_init(&title, 80);
9553d2b2
JK
2090 *msg_p = format_subject(&title, *msg_p,
2091 pp->preserve_subject ? "\n" : " ");
93fc05eb
JS
2092
2093 strbuf_grow(sb, title.len + 1024);
d5a90d63
JK
2094 fmt_output_email_subject(sb, pp->rev);
2095 if (pp->encode_email_headers &&
2096 needs_rfc2047_encoding(title.buf, title.len))
2097 add_rfc2047(sb, title.buf, title.len,
2098 encoding, RFC2047_SUBJECT);
2099 else
2100 strbuf_add_wrapped_bytes(sb, title.buf, title.len,
41dd00ba 2101 -last_line_length(sb), 1, max_length);
93fc05eb
JS
2102 strbuf_addch(sb, '\n');
2103
a9080475
JK
2104 if (need_8bit_cte == 0) {
2105 int i;
2106 for (i = 0; i < pp->in_body_headers.nr; i++) {
2107 if (has_non_ascii(pp->in_body_headers.items[i].string)) {
2108 need_8bit_cte = 1;
2109 break;
2110 }
2111 }
2112 }
2113
6bf4f1b4 2114 if (need_8bit_cte > 0) {
93fc05eb
JS
2115 const char *header_fmt =
2116 "MIME-Version: 1.0\n"
2117 "Content-Type: text/plain; charset=%s\n"
2118 "Content-Transfer-Encoding: 8bit\n";
2119 strbuf_addf(sb, header_fmt, encoding);
2120 }
6bf13944
JK
2121 if (pp->after_subject) {
2122 strbuf_addstr(sb, pp->after_subject);
93fc05eb 2123 }
69aff620
JK
2124
2125 strbuf_addch(sb, '\n');
a9080475
JK
2126
2127 if (pp->in_body_headers.nr) {
2128 int i;
2129 for (i = 0; i < pp->in_body_headers.nr; i++) {
2130 strbuf_addstr(sb, pp->in_body_headers.items[i].string);
2131 free(pp->in_body_headers.items[i].string);
2132 }
2133 string_list_clear(&pp->in_body_headers, 0);
2134 strbuf_addch(sb, '\n');
2135 }
2136
93fc05eb
JS
2137 strbuf_release(&title);
2138}
2139
7cc13c71
LT
2140static int pp_utf8_width(const char *start, const char *end)
2141{
2142 int width = 0;
2143 size_t remain = end - start;
2144
2145 while (remain) {
2146 int n = utf8_width(&start, &remain);
2147 if (n < 0 || !start)
2148 return -1;
2149 width += n;
2150 }
2151 return width;
2152}
2153
6a5c3379
HM
2154static void strbuf_add_tabexpand(struct strbuf *sb, struct grep_opt *opt,
2155 int color, int tabwidth, const char *line,
2156 int linelen)
7cc13c71
LT
2157{
2158 const char *tab;
2159
2160 while ((tab = memchr(line, '\t', linelen)) != NULL) {
2161 int width = pp_utf8_width(line, tab);
2162
2163 /*
2164 * If it wasn't well-formed utf8, or it
2165 * had characters with badly defined
2166 * width (control characters etc), just
2167 * give up on trying to align things.
2168 */
2169 if (width < 0)
2170 break;
2171
2172 /* Output the data .. */
6a5c3379
HM
2173 append_line_with_color(sb, opt, line, tab - line, color,
2174 GREP_CONTEXT_BODY,
2175 GREP_HEADER_FIELD_MAX);
7cc13c71
LT
2176
2177 /* .. and the de-tabified tab */
fe37a9c5 2178 strbuf_addchars(sb, ' ', tabwidth - (width % tabwidth));
7cc13c71
LT
2179
2180 /* Skip over the printed part .. */
2181 linelen -= tab + 1 - line;
2182 line = tab + 1;
2183 }
2184
2185 /*
2186 * Print out everything after the last tab without
2187 * worrying about width - there's nothing more to
2188 * align.
2189 */
6a5c3379
HM
2190 append_line_with_color(sb, opt, line, linelen, color, GREP_CONTEXT_BODY,
2191 GREP_HEADER_FIELD_MAX);
7cc13c71
LT
2192}
2193
2194/*
2195 * pp_handle_indent() prints out the intendation, and
2196 * the whole line (without the final newline), after
2197 * de-tabifying.
2198 */
2199static void pp_handle_indent(struct pretty_print_context *pp,
2200 struct strbuf *sb, int indent,
2201 const char *line, int linelen)
2202{
6a5c3379
HM
2203 struct grep_opt *opt = pp->rev ? &pp->rev->grep_filter : NULL;
2204
7cc13c71
LT
2205 strbuf_addchars(sb, ' ', indent);
2206 if (pp->expand_tabs_in_log)
6a5c3379
HM
2207 strbuf_add_tabexpand(sb, opt, pp->color, pp->expand_tabs_in_log,
2208 line, linelen);
7cc13c71 2209 else
6a5c3379
HM
2210 append_line_with_color(sb, opt, line, linelen, pp->color,
2211 GREP_CONTEXT_BODY,
2212 GREP_HEADER_FIELD_MAX);
7cc13c71
LT
2213}
2214
9f23e040
EW
2215static int is_mboxrd_from(const char *line, int len)
2216{
2217 /*
2218 * a line matching /^From $/ here would only have len == 4
2219 * at this point because is_empty_line would've trimmed all
2220 * trailing space
2221 */
2222 return len > 4 && starts_with(line + strspn(line, ">"), "From ");
2223}
2224
10f2fbff 2225void pp_remainder(struct pretty_print_context *pp,
b02bd65f
DB
2226 const char **msg_p,
2227 struct strbuf *sb,
2228 int indent)
93fc05eb 2229{
6a5c3379 2230 struct grep_opt *opt = pp->rev ? &pp->rev->grep_filter : NULL;
93fc05eb 2231 int first = 1;
6a5c3379 2232
93fc05eb
JS
2233 for (;;) {
2234 const char *line = *msg_p;
2235 int linelen = get_one_line(line);
2236 *msg_p += linelen;
2237
2238 if (!linelen)
2239 break;
2240
77356122 2241 if (is_blank_line(line, &linelen)) {
93fc05eb
JS
2242 if (first)
2243 continue;
6bf13944 2244 if (pp->fmt == CMIT_FMT_SHORT)
93fc05eb
JS
2245 break;
2246 }
2247 first = 0;
2248
2249 strbuf_grow(sb, linelen + indent + 20);
415792ed 2250 if (indent)
7cc13c71 2251 pp_handle_indent(pp, sb, indent, line, linelen);
0893eec8 2252 else if (pp->expand_tabs_in_log)
6a5c3379
HM
2253 strbuf_add_tabexpand(sb, opt, pp->color,
2254 pp->expand_tabs_in_log, line,
2255 linelen);
9f23e040
EW
2256 else {
2257 if (pp->fmt == CMIT_FMT_MBOXRD &&
2258 is_mboxrd_from(line, linelen))
2259 strbuf_addch(sb, '>');
2260
6a5c3379
HM
2261 append_line_with_color(sb, opt, line, linelen,
2262 pp->color, GREP_CONTEXT_BODY,
2263 GREP_HEADER_FIELD_MAX);
9f23e040 2264 }
93fc05eb
JS
2265 strbuf_addch(sb, '\n');
2266 }
2267}
2268
10f2fbff 2269void pretty_print_commit(struct pretty_print_context *pp,
6bf13944
JK
2270 const struct commit *commit,
2271 struct strbuf *sb)
93fc05eb
JS
2272{
2273 unsigned long beginning_of_body;
2274 int indent = 4;
dd0d388c 2275 const char *msg;
b000c59b 2276 const char *reencoded;
93fc05eb 2277 const char *encoding;
6bf13944 2278 int need_8bit_cte = pp->need_8bit_cte;
93fc05eb 2279
6bf13944 2280 if (pp->fmt == CMIT_FMT_USERFORMAT) {
bab82164
ÆAB
2281 repo_format_commit_message(the_repository, commit,
2282 user_format, sb, pp);
93fc05eb
JS
2283 return;
2284 }
2285
e297cf5a 2286 encoding = get_log_output_encoding();
ecb5091f
ÆAB
2287 msg = reencoded = repo_logmsg_reencode(the_repository, commit, NULL,
2288 encoding);
93fc05eb 2289
9f23e040 2290 if (pp->fmt == CMIT_FMT_ONELINE || cmit_fmt_is_mail(pp->fmt))
93fc05eb
JS
2291 indent = 0;
2292
6bf4f1b4
JH
2293 /*
2294 * We need to check and emit Content-type: to mark it
2295 * as 8-bit if we haven't done so.
93fc05eb 2296 */
9f23e040 2297 if (cmit_fmt_is_mail(pp->fmt) && need_8bit_cte == 0) {
93fc05eb
JS
2298 int i, ch, in_body;
2299
2300 for (in_body = i = 0; (ch = msg[i]); i++) {
2301 if (!in_body) {
2302 /* author could be non 7-bit ASCII but
2303 * the log may be so; skip over the
2304 * header part first.
2305 */
2306 if (ch == '\n' && msg[i+1] == '\n')
2307 in_body = 1;
2308 }
2309 else if (non_ascii(ch)) {
6bf4f1b4 2310 need_8bit_cte = 1;
93fc05eb
JS
2311 break;
2312 }
2313 }
2314 }
2315
6bf13944 2316 pp_header(pp, encoding, commit, &msg, sb);
d5a90d63 2317 if (pp->fmt != CMIT_FMT_ONELINE && !cmit_fmt_is_mail(pp->fmt)) {
93fc05eb
JS
2318 strbuf_addch(sb, '\n');
2319 }
2320
2321 /* Skip excess blank lines at the beginning of body, if any... */
77356122 2322 msg = skip_blank_lines(msg);
93fc05eb
JS
2323
2324 /* These formats treat the title line specially. */
69aff620
JK
2325 if (pp->fmt == CMIT_FMT_ONELINE) {
2326 msg = format_subject(sb, msg, " ");
2327 strbuf_addch(sb, '\n');
2328 } else if (cmit_fmt_is_mail(pp->fmt))
2329 pp_email_subject(pp, &msg, sb, encoding, need_8bit_cte);
93fc05eb
JS
2330
2331 beginning_of_body = sb->len;
6bf13944
JK
2332 if (pp->fmt != CMIT_FMT_ONELINE)
2333 pp_remainder(pp, &msg, sb, indent);
93fc05eb
JS
2334 strbuf_rtrim(sb);
2335
2336 /* Make sure there is an EOLN for the non-oneline case */
6bf13944 2337 if (pp->fmt != CMIT_FMT_ONELINE)
93fc05eb
JS
2338 strbuf_addch(sb, '\n');
2339
2340 /*
2341 * The caller may append additional body text in e-mail
2342 * format. Make sure we did not strip the blank line
2343 * between the header and the body.
2344 */
9f23e040 2345 if (cmit_fmt_is_mail(pp->fmt) && sb->len <= beginning_of_body)
93fc05eb 2346 strbuf_addch(sb, '\n');
a97a7468 2347
ecb5091f 2348 repo_unuse_commit_buffer(the_repository, commit, reencoded);
93fc05eb 2349}
8b8a5374
JK
2350
2351void pp_commit_easy(enum cmit_fmt fmt, const struct commit *commit,
2352 struct strbuf *sb)
2353{
2354 struct pretty_print_context pp = {0};
6bf13944
JK
2355 pp.fmt = fmt;
2356 pretty_print_commit(&pp, commit, sb);
8b8a5374 2357}