424
struct format_commit_context {
425
const struct commit *commit;
426
enum date_mode dmode;
427
+ unsigned commit_header_parsed:1;
428
+ unsigned commit_message_parsed:1;
429
430
/* These offsets are relative to the start of the commit message. */
429
- int commit_header_parsed;
430
- struct chunk subject;
431
struct chunk author;
432
struct chunk committer;
433
struct chunk encoding;
434
+ size_t message_off;
435
+ size_t subject_off;
436
size_t body_off;
437
438
/* The following ones are relative to the result struct strbuf. */
462
{
463
const char *msg = context->commit->buffer;
464
int i;
463
- enum { HEADER, SUBJECT, BODY } state;
465
465
- for (i = 0, state = HEADER; msg[i] && state < BODY; i++) {
466
+ for (i = 0; msg[i]; i++) {
467
int eol;
468
for (eol = i; msg[eol] && msg[eol] != '\n'; eol++)
469
; /* do nothing */
470
470
- if (state == SUBJECT) {
471
- context->subject.off = i;
472
- context->subject.len = eol - i;
473
- i = eol;
474
- }
471
if (i == eol) {
476
- state++;
477
- /* strip empty lines */
478
- while (msg[eol] == '\n' && msg[eol + 1] == '\n')
479
- eol++;
472
+ break;
473
} else if (!prefixcmp(msg + i, "author ")) {
474
context->author.off = i + 7;
475
context->author.len = eol - i - 7;
481
context->encoding.len = eol - i - 9;
482
}
483
i = eol;
491
- if (!msg[i])
492
- break;
484
}
494
- context->body_off = i;
485
+ context->message_off = i;
486
context->commit_header_parsed = 1;
487
}
488
499
if (!linelen || is_empty_line(line, &linelen))
500
break;
501
502
+ if (!sb)
503
+ continue;
504
strbuf_grow(sb, linelen + 2);
505
if (!first)
506
strbuf_addstr(sb, line_separator);
510
return msg;
511
}
512
513
+static void parse_commit_message(struct format_commit_context *c)
514
+{
515
+ const char *msg = c->commit->buffer + c->message_off;
516
+ const char *start = c->commit->buffer;
517
+
518
+ msg = skip_empty_lines(msg);
519
+ c->subject_off = msg - start;
520
+
521
+ msg = format_subject(NULL, msg, NULL);
522
+ msg = skip_empty_lines(msg);
523
+ c->body_off = msg - start;
524
+
525
+ c->commit_message_parsed = 1;
526
+}
527
+
528
static void format_decoration(struct strbuf *sb, const struct commit *commit)
529
{
530
struct name_decoration *d;
644
parse_commit_header(c);
645
646
switch (placeholder[0]) {
639
- case 's': /* subject */
640
- strbuf_add(sb, msg + c->subject.off, c->subject.len);
641
- return 1;
647
case 'a': /* author ... */
648
return format_person_part(sb, placeholder[1],
649
msg + c->author.off, c->author.len,
655
case 'e': /* encoding */
656
strbuf_add(sb, msg + c->encoding.off, c->encoding.len);
657
return 1;
658
+ }
659
+
660
+ /* Now we need to parse the commit message. */
661
+ if (!c->commit_message_parsed)
662
+ parse_commit_message(c);
663
+
664
+ switch (placeholder[0]) {
665
+ case 's': /* subject */
666
+ format_subject(sb, msg + c->subject_off, " ");
667
+ return 1;
668
case 'b': /* body */
669
strbuf_addstr(sb, msg + c->body_off);
670
return 1;