@matheusbsbs / matheus-bagliano / commits / f53bd743ff
Fork 0

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 <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>

René Scharfe committed Dec 27, 2008 at 01:49 UTC f53bd743ff713f6507f28f8e730ac3e27858ab43
1 file changed +34 -19
pretty.c
+34 -19
@@ -424,13 +424,15 @@ struct chunk {
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. */
@@ -460,23 +462,14 @@ static void parse_commit_header(struct format_commit_context *context)
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;
@@ -488,10 +481,8 @@ static void parse_commit_header(struct format_commit_context *context)
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
@@ -508,6 +499,8 @@ static const char *format_subject(struct strbuf *sb, const char *msg,
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);
@@ -517,6 +510,21 @@ static const char *format_subject(struct strbuf *sb, const char *msg,
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;
@@ -636,9 +644,6 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
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,
@@ -650,6 +655,16 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
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;