On Wed, Apr 04, 2018 at 11:48:42AM -0400, Derrick Stolee wrote: > > diff --git a/commit.c b/commit.c > > index 858f4fdbc9..2566cba79f 100644 > > --- a/commit.c > > +++ b/commit.c > > @@ -1059,12 +1059,19 @@ int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit * > > { > > struct commit_list *bases; > > int ret = 0, i; > > + uint32_t min_generation = GENERATION_NUMBER_UNDEF; > > if (parse_commit(commit)) > > return ret; > > - for (i = 0; i < nr_reference; i++) > > + for (i = 0; i < nr_reference; i++) { > > if (parse_commit(reference[i])) > > return ret; > > + if (min_generation > reference[i]->generation) > > + min_generation = reference[i]->generation; > > + } > > + > > + if (commit->generation > min_generation) > > + return 0; > > bases = paint_down_to_common(commit, nr_reference, reference); > > if (commit->object.flags & PARENT2) > > This patch may suffice to speed up 'git branch --contains' instead of > needing to always use the 'git tag --contains' algorithm as considered in > [1]. I'd have to do some timings, but I suspect we may want to switch to the "tag --contains" algorithm anyway. This still does N independent merge-base operations, one per ref. So with enough refs, you're still better off throwing it all into one big traversal. -Peff