merge-ort: copy and adapt merge_3way() from merge-recursive.c

Take merge_3way() from merge-recursive.c and make slight adjustments based on different data structures (direct usage of object_id rather diff_filespec, separate pathnames which based on our careful interning of pathnames in opt->priv->paths can be compared with '!=' rather than 'strcmp'). Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Elijah Newren committed Jan 1, 2021 at 02:34 UTC f591c4724615b2fc1e4dc3d6bfe5da96a88eacbe
1 file changed +53 -1
merge-ort.c
+53 -1
@@ -23,6 +23,7 @@
23 #include "diff.h"
24 #include "diffcore.h"
25 #include "dir.h"
26 +#include "ll-merge.h"
27 #include "object-store.h"
28 #include "strmap.h"
29 #include "tree.h"
@@ -650,7 +651,58 @@ static int merge_3way(struct merge_options *opt,
651 const int extra_marker_size,
652 mmbuffer_t *result_buf)
653 {
653 - die("Not yet implemented.");
654 + mmfile_t orig, src1, src2;
655 + struct ll_merge_options ll_opts = {0};
656 + char *base, *name1, *name2;
657 + int merge_status;
658 +
659 + ll_opts.renormalize = opt->renormalize;
660 + ll_opts.extra_marker_size = extra_marker_size;
661 + ll_opts.xdl_opts = opt->xdl_opts;
662 +
663 + if (opt->priv->call_depth) {
664 + ll_opts.virtual_ancestor = 1;
665 + ll_opts.variant = 0;
666 + } else {
667 + switch (opt->recursive_variant) {
668 + case MERGE_VARIANT_OURS:
669 + ll_opts.variant = XDL_MERGE_FAVOR_OURS;
670 + break;
671 + case MERGE_VARIANT_THEIRS:
672 + ll_opts.variant = XDL_MERGE_FAVOR_THEIRS;
673 + break;
674 + default:
675 + ll_opts.variant = 0;
676 + break;
677 + }
678 + }
679 +
680 + assert(pathnames[0] && pathnames[1] && pathnames[2] && opt->ancestor);
681 + if (pathnames[0] == pathnames[1] && pathnames[1] == pathnames[2]) {
682 + base = mkpathdup("%s", opt->ancestor);
683 + name1 = mkpathdup("%s", opt->branch1);
684 + name2 = mkpathdup("%s", opt->branch2);
685 + } else {
686 + base = mkpathdup("%s:%s", opt->ancestor, pathnames[0]);
687 + name1 = mkpathdup("%s:%s", opt->branch1, pathnames[1]);
688 + name2 = mkpathdup("%s:%s", opt->branch2, pathnames[2]);
689 + }
690 +
691 + read_mmblob(&orig, o);
692 + read_mmblob(&src1, a);
693 + read_mmblob(&src2, b);
694 +
695 + merge_status = ll_merge(result_buf, path, &orig, base,
696 + &src1, name1, &src2, name2,
697 + opt->repo->index, &ll_opts);
698 +
699 + free(base);
700 + free(name1);
701 + free(name2);
702 + free(orig.ptr);
703 + free(src1.ptr);
704 + free(src2.ptr);
705 + return merge_status;
706 }
707
708 static int handle_content_merge(struct merge_options *opt,