From: Junio C Hamano Date: Thu, 28 Mar 2013 21:38:25 +0000 (-0700) Subject: Merge branch 'kk/revwalk-slop-too-many-commit-within-a-second' X-Git-Tag: v1.8.3-rc0~154 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/74bd52681d7c57907bef129cdffb6cd0f2895115?ds=inline;hp=-c Merge branch 'kk/revwalk-slop-too-many-commit-within-a-second' Allow the revision "slop" code to look deeper while commits with exactly the same timestamps come next to each other (which can often happen after a large "am" and "rebase" session). * kk/revwalk-slop-too-many-commit-within-a-second: Fix revision walk for commits with the same dates --- 74bd52681d7c57907bef129cdffb6cd0f2895115 diff --combined revision.c index 78397d6486,6a9a8b3c80..71e62d8312 --- a/revision.c +++ b/revision.c @@@ -13,7 -13,6 +13,7 @@@ #include "decorate.h" #include "log-tree.h" #include "string-list.h" +#include "mailmap.h" volatile show_early_output_fn_t show_early_output; @@@ -709,7 -708,7 +709,7 @@@ static int still_interesting(struct com * Does the destination list contain entries with a date * before the source list? Definitely _not_ done. */ - if (date < src->item->date) + if (date <= src->item->date) return SLOP; /* @@@ -1604,8 -1603,6 +1604,8 @@@ static int handle_revision_opt(struct r return argcount; } else if (!strcmp(arg, "--grep-debug")) { revs->grep_filter.debug = 1; + } else if (!strcmp(arg, "--basic-regexp")) { + grep_set_pattern_type_option(GREP_PATTERN_TYPE_BRE, &revs->grep_filter); } else if (!strcmp(arg, "--extended-regexp") || !strcmp(arg, "-E")) { grep_set_pattern_type_option(GREP_PATTERN_TYPE_ERE, &revs->grep_filter); } else if (!strcmp(arg, "--regexp-ignore-case") || !strcmp(arg, "-i")) { @@@ -1613,8 -1610,6 +1613,8 @@@ DIFF_OPT_SET(&revs->diffopt, PICKAXE_IGNORE_CASE); } else if (!strcmp(arg, "--fixed-strings") || !strcmp(arg, "-F")) { grep_set_pattern_type_option(GREP_PATTERN_TYPE_FIXED, &revs->grep_filter); + } else if (!strcmp(arg, "--perl-regexp")) { + grep_set_pattern_type_option(GREP_PATTERN_TYPE_PCRE, &revs->grep_filter); } else if (!strcmp(arg, "--all-match")) { revs->grep_filter.all_match = 1; } else if ((argcount = parse_long_opt("encoding", argv, &optarg))) { @@@ -1970,22 -1965,6 +1970,22 @@@ static struct merge_simplify_state *loc return st; } +static void remove_treesame_parents(struct commit *commit) +{ + struct commit_list **pp, *p; + + pp = &commit->parents; + while ((p = *pp) != NULL) { + struct commit *parent = p->item; + if (parent->object.flags & TREESAME) { + *pp = p->next; + free(p); + continue; + } + pp = &p->next; + } +} + static struct commit_list **simplify_one(struct rev_info *revs, struct commit *commit, struct commit_list **tail) { struct commit_list *p; @@@ -2038,18 -2017,10 +2038,18 @@@ if (revs->first_parent_only) break; } - if (!revs->first_parent_only) - cnt = remove_duplicate_parents(commit); - else + + if (revs->first_parent_only) { cnt = 1; + } else { + /* + * A merge with a tree-same parent is useless + */ + if (commit->parents && commit->parents->next) + remove_treesame_parents(commit); + + cnt = remove_duplicate_parents(commit); + } /* * It is possible that we are a merge and one side branch @@@ -2244,58 -2215,10 +2244,58 @@@ static int rewrite_parents(struct rev_i return 0; } +static int commit_rewrite_person(struct strbuf *buf, const char *what, struct string_list *mailmap) +{ + char *person, *endp; + size_t len, namelen, maillen; + const char *name; + const char *mail; + struct ident_split ident; + + person = strstr(buf->buf, what); + if (!person) + return 0; + + person += strlen(what); + endp = strchr(person, '\n'); + if (!endp) + return 0; + + len = endp - person; + + if (split_ident_line(&ident, person, len)) + return 0; + + mail = ident.mail_begin; + maillen = ident.mail_end - ident.mail_begin; + name = ident.name_begin; + namelen = ident.name_end - ident.name_begin; + + if (map_user(mailmap, &mail, &maillen, &name, &namelen)) { + struct strbuf namemail = STRBUF_INIT; + + strbuf_addf(&namemail, "%.*s <%.*s>", + (int)namelen, name, (int)maillen, mail); + + strbuf_splice(buf, ident.name_begin - buf->buf, + ident.mail_end - ident.name_begin + 1, + namemail.buf, namemail.len); + + strbuf_release(&namemail); + + return 1; + } + + return 0; +} + static int commit_match(struct commit *commit, struct rev_info *opt) { int retval; + const char *encoding; + char *message; struct strbuf buf = STRBUF_INIT; + if (!opt->grep_filter.pattern_list && !opt->grep_filter.header_list) return 1; @@@ -2306,43 -2229,25 +2306,43 @@@ strbuf_addch(&buf, '\n'); } + /* + * We grep in the user's output encoding, under the assumption that it + * is the encoding they are most likely to write their grep pattern + * for. In addition, it means we will match the "notes" encoding below, + * so we will not end up with a buffer that has two different encodings + * in it. + */ + encoding = get_log_output_encoding(); + message = logmsg_reencode(commit, encoding); + /* Copy the commit to temporary if we are using "fake" headers */ if (buf.len) - strbuf_addstr(&buf, commit->buffer); + strbuf_addstr(&buf, message); + + if (opt->grep_filter.header_list && opt->mailmap) { + if (!buf.len) + strbuf_addstr(&buf, message); + + commit_rewrite_person(&buf, "\nauthor ", opt->mailmap); + commit_rewrite_person(&buf, "\ncommitter ", opt->mailmap); + } /* Append "fake" message parts as needed */ if (opt->show_notes) { if (!buf.len) - strbuf_addstr(&buf, commit->buffer); - format_display_notes(commit->object.sha1, &buf, - get_log_output_encoding(), 0); + strbuf_addstr(&buf, message); + format_display_notes(commit->object.sha1, &buf, encoding, 1); } - /* Find either in the commit object, or in the temporary */ + /* Find either in the original commit message, or in the temporary */ if (buf.len) retval = grep_buffer(&opt->grep_filter, buf.buf, buf.len); else retval = grep_buffer(&opt->grep_filter, - commit->buffer, strlen(commit->buffer)); + message, strlen(message)); strbuf_release(&buf); + logmsg_free(message, commit); return retval; }