X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=builtin-shortlog.c;h=fa8bc7d02a2268d99dcc829cb3adbee10c949306;hb=41e2edf41a6d501f1b8beca7f1f0bcbe9296dcc2;hp=3fe754677d3f7ab11419a04dd828c70b5958ed87;hpb=fb5fd011482b5aa0b340a4a5bd9192c0efc1edb7;p=git.git diff --git a/builtin-shortlog.c b/builtin-shortlog.c index 3fe754677..fa8bc7d02 100644 --- a/builtin-shortlog.c +++ b/builtin-shortlog.c @@ -8,9 +8,10 @@ #include "mailmap.h" static const char shortlog_usage[] = -"git-shortlog [-n] [-s] [... ]"; +"git-shortlog [-n] [-s] [-e] [... ]"; static char *common_repo_prefix; +static int email; static int compare_by_number(const void *a1, const void *a2) { @@ -27,45 +28,68 @@ static int compare_by_number(const void *a1, const void *a2) static struct path_list mailmap = {NULL, 0, 0, 0}; -static void insert_author_oneline(struct path_list *list, - const char *author, int authorlen, - const char *oneline, int onelinelen) +static void insert_one_record(struct path_list *list, + const char *author, + const char *oneline) { const char *dot3 = common_repo_prefix; char *buffer, *p; struct path_list_item *item; struct path_list *onelines; + char namebuf[1024]; + size_t len; + const char *eol; + const char *boemail, *eoemail; + + boemail = strchr(author, '<'); + if (!boemail) + return; + eoemail = strchr(boemail, '>'); + if (!eoemail) + return; + if (!map_email(&mailmap, boemail+1, namebuf, sizeof(namebuf))) { + while (author < boemail && isspace(*author)) + author++; + for (len = 0; + len < sizeof(namebuf) - 1 && author + len < boemail; + len++) + namebuf[len] = author[len]; + while (0 < len && isspace(namebuf[len-1])) + len--; + namebuf[len] = '\0'; + } + else + len = strlen(namebuf); - while (authorlen > 0 && isspace(author[authorlen - 1])) - authorlen--; + if (email) { + size_t room = sizeof(namebuf) - len - 1; + int maillen = eoemail - boemail + 1; + snprintf(namebuf + len, room, " %.*s", maillen, boemail); + } - buffer = xmemdupz(author, authorlen); + buffer = xstrdup(namebuf); item = path_list_insert(buffer, list); if (item->util == NULL) item->util = xcalloc(1, sizeof(struct path_list)); else free(buffer); + eol = strchr(oneline, '\n'); + if (!eol) + eol = oneline + strlen(oneline); + while (*oneline && isspace(*oneline) && *oneline != '\n') + oneline++; if (!prefixcmp(oneline, "[PATCH")) { char *eob = strchr(oneline, ']'); - - if (eob) { - while (isspace(eob[1]) && eob[1] != '\n') - eob++; - if (eob - oneline < onelinelen) { - onelinelen -= eob - oneline; - oneline = eob; - } - } + if (eob && (!eol || eob < eol)) + oneline = eob + 1; } - - while (onelinelen > 0 && isspace(oneline[0])) { + while (*oneline && isspace(*oneline) && *oneline != '\n') oneline++; - onelinelen--; - } - while (onelinelen > 0 && isspace(oneline[onelinelen - 1])) - onelinelen--; - buffer = xmemdupz(oneline, onelinelen); + len = eol - oneline; + while (len && isspace(oneline[len-1])) + len--; + buffer = xmemdupz(oneline, len); if (dot3) { int dot3len = strlen(dot3); @@ -92,55 +116,32 @@ static void insert_author_oneline(struct path_list *list, static void read_from_stdin(struct path_list *list) { - char buffer[1024]; - - while (fgets(buffer, sizeof(buffer), stdin) != NULL) { - char *bob; - if ((buffer[0] == 'A' || buffer[0] == 'a') && - !prefixcmp(buffer + 1, "uthor: ") && - (bob = strchr(buffer + 7, '<')) != NULL) { - char buffer2[1024], offset = 0; - - if (map_email(&mailmap, bob + 1, buffer, sizeof(buffer))) - bob = buffer + strlen(buffer); - else { - offset = 8; - while (buffer + offset < bob && - isspace(bob[-1])) - bob--; - } - - while (fgets(buffer2, sizeof(buffer2), stdin) && - buffer2[0] != '\n') - ; /* chomp input */ - if (fgets(buffer2, sizeof(buffer2), stdin)) { - int l2 = strlen(buffer2); - int i; - for (i = 0; i < l2; i++) - if (!isspace(buffer2[i])) - break; - insert_author_oneline(list, - buffer + offset, - bob - buffer - offset, - buffer2 + i, l2 - i); - } - } + char author[1024], oneline[1024]; + + while (fgets(author, sizeof(author), stdin) != NULL) { + if (!(author[0] == 'A' || author[0] == 'a') || + prefixcmp(author + 1, "uthor: ")) + continue; + while (fgets(oneline, sizeof(oneline), stdin) && + oneline[0] != '\n') + ; /* discard headers */ + while (fgets(oneline, sizeof(oneline), stdin) && + oneline[0] == '\n') + ; /* discard blanks */ + insert_one_record(list, author + 8, oneline); } } static void get_from_rev(struct rev_info *rev, struct path_list *list) { - char scratch[1024]; struct commit *commit; prepare_revision_walk(rev); while ((commit = get_revision(rev)) != NULL) { - const char *author = NULL, *oneline, *buffer; - int authorlen = authorlen, onelinelen; + const char *author = NULL, *buffer; - /* get author and oneline */ - for (buffer = commit->buffer; buffer && *buffer != '\0' && - *buffer != '\n'; ) { + buffer = commit->buffer; + while (*buffer && *buffer != '\n') { const char *eol = strchr(buffer, '\n'); if (eol == NULL) @@ -148,50 +149,17 @@ static void get_from_rev(struct rev_info *rev, struct path_list *list) else eol++; - if (!prefixcmp(buffer, "author ")) { - char *bracket = strchr(buffer, '<'); - - if (bracket == NULL || bracket > eol) - die("Invalid commit buffer: %s", - sha1_to_hex(commit->object.sha1)); - - if (map_email(&mailmap, bracket + 1, scratch, - sizeof(scratch))) { - author = scratch; - authorlen = strlen(scratch); - } else { - if (bracket[-1] == ' ') - bracket--; - - author = buffer + 7; - authorlen = bracket - buffer - 7; - } - } + if (!prefixcmp(buffer, "author ")) + author = buffer + 7; buffer = eol; } - - if (author == NULL) - die ("Missing author: %s", - sha1_to_hex(commit->object.sha1)); - - if (buffer == NULL || *buffer == '\0') { - oneline = ""; - onelinelen = sizeof(oneline) + 1; - } else { - char *eol; - - oneline = buffer + 1; - eol = strchr(oneline, '\n'); - if (eol == NULL) - onelinelen = strlen(oneline); - else - onelinelen = eol - oneline; - } - - insert_author_oneline(list, - author, authorlen, oneline, onelinelen); + if (!author) + die("Missing author: %s", + sha1_to_hex(commit->object.sha1)); + if (*buffer) + buffer++; + insert_one_record(list, author, !*buffer ? "" : buffer); } - } static int parse_uint(char const **arg, int comma) @@ -260,6 +228,9 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix) else if (!strcmp(argv[1], "-s") || !strcmp(argv[1], "--summary")) summary = 1; + else if (!strcmp(argv[1], "-e") || + !strcmp(argv[1], "--email")) + email = 1; else if (!prefixcmp(argv[1], "-w")) { wrap_lines = 1; parse_wrap_args(argv[1], &in1, &in2, &wrap); @@ -278,9 +249,10 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix) read_mailmap(&mailmap, ".mailmap", &common_repo_prefix); + /* assume HEAD if from a tty */ + if (!rev.pending.nr && isatty(0)) + add_head_to_pending(&rev); if (rev.pending.nr == 0) { - if (isatty(0)) - fprintf(stderr, "(reading log to summarize from standard input)\n"); read_from_stdin(&list); } else @@ -294,7 +266,7 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix) struct path_list *onelines = list.items[i].util; if (summary) { - printf("%s: %d\n", list.items[i].path, onelines->nr); + printf("%6d\t%s\n", onelines->nr, list.items[i].path); } else { printf("%s (%d):\n", list.items[i].path, onelines->nr); for (j = onelines->nr - 1; j >= 0; j--) {