Skip to content

Commit f53bd74

Browse files
René Scharfegitster
authored andcommitted
pretty: support multiline subjects with format:
git log --pretty=format:%s (and tformat:) used to display the first line of the subject, unlike the other --pretty options, which would construct a subject line from all lines of the first paragraph of the commit message. For consistency and increased code reuse, change format: to do the same as the other options. Before: $ git log --pretty=oneline v1.6.1 | md5sum 7c0896d2a94fc3315a0372b9b3373a8f - $ git log --pretty=tformat:"%H %s" v1.6.1 | md5sum 298903b1c065002e15daa5329213c51f - After: $ git log --pretty=tformat:"%H %s" v1.6.1 | md5sum 7c0896d2a94fc3315a0372b9b3373a8f - $ git log --pretty=oneline v1.6.1 | md5sum 7c0896d2a94fc3315a0372b9b3373a8f - Signed-off-by: Rene Scharfe <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 88c4473 commit f53bd74

File tree

1 file changed

+34
-19
lines changed

1 file changed

+34
-19
lines changed

pretty.c

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -424,13 +424,15 @@ struct chunk {
424424
struct format_commit_context {
425425
const struct commit *commit;
426426
enum date_mode dmode;
427+
unsigned commit_header_parsed:1;
428+
unsigned commit_message_parsed:1;
427429

428430
/* These offsets are relative to the start of the commit message. */
429-
int commit_header_parsed;
430-
struct chunk subject;
431431
struct chunk author;
432432
struct chunk committer;
433433
struct chunk encoding;
434+
size_t message_off;
435+
size_t subject_off;
434436
size_t body_off;
435437

436438
/* The following ones are relative to the result struct strbuf. */
@@ -460,23 +462,14 @@ static void parse_commit_header(struct format_commit_context *context)
460462
{
461463
const char *msg = context->commit->buffer;
462464
int i;
463-
enum { HEADER, SUBJECT, BODY } state;
464465

465-
for (i = 0, state = HEADER; msg[i] && state < BODY; i++) {
466+
for (i = 0; msg[i]; i++) {
466467
int eol;
467468
for (eol = i; msg[eol] && msg[eol] != '\n'; eol++)
468469
; /* do nothing */
469470

470-
if (state == SUBJECT) {
471-
context->subject.off = i;
472-
context->subject.len = eol - i;
473-
i = eol;
474-
}
475471
if (i == eol) {
476-
state++;
477-
/* strip empty lines */
478-
while (msg[eol] == '\n' && msg[eol + 1] == '\n')
479-
eol++;
472+
break;
480473
} else if (!prefixcmp(msg + i, "author ")) {
481474
context->author.off = i + 7;
482475
context->author.len = eol - i - 7;
@@ -488,10 +481,8 @@ static void parse_commit_header(struct format_commit_context *context)
488481
context->encoding.len = eol - i - 9;
489482
}
490483
i = eol;
491-
if (!msg[i])
492-
break;
493484
}
494-
context->body_off = i;
485+
context->message_off = i;
495486
context->commit_header_parsed = 1;
496487
}
497488

@@ -508,6 +499,8 @@ static const char *format_subject(struct strbuf *sb, const char *msg,
508499
if (!linelen || is_empty_line(line, &linelen))
509500
break;
510501

502+
if (!sb)
503+
continue;
511504
strbuf_grow(sb, linelen + 2);
512505
if (!first)
513506
strbuf_addstr(sb, line_separator);
@@ -517,6 +510,21 @@ static const char *format_subject(struct strbuf *sb, const char *msg,
517510
return msg;
518511
}
519512

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+
520528
static void format_decoration(struct strbuf *sb, const struct commit *commit)
521529
{
522530
struct name_decoration *d;
@@ -636,9 +644,6 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
636644
parse_commit_header(c);
637645

638646
switch (placeholder[0]) {
639-
case 's': /* subject */
640-
strbuf_add(sb, msg + c->subject.off, c->subject.len);
641-
return 1;
642647
case 'a': /* author ... */
643648
return format_person_part(sb, placeholder[1],
644649
msg + c->author.off, c->author.len,
@@ -650,6 +655,16 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
650655
case 'e': /* encoding */
651656
strbuf_add(sb, msg + c->encoding.off, c->encoding.len);
652657
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;
653668
case 'b': /* body */
654669
strbuf_addstr(sb, msg + c->body_off);
655670
return 1;

0 commit comments

Comments
 (0)