Junio C Hamano <gitster@xxxxxxxxx> writes: > Here is a tested (in the sense that it passes the test suite, and > also in the sense that an empty pull in the kernel history gives > quick turnaround) patch. As I do not think we would want to revert > 5802f81 (fmt-merge-msg: discard needless merge parents, 2012-04-18) > which was a correctness fix, I think we would rather want to do > something like this. OK, I think I am convinced myself that this patch is the right fix. The performance regression Markus saw is in fmt-merge-message, and it is caused by the updated remove_redundant() that is used by get_merge_bases_many() and reduce_heads(). On the topic branch, all callers of reduce_heads() were passing commits that are already parsed, but before the topic was merged to 'master', we added one more caller to reduce_heads() on the 'master' front that passed an unparsed commit, which is why the problem surfaced at that merge. It might make sense to assert or die in commit_list_insert_by_date() when a caller mistakenly pass an unparsed commit object to prevent this kind of breakages in the future. > -- >8 -- > Subject: paint_down_to_common(): parse commit before relying on its timestamp > > When refactoring the merge-base computation to reduce the pairwise > O(n*(n-1)) traversals to parallel O(n) traversals, the code forgot > that timestamp based heuristics needs each commit to have been > parsed. This caused an empty "git pull" to spend cycles, traversing > the history all the way down to 0 (because an unparsed commit object > has 0 timestamp, and any other commit object with positive timestamp > will be processed for its parents, all getting parsed), only to come > up with a merge message to be used. > > Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx> > --- > commit.c | 5 +++++ > 1 file changed, 5 insertions(+) > > diff --git i/commit.c w/commit.c > index 0246767..213bc98 100644 > --- i/commit.c > +++ w/commit.c > @@ -609,6 +609,7 @@ static struct commit *interesting(struct commit_list *list) > return NULL; > } > > +/* all input commits in one and twos[] must have been parsed! */ > static struct commit_list *paint_down_to_common(struct commit *one, int n, struct commit **twos) > { > struct commit_list *list = NULL; > @@ -617,6 +618,8 @@ static struct commit_list *paint_down_to_common(struct commit *one, int n, struc > > one->object.flags |= PARENT1; > commit_list_insert_by_date(one, &list); > + if (!n) > + return list; > for (i = 0; i < n; i++) { > twos[i]->object.flags |= PARENT2; > commit_list_insert_by_date(twos[i], &list); > @@ -737,6 +740,8 @@ static int remove_redundant(struct commit **array, int cnt) > redundant = xcalloc(cnt, 1); > filled_index = xmalloc(sizeof(*filled_index) * (cnt - 1)); > > + for (i = 0; i < cnt; i++) > + parse_commit(array[i]); > for (i = 0; i < cnt; i++) { > struct commit_list *common; > -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html