diff --git a/commit.c b/commit.c index de5e94d1dd..3d3bb1cde8 100644 --- a/commit.c +++ b/commit.c @@ -1,3 +1,4 @@ +#include #include "tag.h" #include "commit.h" #include "cache.h" @@ -193,12 +194,12 @@ static int get_one_line(const char *msg, unsigned long len) return ret; } -static int add_author_info(char *buf, const char *line, int len) +static int add_author_info(enum cmit_fmt fmt, char *buf, const char *line, int len) { char *date; unsigned int namelen; unsigned long time; - int tz; + int tz, ret; line += strlen("author "); date = strchr(line, '>'); @@ -208,14 +209,22 @@ static int add_author_info(char *buf, const char *line, int len) time = strtoul(date, &date, 10); tz = strtol(date, NULL, 10); - return sprintf(buf, "Author: %.*s\nDate: %s\n", - namelen, line, - show_date(time, tz)); + ret = sprintf(buf, "Author: %.*s\n", namelen, line); + if (fmt == CMIT_FMT_MEDIUM) + ret += sprintf(buf + ret, "Date: %s\n", show_date(time, tz)); + return ret; } -unsigned long pretty_print_commit(const char *msg, unsigned long len, char *buf, unsigned long space) +static int is_empty_line(const char *line, int len) { - int hdr = 1; + while (len && isspace(line[len-1])) + len--; + return !len; +} + +unsigned long pretty_print_commit(enum cmit_fmt fmt, const char *msg, unsigned long len, char *buf, unsigned long space) +{ + int hdr = 1, body = 0; unsigned long offset = 0; for (;;) { @@ -237,13 +246,30 @@ unsigned long pretty_print_commit(const char *msg, unsigned long len, char *buf, msg += linelen; len -= linelen; - if (linelen == 1) - hdr = 0; if (hdr) { + if (linelen == 1) { + hdr = 0; + buf[offset++] = '\n'; + continue; + } + if (fmt == CMIT_FMT_RAW) { + memcpy(buf + offset, line, linelen); + offset += linelen; + continue; + } if (!memcmp(line, "author ", 7)) - offset += add_author_info(buf + offset, line, linelen); + offset += add_author_info(fmt, buf + offset, line, linelen); continue; } + + if (is_empty_line(line, linelen)) { + if (!body) + continue; + if (fmt == CMIT_FMT_SHORT) + break; + } else { + body = 1; + } memset(buf + offset, ' ', 4); memcpy(buf + offset + 4, line, linelen); offset += linelen + 4; diff --git a/commit.h b/commit.h index 8147551c9e..85736a89f9 100644 --- a/commit.h +++ b/commit.h @@ -32,7 +32,15 @@ void free_commit_list(struct commit_list *list); void sort_by_date(struct commit_list **list); -extern unsigned long pretty_print_commit(const char *msg, unsigned long len, char *buf, unsigned long space); +/* Commit formats */ +enum cmit_fmt { + CMIT_FMT_RAW, + CMIT_FMT_MEDIUM, + CMIT_FMT_DEFAULT = CMIT_FMT_MEDIUM, + CMIT_FMT_SHORT +}; + +extern unsigned long pretty_print_commit(enum cmit_fmt fmt, const char *msg, unsigned long len, char *buf, unsigned long space); /** Removes the first commit from a list sorted by date, and adds all diff --git a/diff-tree.c b/diff-tree.c index 3881c23ca3..6f8dc2024c 100644 --- a/diff-tree.c +++ b/diff-tree.c @@ -19,6 +19,7 @@ static int diff_break_opt = -1; static const char *orderfile = NULL; static const char *header = NULL; static const char *header_prefix = ""; +static enum cmit_fmt commit_format = CMIT_FMT_RAW; // What paths are we interested in? static int nr_paths = 0; @@ -321,7 +322,7 @@ static char *generate_header(const char *commit, const char *parent, const char offset = sprintf(this_header, "%s%s (from %s)\n", header_prefix, commit, parent); if (verbose_header) { - offset += pretty_print_commit(msg, len, this_header + offset, sizeof(this_header) - offset); + offset += pretty_print_commit(commit_format, msg, len, this_header + offset, sizeof(this_header) - offset); this_header[offset++] = '\n'; this_header[offset++] = 0; } diff --git a/rev-list.c b/rev-list.c index cbfc5c439d..2b098c1e88 100644 --- a/rev-list.c +++ b/rev-list.c @@ -15,12 +15,12 @@ static const char rev_list_usage[] = static int verbose_header = 0; static int show_parents = 0; -static int pretty_print = 0; static int hdr_termination = 0; static const char *prefix = ""; static unsigned long max_age = -1; static unsigned long min_age = -1; static int max_count = -1; +static enum cmit_fmt commit_format = CMIT_FMT_RAW; static void show_commit(struct commit *commit) { @@ -34,13 +34,9 @@ static void show_commit(struct commit *commit) } putchar('\n'); if (verbose_header) { - const char *buf = commit->buffer; - if (pretty_print) { - static char pretty_header[16384]; - pretty_print_commit(commit->buffer, ~0, pretty_header, sizeof(pretty_header)); - buf = pretty_header; - } - printf("%s%c", buf, hdr_termination); + static char pretty_header[16384]; + pretty_print_commit(commit_format, commit->buffer, ~0, pretty_header, sizeof(pretty_header)); + printf("%s%c", pretty_header, hdr_termination); } } @@ -103,6 +99,20 @@ struct commit_list *limit_list(struct commit_list *list) return newlist; } +static enum cmit_fmt get_commit_format(const char *arg) +{ + if (!*arg) + return CMIT_FMT_DEFAULT; + if (!strcmp(arg, "=raw")) + return CMIT_FMT_RAW; + if (!strcmp(arg, "=medium")) + return CMIT_FMT_MEDIUM; + if (!strcmp(arg, "=short")) + return CMIT_FMT_SHORT; + usage(rev_list_usage); +} + + int main(int argc, char **argv) { struct commit_list *list = NULL; @@ -130,9 +140,9 @@ int main(int argc, char **argv) verbose_header = 1; continue; } - if (!strcmp(arg, "--pretty")) { + if (!strncmp(arg, "--pretty", 8)) { + commit_format = get_commit_format(arg+8); verbose_header = 1; - pretty_print = 1; hdr_termination = '\n'; prefix = "commit "; continue;