{"thread":{"id":"32349","subject":"[PATCH v2 1/7] Use split_ident_line to parse author and committer","startedAt":"2012-12-15T18:05:47Z","lastAt":"2012-12-15T20:18:38Z","messageCount":9,"participants":["Antoine Pelisse","Junio C Hamano"],"isPatch":true,"patchVersion":2,"patchTotal":7},"messages":[{"id":"204921","messageId":"1355594754-27589-1-git-send-email-apelisse@gmail.com","threadId":"32349","inReplyTo":null,"subject":"[PATCH v2 0/7] Allow git log to use mailmap file","fromName":"Antoine Pelisse","fromEmail":"apelisse@gmail.com","sentAt":"2012-12-15T18:05:47Z","receivedAt":"2012-12-15T18:05:47Z","isPatch":true,"sender":{"key":"apelisse@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1929644?v=4"},"body":"Implement the feature suggested by Rich Mindwinter and Junio C Hamano\n(and following his advices)\n\n\n\nAllows git show/log commands to map author and committer\nnames and emails using the mailmap file.\n\nUpdates related to this second series:\n  - All tests are successful after each patch\n  - Use split_ident_line in shortlog.c\n  - Documentation has been added to git-log.txt\n  - Test has been added to check that we use the file\n  - Lots of improvements in the way strbufs are used\n  - New interface to map_user()\n  - Bunch of other fixes\n\ngit glog --committer/--author is still not looking for mailmap user\nnames.\n\nAntoine Pelisse (7):\n  Use split_ident_line to parse author and committer\n  mailmap: Remove buffer length limit in map_user\n  mailmap: Simplify map_user() interface\n  mailmap: Add mailmap structure to rev_info and pp\n  pretty: Use mailmap to display username and email\n  log: Add --use-mailmap option\n  test: Add test for --use-mailmap option\n\n Documentation/git-log.txt |    5 ++\n builtin/blame.c           |  189 +++++++++++++++++++++------------------------\n builtin/log.c             |    9 ++-\n builtin/shortlog.c        |   53 ++++---------\n commit.h                  |    1 +\n log-tree.c                |    1 +\n mailmap.c                 |   56 ++++++--------\n mailmap.h                 |    4 +-\n pretty.c                  |  111 ++++++++++++++------------\n revision.h                |    1 +\n t/t4203-mailmap.sh        |   14 ++++\n 11 files changed, 219 insertions(+), 225 deletions(-)\n\n--\n1.7.9.5\n"},{"id":"204919","messageId":"1355594754-27589-2-git-send-email-apelisse@gmail.com","threadId":"32349","inReplyTo":"1355594754-27589-1-git-send-email-apelisse@gmail.com","subject":"[PATCH v2 1/7] Use split_ident_line to parse author and committer","fromName":"Antoine Pelisse","fromEmail":"apelisse@gmail.com","sentAt":"2012-12-15T18:05:48Z","receivedAt":"2012-12-15T18:05:48Z","isPatch":true,"sender":{"key":"apelisse@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1929644?v=4"},"body":"Currently blame.c::get_acline, pretty.c::pp_user_info() and\nshortlog.c::insert_one_record are parsing author name, email, time and\ntz themselves.\n\nUse ident.c::split_ident_line for better code reuse.\n\nSigned-off-by: Antoine Pelisse <apelisse@gmail.com>\n---\n builtin/blame.c    |   59 +++++++++++++++++++---------------------------------\n builtin/shortlog.c |   36 +++++++++-----------------------\n pretty.c           |   35 ++++++++++++++++++-------------\n 3 files changed, 52 insertions(+), 78 deletions(-)\n\ndiff --git a/builtin/blame.c b/builtin/blame.c\nindex cfae569..dd4aff9 100644\n--- a/builtin/blame.c\n+++ b/builtin/blame.c\n@@ -1343,8 +1343,9 @@ static void get_ac_line(const char *inbuf, const char *what,\n \t\t\tint mail_len, char *mail,\n \t\t\tunsigned long *time, const char **tz)\n {\n-\tint len, tzlen, maillen;\n-\tchar *tmp, *endp, *timepos, *mailpos;\n+\tstruct ident_split ident;\n+\tint len, tzlen, maillen, namelen;\n+\tchar *tmp, *endp, *mailpos;\n \n \ttmp = strstr(inbuf, what);\n \tif (!tmp)\n@@ -1355,7 +1356,10 @@ static void get_ac_line(const char *inbuf, const char *what,\n \t\tlen = strlen(tmp);\n \telse\n \t\tlen = endp - tmp;\n-\tif (person_len <= len) {\n+\tif (person_len <= len)\n+\t\tgoto error_out;\n+\n+\tif (split_ident_line(&ident, tmp, len)) {\n \terror_out:\n \t\t/* Ugh */\n \t\t*tz = \"(unknown)\";\n@@ -1364,47 +1368,26 @@ static void get_ac_line(const char *inbuf, const char *what,\n \t\t*time = 0;\n \t\treturn;\n \t}\n-\tmemcpy(person, tmp, len);\n \n-\ttmp = person;\n-\ttmp += len;\n-\t*tmp = 0;\n-\twhile (person < tmp && *tmp != ' ')\n-\t\ttmp--;\n-\tif (tmp <= person)\n-\t\tgoto error_out;\n-\t*tz = tmp+1;\n-\ttzlen = (person+len)-(tmp+1);\n+\tnamelen = ident.name_end - ident.name_begin;\n+\tmemcpy(person, ident.name_begin, namelen);\n+\tperson[namelen] = 0;\n \n-\t*tmp = 0;\n-\twhile (person < tmp && *tmp != ' ')\n-\t\ttmp--;\n-\tif (tmp <= person)\n-\t\tgoto error_out;\n-\t*time = strtoul(tmp, NULL, 10);\n-\ttimepos = tmp;\n+\tmaillen = ident.mail_end - ident.mail_begin + 2;\n+\tmemcpy(mail, ident.mail_begin - 1, maillen);\n+\tmail[maillen] = 0;\n \n-\t*tmp = 0;\n-\twhile (person < tmp && !(*tmp == ' ' && tmp[1] == '<'))\n-\t\ttmp--;\n-\tif (tmp <= person)\n-\t\treturn;\n-\tmailpos = tmp + 1;\n-\t*tmp = 0;\n-\tmaillen = timepos - tmp;\n-\tmemcpy(mail, mailpos, maillen);\n+\t*time = strtoul(ident.date_begin, NULL, 10);\n \n-\tif (!mailmap.nr)\n-\t\treturn;\n+\ttzlen = ident.tz_end - ident.tz_begin;\n \n-\t/*\n-\t * mailmap expansion may make the name longer.\n-\t * make room by pushing stuff down.\n-\t */\n-\ttmp = person + person_len - (tzlen + 1);\n-\tmemmove(tmp, *tz, tzlen);\n+\t/* Place tz at the end of person */\n+\t*tz = tmp = person + person_len - (tzlen + 1);\n+\tmemcpy(tmp, ident.tz_begin, tzlen);\n \ttmp[tzlen] = 0;\n-\t*tz = tmp;\n+\n+\tif (!mailmap.nr)\n+\t\treturn;\n \n \t/*\n \t * Now, convert both name and e-mail using mailmap\ndiff --git a/builtin/shortlog.c b/builtin/shortlog.c\nindex b316cf3..03c6cd7 100644\n--- a/builtin/shortlog.c\n+++ b/builtin/shortlog.c\n@@ -40,40 +40,24 @@ static void insert_one_record(struct shortlog *log,\n \tchar emailbuf[1024];\n \tsize_t len;\n \tconst char *eol;\n-\tconst char *boemail, *eoemail;\n \tstruct strbuf subject = STRBUF_INIT;\n+\tstruct ident_split ident;\n \n-\tboemail = strchr(author, '<');\n-\tif (!boemail)\n-\t\treturn;\n-\teoemail = strchr(boemail, '>');\n-\tif (!eoemail)\n+\tif (split_ident_line(&ident, author, strlen(author)))\n \t\treturn;\n \n \t/* copy author name to namebuf, to support matching on both name and email */\n-\tmemcpy(namebuf, author, boemail - author);\n-\tlen = boemail - author;\n-\twhile (len > 0 && isspace(namebuf[len-1]))\n-\t\tlen--;\n+\tlen = ident.name_end - ident.name_begin;\n+\tmemcpy(namebuf, ident.name_begin, len);\n \tnamebuf[len] = 0;\n \n \t/* copy email name to emailbuf, to allow email replacement as well */\n-\tmemcpy(emailbuf, boemail+1, eoemail - boemail);\n-\temailbuf[eoemail - boemail - 1] = 0;\n-\n-\tif (!map_user(&log->mailmap, emailbuf, sizeof(emailbuf), namebuf, sizeof(namebuf))) {\n-\t\twhile (author < boemail && isspace(*author))\n-\t\t\tauthor++;\n-\t\tfor (len = 0;\n-\t\t     len < sizeof(namebuf) - 1 && author + len < boemail;\n-\t\t     len++)\n-\t\t\tnamebuf[len] = author[len];\n-\t\twhile (0 < len && isspace(namebuf[len-1]))\n-\t\t\tlen--;\n-\t\tnamebuf[len] = '\\0';\n-\t}\n-\telse\n-\t\tlen = strlen(namebuf);\n+\tlen = ident.mail_end - ident.mail_begin;\n+\tmemcpy(emailbuf, ident.mail_begin, len);\n+\temailbuf[len] = 0;\n+\n+\tmap_user(&log->mailmap, emailbuf, sizeof(emailbuf), namebuf, sizeof(namebuf));\n+\tlen = strlen(namebuf);\n \n \tif (log->email) {\n \t\tsize_t room = sizeof(namebuf) - len - 1;\ndiff --git a/pretty.c b/pretty.c\nindex 5bdc2e7..350d1df 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -387,29 +387,36 @@ void pp_user_info(const struct pretty_print_context *pp,\n \t\t  const char *what, struct strbuf *sb,\n \t\t  const char *line, const char *encoding)\n {\n+\tstruct ident_split ident;\n+\tint linelen, namelen;\n+\tchar *line_end, *date;\n \tint max_length = 78; /* per rfc2822 */\n-\tchar *date;\n-\tint namelen;\n \tunsigned long time;\n \tint tz;\n \n \tif (pp->fmt == CMIT_FMT_ONELINE)\n \t\treturn;\n-\tdate = strchr(line, '>');\n-\tif (!date)\n+\n+\tline_end = strchr(line, '\\n');\n+\tif (!line_end) {\n+\t\tline_end = strchr(line, '\\0');\n+\t\tif (!line_end)\n+\t\t\treturn;\n+\t}\n+\n+\tlinelen = ++line_end - line;\n+\tif (split_ident_line(&ident, line, linelen))\n \t\treturn;\n-\tnamelen = ++date - line;\n-\ttime = strtoul(date, &date, 10);\n+\n+\tnamelen = ident.mail_end - ident.name_begin + 1;\n+\ttime = strtoul(ident.date_begin, &date, 10);\n \ttz = strtol(date, NULL, 10);\n \n \tif (pp->fmt == CMIT_FMT_EMAIL) {\n-\t\tchar *name_tail = strchr(line, '<');\n \t\tint display_name_length;\n-\t\tif (!name_tail)\n-\t\t\treturn;\n-\t\twhile (line < name_tail && isspace(name_tail[-1]))\n-\t\t\tname_tail--;\n-\t\tdisplay_name_length = name_tail - line;\n+\n+\t\tdisplay_name_length = ident.name_end - ident.name_begin;\n+\n \t\tstrbuf_addstr(sb, \"From: \");\n \t\tif (needs_rfc2047_encoding(line, display_name_length, RFC2047_ADDRESS)) {\n \t\t\tadd_rfc2047(sb, line, display_name_length,\n@@ -427,10 +434,10 @@ void pp_user_info(const struct pretty_print_context *pp,\n \t\t}\n \t\tif (namelen - display_name_length + last_line_length(sb) > max_length) {\n \t\t\tstrbuf_addch(sb, '\\n');\n-\t\t\tif (!isspace(name_tail[0]))\n+\t\t\tif (!isspace(ident.name_end[0]))\n \t\t\t\tstrbuf_addch(sb, ' ');\n \t\t}\n-\t\tstrbuf_add(sb, name_tail, namelen - display_name_length);\n+\t\tstrbuf_add(sb, ident.name_end, namelen - display_name_length);\n \t\tstrbuf_addch(sb, '\\n');\n \t} else {\n \t\tstrbuf_addf(sb, \"%s: %.*s%.*s\\n\", what,\n-- \n1.7.9.5\n"},{"id":"204920","messageId":"1355594754-27589-3-git-send-email-apelisse@gmail.com","threadId":"32349","inReplyTo":"1355594754-27589-1-git-send-email-apelisse@gmail.com","subject":"[PATCH v2 2/7] mailmap: Remove buffer length limit in map_user","fromName":"Antoine Pelisse","fromEmail":"apelisse@gmail.com","sentAt":"2012-12-15T18:05:49Z","receivedAt":"2012-12-15T18:05:49Z","isPatch":true,"sender":{"key":"apelisse@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1929644?v=4"},"body":"Remove the hard limit set by mail buffer in map_user and\nuse the strbuf API to replace it.\n\nSigned-off-by: Antoine Pelisse <apelisse@gmail.com>\n---\n mailmap.c |   17 ++++++-----------\n 1 file changed, 6 insertions(+), 11 deletions(-)\n\ndiff --git a/mailmap.c b/mailmap.c\nindex ea4b471..3bc6491 100644\n--- a/mailmap.c\n+++ b/mailmap.c\n@@ -193,7 +193,7 @@ int map_user(struct string_list *map,\n \tchar *end_of_email;\n \tstruct string_list_item *item;\n \tstruct mailmap_entry *me;\n-\tchar buf[1024], *mailbuf;\n+\tstruct strbuf mailbuf = STRBUF_INIT;\n \tint i;\n \n \t/* figure out space requirement for email */\n@@ -204,18 +204,14 @@ int map_user(struct string_list *map,\n \t\tif (!end_of_email)\n \t\t\treturn 0;\n \t}\n-\tif (end_of_email - email + 1 < sizeof(buf))\n-\t\tmailbuf = buf;\n-\telse\n-\t\tmailbuf = xmalloc(end_of_email - email + 1);\n \n \t/* downcase the email address */\n+\tstrbuf_grow(&mailbuf, end_of_email - email);\n \tfor (i = 0; i < end_of_email - email; i++)\n-\t\tmailbuf[i] = tolower(email[i]);\n-\tmailbuf[i] = 0;\n+\t\tstrbuf_addch(&mailbuf, tolower(email[i]));\n \n-\tdebug_mm(\"map_user: map '%s' <%s>\\n\", name, mailbuf);\n-\titem = string_list_lookup(map, mailbuf);\n+\tdebug_mm(\"map_user: map '%s' <%s>\\n\", name, mailbuf.buf);\n+\titem = string_list_lookup(map, mailbuf.buf);\n \tif (item != NULL) {\n \t\tme = (struct mailmap_entry *)item->util;\n \t\tif (me->namemap.nr) {\n@@ -226,8 +222,7 @@ int map_user(struct string_list *map,\n \t\t\t\titem = subitem;\n \t\t}\n \t}\n-\tif (mailbuf != buf)\n-\t\tfree(mailbuf);\n+\tstrbuf_release(&mailbuf);\n \tif (item != NULL) {\n \t\tstruct mailmap_info *mi = (struct mailmap_info *)item->util;\n \t\tif (mi->name == NULL && (mi->email == NULL || maxlen_email == 0)) {\n-- \n1.7.9.5\n"},{"id":"204922","messageId":"1355594754-27589-4-git-send-email-apelisse@gmail.com","threadId":"32349","inReplyTo":"1355594754-27589-1-git-send-email-apelisse@gmail.com","subject":"[PATCH v2 3/7] mailmap: Simplify map_user() interface","fromName":"Antoine Pelisse","fromEmail":"apelisse@gmail.com","sentAt":"2012-12-15T18:05:50Z","receivedAt":"2012-12-15T18:05:50Z","isPatch":true,"sender":{"key":"apelisse@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1929644?v=4"},"body":"mailmap.c::map_user() is simplified to take two strbuf parameters\ninstead of statically allocated buffers.\n\nThe buffers are still modified in-place, when mapping is required.\n\nIt actually makes things easier for callers:\n - Caller must prepare the call by copying author name and email in\n strbuf (instead of copying in static buffer)\n - Caller can easily manipulate the buffer afterward.\n - Caller doesn't have to call strlen() to calculate the size of the\n new string.\n\nSigned-off-by: Antoine Pelisse <apelisse@gmail.com>\n---\n builtin/blame.c    |  164 +++++++++++++++++++++++++++-------------------------\n builtin/shortlog.c |   31 ++++------\n mailmap.c          |   51 ++++++++--------\n mailmap.h          |    4 +-\n pretty.c           |   40 ++++++-------\n 5 files changed, 139 insertions(+), 151 deletions(-)\n\ndiff --git a/builtin/blame.c b/builtin/blame.c\nindex dd4aff9..8586850 100644\n--- a/builtin/blame.c\n+++ b/builtin/blame.c\n@@ -1321,31 +1321,30 @@ static void pass_blame(struct scoreboard *sb, struct origin *origin, int opt)\n  * Information on commits, used for output.\n  */\n struct commit_info {\n-\tconst char *author;\n-\tconst char *author_mail;\n+\tstruct strbuf author;\n+\tstruct strbuf author_mail;\n \tunsigned long author_time;\n-\tconst char *author_tz;\n+\tstruct strbuf author_tz;\n \n \t/* filled only when asked for details */\n-\tconst char *committer;\n-\tconst char *committer_mail;\n+\tstruct strbuf committer;\n+\tstruct strbuf committer_mail;\n \tunsigned long committer_time;\n-\tconst char *committer_tz;\n+\tstruct strbuf committer_tz;\n \n-\tconst char *summary;\n+\tstruct strbuf summary;\n };\n \n /*\n  * Parse author/committer line in the commit object buffer\n  */\n static void get_ac_line(const char *inbuf, const char *what,\n-\t\t\tint person_len, char *person,\n-\t\t\tint mail_len, char *mail,\n-\t\t\tunsigned long *time, const char **tz)\n+\t\t\tstruct strbuf *name, struct strbuf *mail,\n+\t\t\tunsigned long *time, struct strbuf *tz)\n {\n \tstruct ident_split ident;\n-\tint len, tzlen, maillen, namelen;\n-\tchar *tmp, *endp, *mailpos;\n+\tint len;\n+\tchar *tmp, *endp;\n \n \ttmp = strstr(inbuf, what);\n \tif (!tmp)\n@@ -1356,51 +1355,61 @@ static void get_ac_line(const char *inbuf, const char *what,\n \t\tlen = strlen(tmp);\n \telse\n \t\tlen = endp - tmp;\n-\tif (person_len <= len)\n-\t\tgoto error_out;\n \n \tif (split_ident_line(&ident, tmp, len)) {\n \terror_out:\n \t\t/* Ugh */\n-\t\t*tz = \"(unknown)\";\n-\t\tstrcpy(person, *tz);\n-\t\tstrcpy(mail, *tz);\n+\t\ttmp = \"(unknown)\";\n+\t\tstrbuf_addstr(name, tmp);\n+\t\tstrbuf_addstr(mail, tmp);\n+\t\tstrbuf_addstr(tz, tmp);\n \t\t*time = 0;\n \t\treturn;\n \t}\n \n-\tnamelen = ident.name_end - ident.name_begin;\n-\tmemcpy(person, ident.name_begin, namelen);\n-\tperson[namelen] = 0;\n+\tlen = ident.name_end - ident.name_begin;\n+\tstrbuf_add(name, ident.name_begin, len);\n \n-\tmaillen = ident.mail_end - ident.mail_begin + 2;\n-\tmemcpy(mail, ident.mail_begin - 1, maillen);\n-\tmail[maillen] = 0;\n+\tlen = ident.mail_end - ident.mail_begin;\n+\tstrbuf_add(mail, ident.mail_begin, len);\n \n \t*time = strtoul(ident.date_begin, NULL, 10);\n \n-\ttzlen = ident.tz_end - ident.tz_begin;\n+\tlen = ident.tz_end - ident.tz_begin;\n+\tstrbuf_add(tz, ident.tz_begin, len);\n \n-\t/* Place tz at the end of person */\n-\t*tz = tmp = person + person_len - (tzlen + 1);\n-\tmemcpy(tmp, ident.tz_begin, tzlen);\n-\ttmp[tzlen] = 0;\n-\n-\tif (!mailmap.nr)\n-\t\treturn;\n-\n-\t/*\n+        /*\n \t * Now, convert both name and e-mail using mailmap\n \t */\n-\tif (map_user(&mailmap, mail+1, mail_len-1, person, tmp-person-1)) {\n-\t\t/* Add a trailing '>' to email, since map_user returns plain emails\n-\t\t   Note: It already has '<', since we replace from mail+1 */\n-\t\tmailpos = memchr(mail, '\\0', mail_len);\n-\t\tif (mailpos && mailpos-mail < mail_len - 1) {\n-\t\t\t*mailpos = '>';\n-\t\t\t*(mailpos+1) = '\\0';\n-\t\t}\n-\t}\n+\tif (mailmap.nr)\n+\t\tmap_user(&mailmap, mail, name);\n+\n+\tstrbuf_insert(mail, 0, \"<\", 1);\n+\tstrbuf_addch(mail, '>');\n+}\n+\n+static void commit_info_init(struct commit_info *ci)\n+{\n+\n+\tstrbuf_init(&ci->author, 0);\n+\tstrbuf_init(&ci->author_mail, 0);\n+\tstrbuf_init(&ci->author_tz, 0);\n+\tstrbuf_init(&ci->committer, 0);\n+\tstrbuf_init(&ci->committer_mail, 0);\n+\tstrbuf_init(&ci->committer_tz, 0);\n+\tstrbuf_init(&ci->summary, 0);\n+}\n+\n+static void commit_info_destroy(struct commit_info *ci)\n+{\n+\n+\tstrbuf_release(&ci->author);\n+\tstrbuf_release(&ci->author_mail);\n+\tstrbuf_release(&ci->author_tz);\n+\tstrbuf_release(&ci->committer);\n+\tstrbuf_release(&ci->committer_mail);\n+\tstrbuf_release(&ci->committer_tz);\n+\tstrbuf_release(&ci->summary);\n }\n \n static void get_commit_info(struct commit *commit,\n@@ -1410,11 +1419,8 @@ static void get_commit_info(struct commit *commit,\n \tint len;\n \tconst char *subject, *encoding;\n \tchar *reencoded, *message;\n-\tstatic char author_name[1024];\n-\tstatic char author_mail[1024];\n-\tstatic char committer_name[1024];\n-\tstatic char committer_mail[1024];\n-\tstatic char summary_buf[1024];\n+\n+\tcommit_info_init(ret);\n \n \t/*\n \t * We've operated without save_commit_buffer, so\n@@ -1432,11 +1438,7 @@ static void get_commit_info(struct commit *commit,\n \tencoding = get_log_output_encoding();\n \treencoded = logmsg_reencode(commit, encoding);\n \tmessage   = reencoded ? reencoded : commit->buffer;\n-\tret->author = author_name;\n-\tret->author_mail = author_mail;\n-\tget_ac_line(message, \"\\nauthor \",\n-\t\t    sizeof(author_name), author_name,\n-\t\t    sizeof(author_mail), author_mail,\n+\tget_ac_line(message, \"\\nauthor \", &ret->author, &ret->author_mail,\n \t\t    &ret->author_time, &ret->author_tz);\n \n \tif (!detailed) {\n@@ -1444,21 +1446,16 @@ static void get_commit_info(struct commit *commit,\n \t\treturn;\n \t}\n \n-\tret->committer = committer_name;\n-\tret->committer_mail = committer_mail;\n-\tget_ac_line(message, \"\\ncommitter \",\n-\t\t    sizeof(committer_name), committer_name,\n-\t\t    sizeof(committer_mail), committer_mail,\n-\t\t    &ret->committer_time, &ret->committer_tz);\n+\tget_ac_line(message, \"\\ncommitter \", &ret->committer,\n+\t\t    &ret->committer_mail, &ret->committer_time,\n+\t\t    &ret->committer_tz);\n \n-\tret->summary = summary_buf;\n \tlen = find_commit_subject(message, &subject);\n-\tif (len && len < sizeof(summary_buf)) {\n-\t\tmemcpy(summary_buf, subject, len);\n-\t\tsummary_buf[len] = 0;\n-\t} else {\n-\t\tsprintf(summary_buf, \"(%s)\", sha1_to_hex(commit->object.sha1));\n-\t}\n+\tif (len)\n+\t\tstrbuf_add(&ret->summary, subject, len);\n+\telse\n+\t\tstrbuf_addf(&ret->summary, \"(%s)\", sha1_to_hex(commit->object.sha1));\n+\n \tfree(reencoded);\n }\n \n@@ -1487,15 +1484,15 @@ static int emit_one_suspect_detail(struct origin *suspect, int repeat)\n \n \tsuspect->commit->object.flags |= METAINFO_SHOWN;\n \tget_commit_info(suspect->commit, &ci, 1);\n-\tprintf(\"author %s\\n\", ci.author);\n-\tprintf(\"author-mail %s\\n\", ci.author_mail);\n+\tprintf(\"author %s\\n\", ci.author.buf);\n+\tprintf(\"author-mail %s\\n\", ci.author_mail.buf);\n \tprintf(\"author-time %lu\\n\", ci.author_time);\n-\tprintf(\"author-tz %s\\n\", ci.author_tz);\n-\tprintf(\"committer %s\\n\", ci.committer);\n-\tprintf(\"committer-mail %s\\n\", ci.committer_mail);\n+\tprintf(\"author-tz %s\\n\", ci.author_tz.buf);\n+\tprintf(\"committer %s\\n\", ci.committer.buf);\n+\tprintf(\"committer-mail %s\\n\", ci.committer_mail.buf);\n \tprintf(\"committer-time %lu\\n\", ci.committer_time);\n-\tprintf(\"committer-tz %s\\n\", ci.committer_tz);\n-\tprintf(\"summary %s\\n\", ci.summary);\n+\tprintf(\"committer-tz %s\\n\", ci.committer_tz.buf);\n+\tprintf(\"summary %s\\n\", ci.summary.buf);\n \tif (suspect->commit->object.flags & UNINTERESTING)\n \t\tprintf(\"boundary\\n\");\n \tif (suspect->previous) {\n@@ -1503,6 +1500,9 @@ static int emit_one_suspect_detail(struct origin *suspect, int repeat)\n \t\tprintf(\"previous %s \", sha1_to_hex(prev->commit->object.sha1));\n \t\twrite_name_quoted(prev->path, stdout, '\\n');\n \t}\n+\n+\tcommit_info_destroy(&ci);\n+\n \treturn 1;\n }\n \n@@ -1689,11 +1689,11 @@ static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt)\n \t\tif (opt & OUTPUT_ANNOTATE_COMPAT) {\n \t\t\tconst char *name;\n \t\t\tif (opt & OUTPUT_SHOW_EMAIL)\n-\t\t\t\tname = ci.author_mail;\n+\t\t\t\tname = ci.author_mail.buf;\n \t\t\telse\n-\t\t\t\tname = ci.author;\n+\t\t\t\tname = ci.author.buf;\n \t\t\tprintf(\"\\t(%10s\\t%10s\\t%d)\", name,\n-\t\t\t       format_time(ci.author_time, ci.author_tz,\n+\t\t\t       format_time(ci.author_time, ci.author_tz.buf,\n \t\t\t\t\t   show_raw_time),\n \t\t\t       ent->lno + 1 + cnt);\n \t\t} else {\n@@ -1712,14 +1712,14 @@ static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt)\n \t\t\t\tconst char *name;\n \t\t\t\tint pad;\n \t\t\t\tif (opt & OUTPUT_SHOW_EMAIL)\n-\t\t\t\t\tname = ci.author_mail;\n+\t\t\t\t\tname = ci.author_mail.buf;\n \t\t\t\telse\n-\t\t\t\t\tname = ci.author;\n+\t\t\t\t\tname = ci.author.buf;\n \t\t\t\tpad = longest_author - utf8_strwidth(name);\n \t\t\t\tprintf(\" (%s%*s %10s\",\n \t\t\t\t       name, pad, \"\",\n \t\t\t\t       format_time(ci.author_time,\n-\t\t\t\t\t\t   ci.author_tz,\n+\t\t\t\t\t\t   ci.author_tz.buf,\n \t\t\t\t\t\t   show_raw_time));\n \t\t\t}\n \t\t\tprintf(\" %*d) \",\n@@ -1734,6 +1734,8 @@ static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt)\n \n \tif (sb->final_buf_size && cp[-1] != '\\n')\n \t\tputchar('\\n');\n+\n+\tcommit_info_destroy(&ci);\n }\n \n static void output(struct scoreboard *sb, int option)\n@@ -1858,9 +1860,9 @@ static void find_alignment(struct scoreboard *sb, int *option)\n \t\t\tsuspect->commit->object.flags |= METAINFO_SHOWN;\n \t\t\tget_commit_info(suspect->commit, &ci, 1);\n \t\t\tif (*option & OUTPUT_SHOW_EMAIL)\n-\t\t\t\tnum = utf8_strwidth(ci.author_mail);\n+\t\t\t\tnum = utf8_strwidth(ci.author_mail.buf);\n \t\t\telse\n-\t\t\t\tnum = utf8_strwidth(ci.author);\n+\t\t\t\tnum = utf8_strwidth(ci.author.buf);\n \t\t\tif (longest_author < num)\n \t\t\t\tlongest_author = num;\n \t\t}\n@@ -1872,6 +1874,8 @@ static void find_alignment(struct scoreboard *sb, int *option)\n \t\t\tlongest_dst_lines = num;\n \t\tif (largest_score < ent_score(sb, e))\n \t\t\tlargest_score = ent_score(sb, e);\n+\n+\t\tcommit_info_destroy(&ci);\n \t}\n \tmax_orig_digits = decimal_width(longest_src_lines);\n \tmax_digits = decimal_width(longest_dst_lines);\ndiff --git a/builtin/shortlog.c b/builtin/shortlog.c\nindex 03c6cd7..20e8599 100644\n--- a/builtin/shortlog.c\n+++ b/builtin/shortlog.c\n@@ -36,39 +36,30 @@ static void insert_one_record(struct shortlog *log,\n \tconst char *dot3 = log->common_repo_prefix;\n \tchar *buffer, *p;\n \tstruct string_list_item *item;\n-\tchar namebuf[1024];\n-\tchar emailbuf[1024];\n-\tsize_t len;\n \tconst char *eol;\n \tstruct strbuf subject = STRBUF_INIT;\n+\tstruct strbuf name = STRBUF_INIT;\n+\tstruct strbuf mail = STRBUF_INIT;\n \tstruct ident_split ident;\n \n \tif (split_ident_line(&ident, author, strlen(author)))\n \t\treturn;\n \n-\t/* copy author name to namebuf, to support matching on both name and email */\n-\tlen = ident.name_end - ident.name_begin;\n-\tmemcpy(namebuf, ident.name_begin, len);\n-\tnamebuf[len] = 0;\n+\tstrbuf_add(&mail, ident.mail_begin, ident.mail_end - ident.mail_begin);\n+\tstrbuf_add(&name, ident.name_begin, ident.name_end - ident.name_begin);\n \n-\t/* copy email name to emailbuf, to allow email replacement as well */\n-\tlen = ident.mail_end - ident.mail_begin;\n-\tmemcpy(emailbuf, ident.mail_begin, len);\n-\temailbuf[len] = 0;\n+\tmap_user(&log->mailmap, &mail, &name);\n \n-\tmap_user(&log->mailmap, emailbuf, sizeof(emailbuf), namebuf, sizeof(namebuf));\n-\tlen = strlen(namebuf);\n+\tif (log->email)\n+\t\tstrbuf_addf(&name, \" <%s>\", mail.buf);\n \n-\tif (log->email) {\n-\t\tsize_t room = sizeof(namebuf) - len - 1;\n-\t\tint maillen = strlen(emailbuf);\n-\t\tsnprintf(namebuf + len, room, \" <%.*s>\", maillen, emailbuf);\n-\t}\n-\n-\titem = string_list_insert(&log->list, namebuf);\n+\titem = string_list_insert(&log->list, name.buf);\n \tif (item->util == NULL)\n \t\titem->util = xcalloc(1, sizeof(struct string_list));\n \n+\tstrbuf_release(&name);\n+\tstrbuf_release(&mail);\n+\n \t/* Skip any leading whitespace, including any blank lines. */\n \twhile (*oneline && isspace(*oneline))\n \t\toneline++;\ndiff --git a/mailmap.c b/mailmap.c\nindex 3bc6491..d5bffc6 100644\n--- a/mailmap.c\n+++ b/mailmap.c\n@@ -187,57 +187,52 @@ void clear_mailmap(struct string_list *map)\n \tdebug_mm(\"mailmap: cleared\\n\");\n }\n \n-int map_user(struct string_list *map,\n-\t     char *email, int maxlen_email, char *name, int maxlen_name)\n+int map_user(struct string_list *map, struct strbuf *mail, struct strbuf *name)\n {\n-\tchar *end_of_email;\n+\n \tstruct string_list_item *item;\n \tstruct mailmap_entry *me;\n-\tstruct strbuf mailbuf = STRBUF_INIT;\n+\tstruct strbuf lowermail = STRBUF_INIT;\n \tint i;\n \n-\t/* figure out space requirement for email */\n-\tend_of_email = strchr(email, '>');\n-\tif (!end_of_email) {\n-\t\t/* email passed in might not be wrapped in <>, but end with a \\0 */\n-\t\tend_of_email = memchr(email, '\\0', maxlen_email);\n-\t\tif (!end_of_email)\n-\t\t\treturn 0;\n-\t}\n-\n \t/* downcase the email address */\n-\tstrbuf_grow(&mailbuf, end_of_email - email);\n-\tfor (i = 0; i < end_of_email - email; i++)\n-\t\tstrbuf_addch(&mailbuf, tolower(email[i]));\n+\tstrbuf_grow(&lowermail, mail->len);\n+\tfor (i = 0; i < mail->len; i++)\n+\t\tstrbuf_addch(&lowermail, tolower(mail->buf[i]));\n \n-\tdebug_mm(\"map_user: map '%s' <%s>\\n\", name, mailbuf.buf);\n-\titem = string_list_lookup(map, mailbuf.buf);\n+\tdebug_mm(\"map_user: map '%s' <%s>\\n\", name->buf, lowermail.buf);\n+\titem = string_list_lookup(map, lowermail.buf);\n \tif (item != NULL) {\n \t\tme = (struct mailmap_entry *)item->util;\n \t\tif (me->namemap.nr) {\n \t\t\t/* The item has multiple items, so we'll look up on name too */\n \t\t\t/* If the name is not found, we choose the simple entry      */\n-\t\t\tstruct string_list_item *subitem = string_list_lookup(&me->namemap, name);\n+\t\t\tstruct string_list_item *subitem = string_list_lookup(&me->namemap, name->buf);\n \t\t\tif (subitem)\n \t\t\t\titem = subitem;\n \t\t}\n \t}\n-\tstrbuf_release(&mailbuf);\n+\tstrbuf_release(&lowermail);\n \tif (item != NULL) {\n \t\tstruct mailmap_info *mi = (struct mailmap_info *)item->util;\n-\t\tif (mi->name == NULL && (mi->email == NULL || maxlen_email == 0)) {\n+\t\tif (mi->name == NULL && mi->email == NULL) {\n \t\t\tdebug_mm(\"map_user:  -- (no simple mapping)\\n\");\n \t\t\treturn 0;\n \t\t}\n-\t\tif (maxlen_email && mi->email)\n-\t\t\tstrlcpy(email, mi->email, maxlen_email);\n-\t\telse\n-\t\t\t*end_of_email = '\\0';\n-\t\tif (maxlen_name && mi->name)\n-\t\t\tstrlcpy(name, mi->name, maxlen_name);\n-\t\tdebug_mm(\"map_user:  to '%s' <%s>\\n\", name, mi->email ? mi->email : \"\");\n+\t\tif (mi->email) {\n+\t\t\tstrbuf_reset(mail);\n+\t\t\tstrbuf_addstr(mail, mi->email);\n+\t\t}\n+\n+\t\tif (mi->name) {\n+\t\t\tstrbuf_reset(name);\n+\t\t\tstrbuf_addstr(name, mi->name);\n+\t\t}\n+\n+\t\tdebug_mm(\"map_user:  to '%s' <%s>\\n\", name->buf, mi->email ? mi->email : \"\");\n \t\treturn 1;\n \t}\n+\n \tdebug_mm(\"map_user:  --\\n\");\n \treturn 0;\n }\ndiff --git a/mailmap.h b/mailmap.h\nindex d5c3664..88dca51 100644\n--- a/mailmap.h\n+++ b/mailmap.h\n@@ -4,7 +4,5 @@\n int read_mailmap(struct string_list *map, char **repo_abbrev);\n void clear_mailmap(struct string_list *map);\n \n-int map_user(struct string_list *mailmap,\n-\t     char *email, int maxlen_email, char *name, int maxlen_name);\n-\n+int map_user(struct string_list *map, struct strbuf *name, struct strbuf *mail);\n #endif\ndiff --git a/pretty.c b/pretty.c\nindex 350d1df..d05c675 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -593,14 +593,14 @@ char *logmsg_reencode(const struct commit *commit,\n \treturn out;\n }\n \n-static int mailmap_name(char *email, int email_len, char *name, int name_len)\n+static int mailmap_name(struct strbuf *mail, struct strbuf *name)\n {\n \tstatic struct string_list *mail_map;\n \tif (!mail_map) {\n \t\tmail_map = xcalloc(1, sizeof(*mail_map));\n \t\tread_mailmap(mail_map, NULL);\n \t}\n-\treturn mail_map->nr && map_user(mail_map, email, email_len, name, name_len);\n+\treturn mail_map->nr && map_user(mail_map, mail, name);\n }\n \n static size_t format_person_part(struct strbuf *sb, char part,\n@@ -610,39 +610,39 @@ static size_t format_person_part(struct strbuf *sb, char part,\n \tconst int placeholder_len = 2;\n \tint tz;\n \tunsigned long date = 0;\n-\tchar person_name[1024];\n-\tchar person_mail[1024];\n+\tstruct strbuf person_name = STRBUF_INIT;\n+\tstruct strbuf person_mail = STRBUF_INIT;\n \tstruct ident_split s;\n-\tconst char *name_start, *name_end, *mail_start, *mail_end;\n \n \tif (split_ident_line(&s, msg, len) < 0)\n \t\tgoto skip;\n \n-\tname_start = s.name_begin;\n-\tname_end = s.name_end;\n-\tmail_start = s.mail_begin;\n-\tmail_end = s.mail_end;\n+\tstrbuf_add(&person_name, s.name_begin, (int)(s.name_end - s.name_begin));\n+\tstrbuf_add(&person_mail, s.mail_begin, (int)(s.mail_end - s.mail_begin));\n \n \tif (part == 'N' || part == 'E') { /* mailmap lookup */\n-\t\tsnprintf(person_name, sizeof(person_name), \"%.*s\",\n-\t\t\t (int)(name_end - name_start), name_start);\n-\t\tsnprintf(person_mail, sizeof(person_mail), \"%.*s\",\n-\t\t\t (int)(mail_end - mail_start), mail_start);\n-\t\tmailmap_name(person_mail, sizeof(person_mail), person_name, sizeof(person_name));\n-\t\tname_start = person_name;\n-\t\tname_end = name_start + strlen(person_name);\n-\t\tmail_start = person_mail;\n-\t\tmail_end = mail_start +  strlen(person_mail);\n+\t\tmailmap_name(&person_mail, &person_name);\n \t}\n \tif (part == 'n' || part == 'N') {\t/* name */\n-\t\tstrbuf_add(sb, name_start, name_end-name_start);\n+\t\tstrbuf_addbuf(sb, &person_name);\n+\n+\t\tstrbuf_release(&person_name);\n+\t\tstrbuf_release(&person_mail);\n+\n \t\treturn placeholder_len;\n \t}\n \tif (part == 'e' || part == 'E') {\t/* email */\n-\t\tstrbuf_add(sb, mail_start, mail_end-mail_start);\n+\t\tstrbuf_addbuf(sb, &person_mail);\n+\n+\t\tstrbuf_release(&person_name);\n+\t\tstrbuf_release(&person_mail);\n+\n \t\treturn placeholder_len;\n \t}\n \n+\tstrbuf_release(&person_name);\n+\tstrbuf_release(&person_mail);\n+\n \tif (!s.date_begin)\n \t\tgoto skip;\n \n-- \n1.7.9.5\n"},{"id":"204925","messageId":"1355594754-27589-5-git-send-email-apelisse@gmail.com","threadId":"32349","inReplyTo":"1355594754-27589-1-git-send-email-apelisse@gmail.com","subject":"[PATCH v2 4/7] mailmap: Add mailmap structure to rev_info and pp","fromName":"Antoine Pelisse","fromEmail":"apelisse@gmail.com","sentAt":"2012-12-15T18:05:51Z","receivedAt":"2012-12-15T18:05:51Z","isPatch":true,"sender":{"key":"apelisse@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1929644?v=4"},"body":"the mailmap string_list structure filled with mailmap\ninformation is passed along from rev_info to pretty_print_context\nto provide mailmap information to pretty print each commits\nwith the correct username and email.\n\nSigned-off-by: Antoine Pelisse <apelisse@gmail.com>\n---\n commit.h   |    1 +\n log-tree.c |    1 +\n revision.h |    1 +\n 3 files changed, 3 insertions(+)\n\ndiff --git a/commit.h b/commit.h\nindex b6ad8f3..7f8f987 100644\n--- a/commit.h\n+++ b/commit.h\n@@ -89,6 +89,7 @@ struct pretty_print_context {\n \tchar *notes_message;\n \tstruct reflog_walk_info *reflog_info;\n \tconst char *output_encoding;\n+\tstruct string_list *mailmap;\n };\n \n struct userformat_want {\ndiff --git a/log-tree.c b/log-tree.c\nindex 4f86def..92254fd 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -671,6 +671,7 @@ void show_log(struct rev_info *opt)\n \tctx.preserve_subject = opt->preserve_subject;\n \tctx.reflog_info = opt->reflog_info;\n \tctx.fmt = opt->commit_format;\n+\tctx.mailmap = opt->mailmap;\n \tpretty_print_commit(&ctx, commit, &msgbuf);\n \n \tif (opt->add_signoff)\ndiff --git a/revision.h b/revision.h\nindex 059bfff..83a79f5 100644\n--- a/revision.h\n+++ b/revision.h\n@@ -143,6 +143,7 @@ struct rev_info {\n \tconst char\t*subject_prefix;\n \tint\t\tno_inline;\n \tint\t\tshow_log_size;\n+\tstruct string_list *mailmap;\n \n \t/* Filter by commit log message */\n \tstruct grep_opt\tgrep_filter;\n-- \n1.7.9.5\n"},{"id":"204924","messageId":"1355594754-27589-6-git-send-email-apelisse@gmail.com","threadId":"32349","inReplyTo":"1355594754-27589-1-git-send-email-apelisse@gmail.com","subject":"[PATCH v2 5/7] pretty: Use mailmap to display username and email","fromName":"Antoine Pelisse","fromEmail":"apelisse@gmail.com","sentAt":"2012-12-15T18:05:52Z","receivedAt":"2012-12-15T18:05:52Z","isPatch":true,"sender":{"key":"apelisse@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1929644?v=4"},"body":"Use the mailmap information to display the correct\nusername and email address in all log commands.\n\nSigned-off-by: Antoine Pelisse <apelisse@gmail.com>\n---\n pretty.c |   48 ++++++++++++++++++++++++++++--------------------\n 1 file changed, 28 insertions(+), 20 deletions(-)\n\ndiff --git a/pretty.c b/pretty.c\nindex d05c675..fbf87b7 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -387,6 +387,8 @@ void pp_user_info(const struct pretty_print_context *pp,\n \t\t  const char *what, struct strbuf *sb,\n \t\t  const char *line, const char *encoding)\n {\n+\tstruct strbuf name;\n+\tstruct strbuf mail;\n \tstruct ident_split ident;\n \tint linelen, namelen;\n \tchar *line_end, *date;\n@@ -408,42 +410,48 @@ void pp_user_info(const struct pretty_print_context *pp,\n \tif (split_ident_line(&ident, line, linelen))\n \t\treturn;\n \n-\tnamelen = ident.mail_end - ident.name_begin + 1;\n+\tstrbuf_init(&mail, 0);\n+\tstrbuf_init(&name, 0);\n+\n+\tstrbuf_add(&mail, ident.mail_begin, ident.mail_end - ident.mail_begin);\n+\tstrbuf_add(&name, ident.name_begin, ident.name_end - ident.name_begin);\n+\n+\tif (pp->mailmap)\n+\t\tmap_user(pp->mailmap, &mail, &name);\n+\n+\tnamelen = name.len + mail.len + 3; /* ' ' + '<' + '>' */\n \ttime = strtoul(ident.date_begin, &date, 10);\n \ttz = strtol(date, NULL, 10);\n \n \tif (pp->fmt == CMIT_FMT_EMAIL) {\n-\t\tint display_name_length;\n-\n-\t\tdisplay_name_length = ident.name_end - ident.name_begin;\n-\n \t\tstrbuf_addstr(sb, \"From: \");\n-\t\tif (needs_rfc2047_encoding(line, display_name_length, RFC2047_ADDRESS)) {\n-\t\t\tadd_rfc2047(sb, line, display_name_length,\n-\t\t\t\t\t\tencoding, RFC2047_ADDRESS);\n+\t\tif (needs_rfc2047_encoding(name.buf, name.len, RFC2047_ADDRESS)) {\n+\t\t\tadd_rfc2047(sb, name.buf, name.len,\n+\t\t\t\t    encoding, RFC2047_ADDRESS);\n \t\t\tmax_length = 76; /* per rfc2047 */\n-\t\t} else if (needs_rfc822_quoting(line, display_name_length)) {\n+\t\t} else if (needs_rfc822_quoting(name.buf, name.len)) {\n \t\t\tstruct strbuf quoted = STRBUF_INIT;\n-\t\t\tadd_rfc822_quoted(&quoted, line, display_name_length);\n+\t\t\tadd_rfc822_quoted(&quoted, name.buf, name.len);\n \t\t\tstrbuf_add_wrapped_bytes(sb, quoted.buf, quoted.len,\n \t\t\t\t\t\t\t-6, 1, max_length);\n \t\t\tstrbuf_release(&quoted);\n \t\t} else {\n-\t\t\tstrbuf_add_wrapped_bytes(sb, line, display_name_length,\n-\t\t\t\t\t\t\t-6, 1, max_length);\n+\t\t\tstrbuf_add_wrapped_bytes(sb, name.buf, name.len,\n+\t\t\t\t\t\t -6, 1, max_length);\n \t\t}\n-\t\tif (namelen - display_name_length + last_line_length(sb) > max_length) {\n+\t\tif (namelen - name.len + last_line_length(sb) > max_length)\n \t\t\tstrbuf_addch(sb, '\\n');\n-\t\t\tif (!isspace(ident.name_end[0]))\n-\t\t\t\tstrbuf_addch(sb, ' ');\n-\t\t}\n-\t\tstrbuf_add(sb, ident.name_end, namelen - display_name_length);\n-\t\tstrbuf_addch(sb, '\\n');\n+\n+\t\tstrbuf_addf(sb, \" <%s>\\n\", mail.buf);\n \t} else {\n-\t\tstrbuf_addf(sb, \"%s: %.*s%.*s\\n\", what,\n+\t\tstrbuf_addf(sb, \"%s: %.*s%s <%s>\\n\", what,\n \t\t\t      (pp->fmt == CMIT_FMT_FULLER) ? 4 : 0,\n-\t\t\t      \"    \", namelen, line);\n+\t\t\t      \"    \", name.buf, mail.buf);\n \t}\n+\n+\tstrbuf_release(&mail);\n+\tstrbuf_release(&name);\n+\n \tswitch (pp->fmt) {\n \tcase CMIT_FMT_MEDIUM:\n \t\tstrbuf_addf(sb, \"Date:   %s\\n\", show_date(time, tz, pp->date_mode));\n-- \n1.7.9.5\n"},{"id":"204926","messageId":"1355594754-27589-7-git-send-email-apelisse@gmail.com","threadId":"32349","inReplyTo":"1355594754-27589-1-git-send-email-apelisse@gmail.com","subject":"[PATCH v2 6/7] log: Add --use-mailmap option","fromName":"Antoine Pelisse","fromEmail":"apelisse@gmail.com","sentAt":"2012-12-15T18:05:53Z","receivedAt":"2012-12-15T18:05:53Z","isPatch":true,"sender":{"key":"apelisse@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1929644?v=4"},"body":"Add the --use-mailmap option to log commands. It allows\nto display names from mailmap file when displaying logs,\nwhatever the format used.\n\nSigned-off-by: Antoine Pelisse <apelisse@gmail.com>\n---\n Documentation/git-log.txt |    5 +++++\n builtin/log.c             |    9 ++++++++-\n 2 files changed, 13 insertions(+), 1 deletion(-)\n\ndiff --git a/Documentation/git-log.txt b/Documentation/git-log.txt\nindex 585dac4..a99be97 100644\n--- a/Documentation/git-log.txt\n+++ b/Documentation/git-log.txt\n@@ -47,6 +47,11 @@ OPTIONS\n \tPrint out the ref name given on the command line by which each\n \tcommit was reached.\n \n+--use-mailmap::\n+\tUse mailmap file to map author and committer names and email\n+\tto canonical real names and email addresses. See\n+\tlinkgit:git-shortlog[1].\n+\n --full-diff::\n \tWithout this flag, \"git log -p <path>...\" shows commits that\n \ttouch the specified paths, and diffs about the same specified\ndiff --git a/builtin/log.c b/builtin/log.c\nindex e7b7db1..d2bd8ce 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -22,6 +22,7 @@\n #include \"branch.h\"\n #include \"streaming.h\"\n #include \"version.h\"\n+#include \"mailmap.h\"\n \n /* Set a default date-time format for git log (\"log.date\" config variable) */\n static const char *default_date_mode = NULL;\n@@ -94,11 +95,12 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,\n \t\t\t struct rev_info *rev, struct setup_revision_opt *opt)\n {\n \tstruct userformat_want w;\n-\tint quiet = 0, source = 0;\n+\tint quiet = 0, source = 0, mailmap = 0;\n \n \tconst struct option builtin_log_options[] = {\n \t\tOPT_BOOLEAN(0, \"quiet\", &quiet, N_(\"suppress diff output\")),\n \t\tOPT_BOOLEAN(0, \"source\", &source, N_(\"show source\")),\n+\t\tOPT_BOOLEAN(0, \"use-mailmap\", &mailmap, N_(\"Use mail map file\")),\n \t\t{ OPTION_CALLBACK, 0, \"decorate\", NULL, NULL, N_(\"decorate options\"),\n \t\t  PARSE_OPT_OPTARG, decorate_callback},\n \t\tOPT_END()\n@@ -136,6 +138,11 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,\n \tif (source)\n \t\trev->show_source = 1;\n \n+\tif (mailmap) {\n+\t\trev->mailmap = xcalloc(1, sizeof(struct string_list));\n+\t\tread_mailmap(rev->mailmap, NULL);\n+\t}\n+\n \tif (rev->pretty_given && rev->commit_format == CMIT_FMT_RAW) {\n \t\t/*\n \t\t * \"log --pretty=raw\" is special; ignore UI oriented\n-- \n1.7.9.5\n"},{"id":"204923","messageId":"1355594754-27589-8-git-send-email-apelisse@gmail.com","threadId":"32349","inReplyTo":"1355594754-27589-1-git-send-email-apelisse@gmail.com","subject":"[PATCH v2 7/7] test: Add test for --use-mailmap option","fromName":"Antoine Pelisse","fromEmail":"apelisse@gmail.com","sentAt":"2012-12-15T18:05:54Z","receivedAt":"2012-12-15T18:05:54Z","isPatch":true,"sender":{"key":"apelisse@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1929644?v=4"},"body":"The new option '--use-mailmap' can be used to make\nsure that mailmap file is used to convert name\nwhen running log commands.\n\nThe test is simple and checks that the Author line\nis correctly replaced when running log.\n\nSigned-off-by: Antoine Pelisse <apelisse@gmail.com>\n---\n t/t4203-mailmap.sh |   14 ++++++++++++++\n 1 file changed, 14 insertions(+)\n\ndiff --git a/t/t4203-mailmap.sh b/t/t4203-mailmap.sh\nindex 1f182f6..db043dc 100755\n--- a/t/t4203-mailmap.sh\n+++ b/t/t4203-mailmap.sh\n@@ -239,6 +239,20 @@ test_expect_success 'Log output (complex mapping)' '\n \ttest_cmp expect actual\n '\n \n+cat >expect <<\\EOF\n+Author: CTO <cto@company.xx>\n+Author: Santa Claus <santa.claus@northpole.xx>\n+Author: Santa Claus <santa.claus@northpole.xx>\n+Author: Other Author <other@author.xx>\n+Author: Other Author <other@author.xx>\n+Author: Some Dude <some@dude.xx>\n+Author: A U Thor <author@example.com>\n+EOF\n+test_expect_success 'Log output with --use-mailmap' '\n+\tgit log --use-mailmap | grep Author >actual &&\n+\ttest_cmp expect actual\n+'\n+\n # git blame\n cat >expect <<\\EOF\n ^OBJI (A U Thor     DATE 1) one\n-- \n1.7.9.5\n"},{"id":"204946","messageId":"7vd2ybrrvl.fsf@alter.siamese.dyndns.org","threadId":"32349","inReplyTo":"1355594754-27589-1-git-send-email-apelisse@gmail.com","subject":"Re: [PATCH v2 0/7] Allow git log to use mailmap file","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-12-15T20:18:38Z","receivedAt":"2012-12-15T20:18:38Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Antoine Pelisse <apelisse@gmail.com> writes:\n\n> Implement the feature suggested by Rich Mindwinter and Junio C Hamano\n> (and following his advices)\n>\n>\n>\n> Allows git show/log commands to map author and committer\n> names and emails using the mailmap file.\n>\n> Updates related to this second series:\n>   - All tests are successful after each patch\n>   - Use split_ident_line in shortlog.c\n>   - Documentation has been added to git-log.txt\n>   - Test has been added to check that we use the file\n>   - Lots of improvements in the way strbufs are used\n>   - New interface to map_user()\n>   - Bunch of other fixes\n\nThe updated map_user() and its users look much nicer now.  Applying\nyour patches with \"git am --whitespace=error\" spots a few style\nviolations, though.\n\n> git glog --committer/--author is still not looking for mailmap user\n> names.\n\nI think we should stop using the header grep mechanism for these and\ninstead keep two separate grep expressions in struct rev_info and\nuse them in revision.c::commit_match().  The unification of header\nfilter and message grep filter done in 2d10c55 (git log: Unify\nheader_filter and message_filter into one., 2006-09-20) may not have\nbeen a good idea.\n\nThanks.\n"}]}