On Fri, Jun 11, 2021 at 10:57 AM Felipe Contreras <felipe.contreras@xxxxxxxxx> wrote: > Elijah Newren wrote: > > On Fri, Jun 11, 2021 at 8:32 AM Felipe Contreras <felipe.contreras@xxxxxxxxx> > > wrote: ... > > The alternative to the above two options was the > > make-a-virtual-merge-base-by-merging-merge-bases strategy. It apparently > > was very successful. > > OK. That makes sense. > > > But it does mean that merge bases can have conflict markers in them. > > But why? And even if they do, why do they have to be diff3 conflict > markers? This could be changed; I suspect it just was a natural consequence of how the code was built. (Recursive means there's not a separate code-path for merging the merge-bases, so they get the same merge style by default.) > This would be more human-friendly: > > <<<<<<< HEAD > D > ||||||| merged common ancestors > <<<<<<<<< Temporary merge branch 1 > B > ========= > A > >>>>>>>>> Temporary merge branch 2 > ======= > C > >>>>>>> C I suspect that would be as easy as this (not compiled or tested): diff --git a/ll-merge.c b/ll-merge.c index 095a4d820e..bdd129cbd6 100644 --- a/ll-merge.c +++ b/ll-merge.c @@ -131,7 +131,7 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused, xmp.level = XDL_MERGE_ZEALOUS; xmp.favor = opts->variant; xmp.xpp.flags = opts->xdl_opts; - if (git_xmerge_style >= 0) + if (git_xmerge_style >= 0 && !opts->virtual_ancestor) xmp.style = git_xmerge_style; if (marker_size > 0) xmp.marker_size = marker_size; > Or just put a stub conflict marker: > > <<<<<<< HEAD > D > ||||||| merged common ancestors > <<<<<<<<< Temporary merge >>>>>>>>> > ======= > C > >>>>>>> C I don't know what would be involved to do this one; I think it wouldn't be too hard, but I don't think we'd want to pursue this option. > Or just use the base of the virtual merge: > > <<<<<<< HEAD > D > ||||||| merged common ancestors > 1 > ======= > C > >>>>>>> C I think that implementing this choice would look like this (again, not compiled or tested and I'm not familiar with xdiff so take it with a big grain of salt): diff --git a/ll-merge.c b/ll-merge.c index 095a4d820e..dbc7f76951 100644 --- a/ll-merge.c +++ b/ll-merge.c @@ -130,6 +130,8 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused, memset(&xmp, 0, sizeof(xmp)); xmp.level = XDL_MERGE_ZEALOUS; xmp.favor = opts->variant; + if (git_xmerge_style >= 0 && opts->virtual_ancestor) + xmp.favor = XDL_MERGE_FAVOR_BASE; xmp.xpp.flags = opts->xdl_opts; if (git_xmerge_style >= 0) xmp.style = git_xmerge_style; diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h index 8629ae287c..b8d1a536c2 100644 --- a/xdiff/xdiff.h +++ b/xdiff/xdiff.h @@ -62,6 +62,7 @@ extern "C" { #define XDL_MERGE_FAVOR_OURS 1 #define XDL_MERGE_FAVOR_THEIRS 2 #define XDL_MERGE_FAVOR_UNION 3 +#define XDL_MERGE_FAVOR_BASE 4 /* merge output styles */ #define XDL_MERGE_DIFF3 1 diff --git a/xdiff/xmerge.c b/xdiff/xmerge.c index 95871a0b6e..a8dc42595a 100644 --- a/xdiff/xmerge.c +++ b/xdiff/xmerge.c @@ -313,6 +313,9 @@ static int xdl_fill_merge_buffer(xdfenv_t *xe1, const char *name1, if (m->mode & 2) size += xdl_recs_copy(xe2, m->i2, m->chg2, 0, 0, dest ? dest + size : NULL); + } else if (m->mode == 4) { + size += xdl_orig_copy(xe1, m->i0, m->chg0, needs_cr, 0, + dest ? dest + size : NULL); } else continue; i = m->i1 + m->chg1; > We don't have to use diff3 all the way. Right, thus my mention in the other email to consider adding a XDL_MERGE_FAVOR_BASE -- which you then also mention here in your third option, and which I've now given at least a partial patch for. Not sure if it's a crazy idea or a great idea, since I don't do very many criss-cross merges myself. Hope that helps, Elijah