From b8ec59234ba2c1833e29eece9ed87f7a471cbae2 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sun, 22 Oct 2006 13:23:31 +0200 Subject: Build in shortlog [jc: with minimum squelching of compiler warning under "-pedantic" compilation options.] Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-shortlog.c | 302 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 302 insertions(+) create mode 100644 builtin-shortlog.c (limited to 'builtin-shortlog.c') diff --git a/builtin-shortlog.c b/builtin-shortlog.c new file mode 100644 index 0000000000..48a2a0b0d3 --- /dev/null +++ b/builtin-shortlog.c @@ -0,0 +1,302 @@ +#include "builtin.h" +#include "cache.h" +#include "commit.h" +#include "diff.h" +#include "path-list.h" +#include "revision.h" +#include + +static const char shortlog_usage[] = +"git-shortlog [-n] [-s] [... ]\n"; + +static int compare_by_number(const void *a1, const void *a2) +{ + const struct path_list_item *i1 = a1, *i2 = a2; + const struct path_list *l1 = i1->util, *l2 = i2->util; + + if (l1->nr < l2->nr) + return -1; + else if (l1->nr == l2->nr) + return 0; + else + return +1; +} + +static struct path_list_item mailmap_list[] = { + { "R.Marek@sh.cvut.cz", (void*)"Rudolf Marek" }, + { "Ralf.Wildenhues@gmx.de", (void*)"Ralf Wildenhues" }, + { "aherrman@de.ibm.com", (void*)"Andreas Herrmann" }, + { "akpm@osdl.org", (void*)"Andrew Morton" }, + { "andrew.vasquez@qlogic.com", (void*)"Andrew Vasquez" }, + { "aquynh@gmail.com", (void*)"Nguyen Anh Quynh" }, + { "axboe@suse.de", (void*)"Jens Axboe" }, + { "blaisorblade@yahoo.it", (void*)"Paolo 'Blaisorblade' Giarrusso" }, + { "bunk@stusta.de", (void*)"Adrian Bunk" }, + { "domen@coderock.org", (void*)"Domen Puncer" }, + { "dougg@torque.net", (void*)"Douglas Gilbert" }, + { "dwmw2@shinybook.infradead.org", (void*)"David Woodhouse" }, + { "ecashin@coraid.com", (void*)"Ed L Cashin" }, + { "felix@derklecks.de", (void*)"Felix Moeller" }, + { "fzago@systemfabricworks.com", (void*)"Frank Zago" }, + { "gregkh@suse.de", (void*)"Greg Kroah-Hartman" }, + { "hch@lst.de", (void*)"Christoph Hellwig" }, + { "htejun@gmail.com", (void*)"Tejun Heo" }, + { "jejb@mulgrave.(none)", (void*)"James Bottomley" }, + { "jejb@titanic.il.steeleye.com", (void*)"James Bottomley" }, + { "jgarzik@pretzel.yyz.us", (void*)"Jeff Garzik" }, + { "johnpol@2ka.mipt.ru", (void*)"Evgeniy Polyakov" }, + { "kay.sievers@vrfy.org", (void*)"Kay Sievers" }, + { "minyard@acm.org", (void*)"Corey Minyard" }, + { "mshah@teja.com", (void*)"Mitesh shah" }, + { "pj@ludd.ltu.se", (void*)"Peter A Jonsson" }, + { "rmps@joel.ist.utl.pt", (void*)"Rui Saraiva" }, + { "santtu.hyrkko@gmail.com", (void*)"Santtu Hyrkk,Av(B" }, + { "simon@thekelleys.org.uk", (void*)"Simon Kelley" }, + { "ssant@in.ibm.com", (void*)"Sachin P Sant" }, + { "terra@gnome.org", (void*)"Morten Welinder" }, + { "tony.luck@intel.com", (void*)"Tony Luck" }, + { "welinder@anemone.rentec.com", (void*)"Morten Welinder" }, + { "welinder@darter.rentec.com", (void*)"Morten Welinder" }, + { "welinder@troll.com", (void*)"Morten Welinder" } +}; + +static struct path_list mailmap = { + mailmap_list, + sizeof(mailmap_list) / sizeof(struct path_list_item), 0, 0 +}; + +static int map_email(char *email, char *name, int maxlen) +{ + char *p; + struct path_list_item *item; + + /* autocomplete common developers */ + p = strchr(email, '>'); + if (!p) + return 0; + + *p = '\0'; + item = path_list_lookup(email, &mailmap); + if (item != NULL) { + const char *realname = (const char *)item->util; + strncpy(name, realname, maxlen); + return 1; + } + return 0; +} + +static void insert_author_oneline(struct path_list *list, + const char *author, int authorlen, + const char *oneline, int onelinelen) +{ + const char *dot3 = "/pub/scm/linux/kernel/git/"; + char *buffer, *p; + struct path_list_item *item; + struct path_list *onelines; + + while (authorlen > 0 && isspace(author[authorlen - 1])) + authorlen--; + + buffer = xmalloc(authorlen + 1); + memcpy(buffer, author, authorlen); + buffer[authorlen] = '\0'; + + item = path_list_insert(buffer, list); + if (item->util == NULL) + item->util = xcalloc(1, sizeof(struct path_list)); + else + free(buffer); + + if (!strncmp(oneline, "[PATCH", 6)) { + char *eob = strchr(buffer, ']'); + + while (isspace(eob[1]) && eob[1] != '\n') + eob++; + if (eob - oneline < onelinelen) { + onelinelen -= eob - oneline; + oneline = eob; + } + } + + while (onelinelen > 0 && isspace(oneline[0])) { + oneline++; + onelinelen--; + } + + while (onelinelen > 0 && isspace(oneline[onelinelen - 1])) + onelinelen--; + + buffer = xmalloc(onelinelen + 1); + memcpy(buffer, oneline, onelinelen); + buffer[onelinelen] = '\0'; + + while ((p = strstr(buffer, dot3)) != NULL) { + memcpy(p, "...", 3); + strcpy(p + 2, p + sizeof(dot3) - 1); + } + + + onelines = item->util; + if (onelines->nr >= onelines->alloc) { + onelines->alloc = alloc_nr(onelines->nr); + onelines->items = xrealloc(onelines->items, + onelines->alloc + * sizeof(struct path_list_item)); + } + + onelines->items[onelines->nr].util = NULL; + onelines->items[onelines->nr++].path = buffer; +} + +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') && + !strncmp(buffer + 1, "uthor: ", 7) && + (bob = strchr(buffer + 7, '<')) != NULL) { + char buffer2[1024], offset = 0; + + if (map_email(bob + 1, buffer, sizeof(buffer))) + bob = buffer + strlen(buffer); + else { + offset = 8; + while (isspace(bob[-1])) + bob--; + } + + while (fgets(buffer2, sizeof(buffer2), stdin) && + buffer2[0] != '\n') + ; /* chomp input */ + if (fgets(buffer2, sizeof(buffer2), stdin)) + insert_author_oneline(list, + buffer + offset, + bob - buffer - offset, + buffer2, strlen(buffer2)); + } + } +} + +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) { + char *author = NULL, *oneline, *buffer; + int authorlen = authorlen, onelinelen; + + /* get author and oneline */ + for (buffer = commit->buffer; buffer && *buffer != '\0' && + *buffer != '\n'; ) { + char *eol = strchr(buffer, '\n'); + + if (eol == NULL) + eol = buffer + strlen(buffer); + else + eol++; + + if (!strncmp(buffer, "author ", 7)) { + char *bracket = strchr(buffer, '<'); + + if (bracket == NULL || bracket > eol) + die("Invalid commit buffer: %s", + sha1_to_hex(commit->object.sha1)); + + if (map_email(bracket + 1, scratch, + sizeof(scratch))) { + author = scratch; + authorlen = strlen(scratch); + } else { + while (bracket[-1] == ' ') + bracket--; + + author = buffer + 7; + authorlen = bracket - 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); + } + +} + +int cmd_shortlog(int argc, const char **argv, const char *prefix) +{ + struct rev_info rev; + struct path_list list = { NULL, 0, 0, 1 }; + int i, j, sort_by_number = 0, summary = 0; + + init_revisions(&rev, prefix); + argc = setup_revisions(argc, argv, &rev, NULL); + while (argc > 1) { + if (!strcmp(argv[1], "-n") || !strcmp(argv[1], "--numbered")) + sort_by_number = 1; + else if (!strcmp(argv[1], "-s") || + !strcmp(argv[1], "--summary")) + summary = 1; + else if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) + usage(shortlog_usage); + else + die ("unrecognized argument: %s", argv[1]); + argv++; + argc--; + } + + if (rev.pending.nr == 1) + die ("Need a range!"); + else if (rev.pending.nr == 0) + read_from_stdin(&list); + else + get_from_rev(&rev, &list); + + if (sort_by_number) + qsort(list.items, sizeof(struct path_list_item), list.nr, + compare_by_number); + + for (i = 0; i < list.nr; i++) { + struct path_list *onelines = list.items[i].util; + + printf("%s (%d):\n", list.items[i].path, onelines->nr); + if (!summary) { + for (j = onelines->nr - 1; j >= 0; j--) + printf(" %s\n", onelines->items[j].path); + printf("\n"); + } + + onelines->strdup_paths = 1; + path_list_clear(onelines, 1); + free(onelines); + list.items[i].util = NULL; + } + + list.strdup_paths = 1; + path_list_clear(&list, 1); + + return 0; +} + -- cgit v1.2.1 From 72019cdefeb6b8fd7e8bff37b9c087302a45e29e Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sun, 19 Nov 2006 17:28:25 +0100 Subject: shortlog: do not crash on parsing "[PATCH" Annoyingly, it looked for the closing bracket in the author name instead of in the message, and then accessed the NULL pointer. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-shortlog.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'builtin-shortlog.c') diff --git a/builtin-shortlog.c b/builtin-shortlog.c index 48a2a0b0d3..26212b009c 100644 --- a/builtin-shortlog.c +++ b/builtin-shortlog.c @@ -108,13 +108,15 @@ static void insert_author_oneline(struct path_list *list, free(buffer); if (!strncmp(oneline, "[PATCH", 6)) { - char *eob = strchr(buffer, ']'); - - while (isspace(eob[1]) && eob[1] != '\n') - eob++; - if (eob - oneline < onelinelen) { - onelinelen -= eob - oneline; - oneline = eob; + char *eob = strchr(oneline, ']'); + + if (eob) { + while (isspace(eob[1]) && eob[1] != '\n') + eob++; + if (eob - oneline < onelinelen) { + onelinelen -= eob - oneline; + oneline = eob; + } } } -- cgit v1.2.1 From d8e812502f1c72f5ef542de7eb05874e27f2b086 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sun, 19 Nov 2006 17:28:51 +0100 Subject: shortlog: read mailmap from ./.mailmap again While at it, remove the linux specific mailmap into contrib/mailmap.linux. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-shortlog.c | 81 ++++++++++++++++++++++++++---------------------------- 1 file changed, 39 insertions(+), 42 deletions(-) (limited to 'builtin-shortlog.c') diff --git a/builtin-shortlog.c b/builtin-shortlog.c index 26212b009c..afc945663d 100644 --- a/builtin-shortlog.c +++ b/builtin-shortlog.c @@ -22,48 +22,40 @@ static int compare_by_number(const void *a1, const void *a2) return +1; } -static struct path_list_item mailmap_list[] = { - { "R.Marek@sh.cvut.cz", (void*)"Rudolf Marek" }, - { "Ralf.Wildenhues@gmx.de", (void*)"Ralf Wildenhues" }, - { "aherrman@de.ibm.com", (void*)"Andreas Herrmann" }, - { "akpm@osdl.org", (void*)"Andrew Morton" }, - { "andrew.vasquez@qlogic.com", (void*)"Andrew Vasquez" }, - { "aquynh@gmail.com", (void*)"Nguyen Anh Quynh" }, - { "axboe@suse.de", (void*)"Jens Axboe" }, - { "blaisorblade@yahoo.it", (void*)"Paolo 'Blaisorblade' Giarrusso" }, - { "bunk@stusta.de", (void*)"Adrian Bunk" }, - { "domen@coderock.org", (void*)"Domen Puncer" }, - { "dougg@torque.net", (void*)"Douglas Gilbert" }, - { "dwmw2@shinybook.infradead.org", (void*)"David Woodhouse" }, - { "ecashin@coraid.com", (void*)"Ed L Cashin" }, - { "felix@derklecks.de", (void*)"Felix Moeller" }, - { "fzago@systemfabricworks.com", (void*)"Frank Zago" }, - { "gregkh@suse.de", (void*)"Greg Kroah-Hartman" }, - { "hch@lst.de", (void*)"Christoph Hellwig" }, - { "htejun@gmail.com", (void*)"Tejun Heo" }, - { "jejb@mulgrave.(none)", (void*)"James Bottomley" }, - { "jejb@titanic.il.steeleye.com", (void*)"James Bottomley" }, - { "jgarzik@pretzel.yyz.us", (void*)"Jeff Garzik" }, - { "johnpol@2ka.mipt.ru", (void*)"Evgeniy Polyakov" }, - { "kay.sievers@vrfy.org", (void*)"Kay Sievers" }, - { "minyard@acm.org", (void*)"Corey Minyard" }, - { "mshah@teja.com", (void*)"Mitesh shah" }, - { "pj@ludd.ltu.se", (void*)"Peter A Jonsson" }, - { "rmps@joel.ist.utl.pt", (void*)"Rui Saraiva" }, - { "santtu.hyrkko@gmail.com", (void*)"Santtu Hyrkk,Av(B" }, - { "simon@thekelleys.org.uk", (void*)"Simon Kelley" }, - { "ssant@in.ibm.com", (void*)"Sachin P Sant" }, - { "terra@gnome.org", (void*)"Morten Welinder" }, - { "tony.luck@intel.com", (void*)"Tony Luck" }, - { "welinder@anemone.rentec.com", (void*)"Morten Welinder" }, - { "welinder@darter.rentec.com", (void*)"Morten Welinder" }, - { "welinder@troll.com", (void*)"Morten Welinder" } -}; - -static struct path_list mailmap = { - mailmap_list, - sizeof(mailmap_list) / sizeof(struct path_list_item), 0, 0 -}; +static struct path_list mailmap = {NULL, 0, 0, 0}; + +static int read_mailmap(const char *filename) +{ + char buffer[1024]; + FILE *f = fopen(filename, "r"); + + if (f == NULL) + return 1; + while (fgets(buffer, sizeof(buffer), f) != NULL) { + char *end_of_name, *left_bracket, *right_bracket; + char *name, *email; + if (buffer[0] == '#') + continue; + if ((left_bracket = strchr(buffer, '<')) == NULL) + continue; + if ((right_bracket = strchr(left_bracket + 1, '>')) == NULL) + continue; + if (right_bracket == left_bracket + 1) + continue; + for (end_of_name = left_bracket; end_of_name != buffer + && isspace(end_of_name[-1]); end_of_name--) + /* keep on looking */ + if (end_of_name == buffer) + continue; + name = xmalloc(end_of_name - buffer + 1); + strlcpy(name, buffer, end_of_name - buffer + 1); + email = xmalloc(right_bracket - left_bracket); + strlcpy(email, left_bracket + 1, right_bracket - left_bracket); + path_list_insert(email, &mailmap)->util = name; + } + fclose(f); + return 0; +} static int map_email(char *email, char *name, int maxlen) { @@ -269,6 +261,9 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix) argc--; } + if (!access(".mailmap", R_OK)) + read_mailmap(".mailmap"); + if (rev.pending.nr == 1) die ("Need a range!"); else if (rev.pending.nr == 0) @@ -298,6 +293,8 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix) list.strdup_paths = 1; path_list_clear(&list, 1); + mailmap.strdup_paths = 1; + path_list_clear(&mailmap, 1); return 0; } -- cgit v1.2.1 From 549652361b7fea5a5e9046571c9f0bc4a7d5d6ef Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sun, 19 Nov 2006 17:29:14 +0100 Subject: shortlog: handle email addresses case-insensitively Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-shortlog.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'builtin-shortlog.c') diff --git a/builtin-shortlog.c b/builtin-shortlog.c index afc945663d..4775c110ff 100644 --- a/builtin-shortlog.c +++ b/builtin-shortlog.c @@ -34,6 +34,7 @@ static int read_mailmap(const char *filename) while (fgets(buffer, sizeof(buffer), f) != NULL) { char *end_of_name, *left_bracket, *right_bracket; char *name, *email; + int i; if (buffer[0] == '#') continue; if ((left_bracket = strchr(buffer, '<')) == NULL) @@ -50,7 +51,9 @@ static int read_mailmap(const char *filename) name = xmalloc(end_of_name - buffer + 1); strlcpy(name, buffer, end_of_name - buffer + 1); email = xmalloc(right_bracket - left_bracket); - strlcpy(email, left_bracket + 1, right_bracket - left_bracket); + for (i = 0; i < right_bracket - left_bracket - 1; i++) + email[i] = tolower(left_bracket[i + 1]); + email[right_bracket - left_bracket - 1] = '\0'; path_list_insert(email, &mailmap)->util = name; } fclose(f); @@ -68,6 +71,9 @@ static int map_email(char *email, char *name, int maxlen) return 0; *p = '\0'; + /* downcase the email address */ + for (p = email; *p; p++) + *p = tolower(*p); item = path_list_lookup(email, &mailmap); if (item != NULL) { const char *realname = (const char *)item->util; -- cgit v1.2.1 From 6d6ab6104a5055b9f66cc9a80d55d2ef59d0763c Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 21 Nov 2006 21:12:06 +0100 Subject: shortlog: fix "-n" Since it is now a builtin optionally taking a range, we have to parse the options before the rev machinery, to be able to shadow the short hand "-n" for "--max-count". Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-shortlog.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'builtin-shortlog.c') diff --git a/builtin-shortlog.c b/builtin-shortlog.c index 4775c110ff..1456e1a191 100644 --- a/builtin-shortlog.c +++ b/builtin-shortlog.c @@ -15,11 +15,11 @@ static int compare_by_number(const void *a1, const void *a2) const struct path_list *l1 = i1->util, *l2 = i2->util; if (l1->nr < l2->nr) - return -1; + return 1; else if (l1->nr == l2->nr) return 0; else - return +1; + return -1; } static struct path_list mailmap = {NULL, 0, 0, 0}; @@ -251,8 +251,7 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix) struct path_list list = { NULL, 0, 0, 1 }; int i, j, sort_by_number = 0, summary = 0; - init_revisions(&rev, prefix); - argc = setup_revisions(argc, argv, &rev, NULL); + /* since -n is a shadowed rev argument, parse our args first */ while (argc > 1) { if (!strcmp(argv[1], "-n") || !strcmp(argv[1], "--numbered")) sort_by_number = 1; @@ -262,10 +261,14 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix) else if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) usage(shortlog_usage); else - die ("unrecognized argument: %s", argv[1]); + break; argv++; argc--; } + init_revisions(&rev, prefix); + argc = setup_revisions(argc, argv, &rev, NULL); + if (argc > 1) + die ("unrecognized argument: %s", argv[1]); if (!access(".mailmap", R_OK)) read_mailmap(".mailmap"); @@ -278,7 +281,7 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix) get_from_rev(&rev, &list); if (sort_by_number) - qsort(list.items, sizeof(struct path_list_item), list.nr, + qsort(list.items, list.nr, sizeof(struct path_list_item), compare_by_number); for (i = 0; i < list.nr; i++) { -- cgit v1.2.1 From ac60c94d74ff3341a5175ca865fd52a0a0189146 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Tue, 21 Nov 2006 15:49:45 -0500 Subject: builtin git-shortlog is broken Another small patch to fix the output result to be conform with the perl version. Signed-off-by: Nicolas Pitre Acked-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-shortlog.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'builtin-shortlog.c') diff --git a/builtin-shortlog.c b/builtin-shortlog.c index 1456e1a191..b760b477ea 100644 --- a/builtin-shortlog.c +++ b/builtin-shortlog.c @@ -7,7 +7,7 @@ #include static const char shortlog_usage[] = -"git-shortlog [-n] [-s] [... ]\n"; +"git-shortlog [-n] [-s] [... ]"; static int compare_by_number(const void *a1, const void *a2) { @@ -287,8 +287,10 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix) for (i = 0; i < list.nr; i++) { struct path_list *onelines = list.items[i].util; - printf("%s (%d):\n", list.items[i].path, onelines->nr); - if (!summary) { + if (summary) { + printf("%s: %d\n", list.items[i].path, onelines->nr); + } else { + printf("%s (%d):\n", list.items[i].path, onelines->nr); for (j = onelines->nr - 1; j >= 0; j--) printf(" %s\n", onelines->items[j].path); printf("\n"); -- cgit v1.2.1 From c95044d4f3c98b52f16e32cfe09f3ff988a80d2a Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 25 Nov 2006 00:01:27 -0800 Subject: git-shortlog: fix common repository prefix abbreviation. The code to abbreviate the common repository prefix was totally borked. Signed-off-by: Junio C Hamano --- builtin-shortlog.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'builtin-shortlog.c') diff --git a/builtin-shortlog.c b/builtin-shortlog.c index b760b477ea..bdd952c252 100644 --- a/builtin-shortlog.c +++ b/builtin-shortlog.c @@ -130,12 +130,17 @@ static void insert_author_oneline(struct path_list *list, memcpy(buffer, oneline, onelinelen); buffer[onelinelen] = '\0'; - while ((p = strstr(buffer, dot3)) != NULL) { - memcpy(p, "...", 3); - strcpy(p + 2, p + sizeof(dot3) - 1); + if (dot3) { + int dot3len = strlen(dot3); + if (dot3len > 5) { + while ((p = strstr(buffer, dot3)) != NULL) { + int taillen = strlen(p) - dot3len; + memcpy(p, "/.../", 5); + memmove(p + 5, p + dot3len, taillen + 1); + } + } } - onelines = item->util; if (onelines->nr >= onelines->alloc) { onelines->alloc = alloc_nr(onelines->nr); -- cgit v1.2.1 From 7595e2ee6ef9b35ebc8dc45543723e1d89765ce3 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 25 Nov 2006 00:07:54 -0800 Subject: git-shortlog: make common repository prefix configurable with .mailmap The code had "/pub/scm/linux/kernel/git/" hardcoded which was too specific to the kernel project. With this, a line in the .mailmap file: # repo-abbrev: /pub/scm/linux/kernel/git/ can be used to cause the substring to be abbreviated to /.../ on the title line of the commit message. Signed-off-by: Junio C Hamano --- builtin-shortlog.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'builtin-shortlog.c') diff --git a/builtin-shortlog.c b/builtin-shortlog.c index bdd952c252..b5b13dee3b 100644 --- a/builtin-shortlog.c +++ b/builtin-shortlog.c @@ -9,6 +9,8 @@ static const char shortlog_usage[] = "git-shortlog [-n] [-s] [... ]"; +static char *common_repo_prefix; + static int compare_by_number(const void *a1, const void *a2) { const struct path_list_item *i1 = a1, *i2 = a2; @@ -35,8 +37,26 @@ static int read_mailmap(const char *filename) char *end_of_name, *left_bracket, *right_bracket; char *name, *email; int i; - if (buffer[0] == '#') + if (buffer[0] == '#') { + static const char abbrev[] = "# repo-abbrev:"; + int abblen = sizeof(abbrev) - 1; + int len = strlen(buffer); + + if (len && buffer[len - 1] == '\n') + buffer[--len] = 0; + if (!strncmp(buffer, abbrev, abblen)) { + char *cp; + + if (common_repo_prefix) + free(common_repo_prefix); + common_repo_prefix = xmalloc(len); + + for (cp = buffer + abblen; isspace(*cp); cp++) + ; /* nothing */ + strcpy(common_repo_prefix, cp); + } continue; + } if ((left_bracket = strchr(buffer, '<')) == NULL) continue; if ((right_bracket = strchr(left_bracket + 1, '>')) == NULL) @@ -87,7 +107,7 @@ static void insert_author_oneline(struct path_list *list, const char *author, int authorlen, const char *oneline, int onelinelen) { - const char *dot3 = "/pub/scm/linux/kernel/git/"; + const char *dot3 = common_repo_prefix; char *buffer, *p; struct path_list_item *item; struct path_list *onelines; -- cgit v1.2.1 From c3e43938839752b48ff3a36862ae59f1cd1e630d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Tue, 28 Nov 2006 22:49:17 +0100 Subject: shortlog: remove range check Don't force the user to specify more than one revision parameter, thus making git-shortlog behave more like git-log. 'git-shortlog master' will now produce the expected results; the other end of the range simply is the (oldest) root commit. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- builtin-shortlog.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'builtin-shortlog.c') diff --git a/builtin-shortlog.c b/builtin-shortlog.c index b5b13dee3b..f1124e261b 100644 --- a/builtin-shortlog.c +++ b/builtin-shortlog.c @@ -298,9 +298,7 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix) if (!access(".mailmap", R_OK)) read_mailmap(".mailmap"); - if (rev.pending.nr == 1) - die ("Need a range!"); - else if (rev.pending.nr == 0) + if (rev.pending.nr == 0) read_from_stdin(&list); else get_from_rev(&rev, &list); -- cgit v1.2.1 From 90ffefe564cd849f88b1d1b5817eb25e3d57521b Mon Sep 17 00:00:00 2001 From: Jeff King Date: Fri, 8 Dec 2006 23:04:21 -0500 Subject: shortlog: fix segfault on empty authorname The old code looked backwards from the email address to parse the name, allowing an arbitrary number of spaces between the two. However, in the case of no name, we looked back too far to the 'author' (or 'Author:') header. Instead, remove at most one space between name and address. The bug was triggered by commit febf7ea4bed from linux-2.6. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin-shortlog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'builtin-shortlog.c') diff --git a/builtin-shortlog.c b/builtin-shortlog.c index f1124e261b..7a2ddfe797 100644 --- a/builtin-shortlog.c +++ b/builtin-shortlog.c @@ -188,7 +188,7 @@ static void read_from_stdin(struct path_list *list) bob = buffer + strlen(buffer); else { offset = 8; - while (isspace(bob[-1])) + if (isspace(bob[-1])) bob--; } @@ -236,7 +236,7 @@ static void get_from_rev(struct rev_info *rev, struct path_list *list) author = scratch; authorlen = strlen(scratch); } else { - while (bracket[-1] == ' ') + if (bracket[-1] == ' ') bracket--; author = buffer + 7; -- cgit v1.2.1 From bca73251da5cc3e4bea71e28e0096a5cd662bbd9 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 10 Dec 2006 15:55:07 -0800 Subject: shortlog: remove "[PATCH]" prefix from shortlog output Originally noticed by Nicolas Pitre; the real cause was the code was prepared to deal with [PATCH] (and [PATCH n/m whatever]) prefixes but forgot that the string can be indented while acting as a filter. Signed-off-by: Junio C Hamano --- builtin-shortlog.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'builtin-shortlog.c') diff --git a/builtin-shortlog.c b/builtin-shortlog.c index 7a2ddfe797..3322c3a2ee 100644 --- a/builtin-shortlog.c +++ b/builtin-shortlog.c @@ -195,11 +195,17 @@ static void read_from_stdin(struct path_list *list) while (fgets(buffer2, sizeof(buffer2), stdin) && buffer2[0] != '\n') ; /* chomp input */ - if (fgets(buffer2, sizeof(buffer2), stdin)) + 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, strlen(buffer2)); + buffer2 + i, l2 - i); + } } } } -- cgit v1.2.1 From 6f9872582246b9b8ee4bdc9f6a563b409aab1ecb Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 10 Dec 2006 15:51:54 -0800 Subject: shortlog: fix segfault on empty authorname The old code looked backwards from the email address to parse the name, allowing an arbitrary number of spaces between the two. However, in the case of no name, we looked back too far to the 'author' (or 'Author:') header. The bug was triggered by commit febf7ea4bed from linux-2.6. Jeff King originally fixed it by looking back only one character; Johannes Schindelin pointed out that we could try harder while at it to cope with commits with broken headers. Signed-off-by: Junio C Hamano --- builtin-shortlog.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'builtin-shortlog.c') diff --git a/builtin-shortlog.c b/builtin-shortlog.c index 3322c3a2ee..3fc43dd7dd 100644 --- a/builtin-shortlog.c +++ b/builtin-shortlog.c @@ -188,7 +188,8 @@ static void read_from_stdin(struct path_list *list) bob = buffer + strlen(buffer); else { offset = 8; - if (isspace(bob[-1])) + while (buffer + offset < bob && + isspace(bob[-1])) bob--; } -- cgit v1.2.1 From 85023577a8f4b540aa64aa37f6f44578c0c305a3 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 19 Dec 2006 14:34:12 -0800 Subject: simplify inclusion of system header files. This is a mechanical clean-up of the way *.c files include system header files. (1) sources under compat/, platform sha-1 implementations, and xdelta code are exempt from the following rules; (2) the first #include must be "git-compat-util.h" or one of our own header file that includes it first (e.g. config.h, builtin.h, pkt-line.h); (3) system headers that are included in "git-compat-util.h" need not be included in individual C source files. (4) "git-compat-util.h" does not have to include subsystem specific header files (e.g. expat.h). Signed-off-by: Junio C Hamano --- builtin-shortlog.c | 1 - 1 file changed, 1 deletion(-) (limited to 'builtin-shortlog.c') diff --git a/builtin-shortlog.c b/builtin-shortlog.c index 3fc43dd7dd..edb40429ec 100644 --- a/builtin-shortlog.c +++ b/builtin-shortlog.c @@ -4,7 +4,6 @@ #include "diff.h" #include "path-list.h" #include "revision.h" -#include static const char shortlog_usage[] = "git-shortlog [-n] [-s] [... ]"; -- cgit v1.2.1