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>
This commit is contained in:
René Scharfe 2008-12-27 01:49:21 +01:00 коммит произвёл Junio C Hamano
Родитель 88c44735ab
Коммит f53bd743ff
1 изменённых файлов: 34 добавлений и 19 удалений

Просмотреть файл

@ -424,13 +424,15 @@ struct chunk {
struct format_commit_context { struct format_commit_context {
const struct commit *commit; const struct commit *commit;
enum date_mode dmode; enum date_mode dmode;
unsigned commit_header_parsed:1;
unsigned commit_message_parsed:1;
/* These offsets are relative to the start of the commit message. */ /* These offsets are relative to the start of the commit message. */
int commit_header_parsed;
struct chunk subject;
struct chunk author; struct chunk author;
struct chunk committer; struct chunk committer;
struct chunk encoding; struct chunk encoding;
size_t message_off;
size_t subject_off;
size_t body_off; size_t body_off;
/* The following ones are relative to the result struct strbuf. */ /* The following ones are relative to the result struct strbuf. */
@ -460,23 +462,14 @@ static void parse_commit_header(struct format_commit_context *context)
{ {
const char *msg = context->commit->buffer; const char *msg = context->commit->buffer;
int i; int i;
enum { HEADER, SUBJECT, BODY } state;
for (i = 0, state = HEADER; msg[i] && state < BODY; i++) { for (i = 0; msg[i]; i++) {
int eol; int eol;
for (eol = i; msg[eol] && msg[eol] != '\n'; eol++) for (eol = i; msg[eol] && msg[eol] != '\n'; eol++)
; /* do nothing */ ; /* do nothing */
if (state == SUBJECT) {
context->subject.off = i;
context->subject.len = eol - i;
i = eol;
}
if (i == eol) { if (i == eol) {
state++; break;
/* strip empty lines */
while (msg[eol] == '\n' && msg[eol + 1] == '\n')
eol++;
} else if (!prefixcmp(msg + i, "author ")) { } else if (!prefixcmp(msg + i, "author ")) {
context->author.off = i + 7; context->author.off = i + 7;
context->author.len = eol - i - 7; context->author.len = eol - i - 7;
@ -488,10 +481,8 @@ static void parse_commit_header(struct format_commit_context *context)
context->encoding.len = eol - i - 9; context->encoding.len = eol - i - 9;
} }
i = eol; i = eol;
if (!msg[i])
break;
} }
context->body_off = i; context->message_off = i;
context->commit_header_parsed = 1; context->commit_header_parsed = 1;
} }
@ -508,6 +499,8 @@ static const char *format_subject(struct strbuf *sb, const char *msg,
if (!linelen || is_empty_line(line, &linelen)) if (!linelen || is_empty_line(line, &linelen))
break; break;
if (!sb)
continue;
strbuf_grow(sb, linelen + 2); strbuf_grow(sb, linelen + 2);
if (!first) if (!first)
strbuf_addstr(sb, line_separator); strbuf_addstr(sb, line_separator);
@ -517,6 +510,21 @@ static const char *format_subject(struct strbuf *sb, const char *msg,
return msg; return msg;
} }
static void parse_commit_message(struct format_commit_context *c)
{
const char *msg = c->commit->buffer + c->message_off;
const char *start = c->commit->buffer;
msg = skip_empty_lines(msg);
c->subject_off = msg - start;
msg = format_subject(NULL, msg, NULL);
msg = skip_empty_lines(msg);
c->body_off = msg - start;
c->commit_message_parsed = 1;
}
static void format_decoration(struct strbuf *sb, const struct commit *commit) static void format_decoration(struct strbuf *sb, const struct commit *commit)
{ {
struct name_decoration *d; struct name_decoration *d;
@ -636,9 +644,6 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
parse_commit_header(c); parse_commit_header(c);
switch (placeholder[0]) { switch (placeholder[0]) {
case 's': /* subject */
strbuf_add(sb, msg + c->subject.off, c->subject.len);
return 1;
case 'a': /* author ... */ case 'a': /* author ... */
return format_person_part(sb, placeholder[1], return format_person_part(sb, placeholder[1],
msg + c->author.off, c->author.len, msg + c->author.off, c->author.len,
@ -650,6 +655,16 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
case 'e': /* encoding */ case 'e': /* encoding */
strbuf_add(sb, msg + c->encoding.off, c->encoding.len); strbuf_add(sb, msg + c->encoding.off, c->encoding.len);
return 1; return 1;
}
/* Now we need to parse the commit message. */
if (!c->commit_message_parsed)
parse_commit_message(c);
switch (placeholder[0]) {
case 's': /* subject */
format_subject(sb, msg + c->subject_off, " ");
return 1;
case 'b': /* body */ case 'b': /* body */
strbuf_addstr(sb, msg + c->body_off); strbuf_addstr(sb, msg + c->body_off);
return 1; return 1;