On Fri, Aug 16, 2019 at 2:33 PM Junio C Hamano <gitster@xxxxxxxxx> wrote: > > Elijah Newren <newren@xxxxxxxxx> writes: > > > @@ -3507,6 +3507,11 @@ int merge_recursive(struct merge_options *opt, > > struct commit *merged_common_ancestors; > > struct tree *mrtree; > > int clean; > > + int num_merge_bases; > > + struct strbuf merge_base_abbrev = STRBUF_INIT; > > + > > + if (!opt->call_depth) > > + assert(opt->ancestor == NULL); > > Hmph. Do we have anything to say on this field when call_depth is > not zero? Is it OK for opt->ancestor to be sometimes NULL and non > NULL some other times? I was specifically trying to add a check for external callers of merge_recursive() to make sure they called it correctly. Since merge_recursive() sets opt->ancestor before calling itself recursively, I had to hide the assertion behind an if-check, namely on call_depth. We could add an assertion that opt->ancestor != NULL when opt->call_depth > 0, but it seemed odd to document pre-conditions for how merge_recursive() calls itself. Anyway, this code block actually becomes a bit cleaner later in the series when I create separate merge_recursive() and merge_recursive_internal() functions, as the assertion can just go into merge_recursive() and not be protected by the opt->call_depth check. > > @@ -3528,6 +3533,7 @@ int merge_recursive(struct merge_options *opt, > > output_commit_title(opt, iter->item); > > } > > > > + num_merge_bases = commit_list_count(ca); > > Criss-cross merge with very large number of merge bases is rare, so > it is OK to count them all, even though we only care about "is it > zero, is it one, or is it two or more?" > > I suspect this does not have to count, though, if we really wanted > to avoid counting. > > > merged_common_ancestors = pop_commit(&ca); > > if (merged_common_ancestors == NULL) { > > /* if there is no common ancestor, use an empty tree */ > > Here is the case where we can already decide the ancestor name for > the later merge_trees() should be "empty tree". > > And if merged_common_ancestors is not NULL, ca may have run out (in > which case, we only have a single merge base), or ca still has > another merge base (in which case, we have two or more). So, if you > add > ancestor_name = "empty tree"; > } else if (ca) { > ancestor_name = "merged common ancestors"; > } else { > ancestor_name = abbrev_name(merged_common_ancestors); > } > > to that if() statement above, that should be sufficient, no? > > opt is used for inner merge in the for() loop, so you would probably > need another "char *" variable without contaminating opt->ancestor_name > at this point, and then assign the value in the temporary to the > opt->ancestor field where the original always assigned "merged > common ancestors". Sure, I can make these changes. > > @@ -3568,10 +3574,23 @@ int merge_recursive(struct merge_options *opt, > > if (!opt->call_depth) > > repo_read_index(opt->repo); > > > > - opt->ancestor = "merged common ancestors"; > > + switch (num_merge_bases) { > > + case 0: > > + opt->ancestor = "<empty tree>"; > > Also, I do not see a reason why you want angle bra-ket pair around > "empty tree". You are already using "merged common ancestors" > literal phrase without any special marker syntax. Oh good point; will drop.