@@ -631,6 +631,28 @@ static int collect_merge_info(struct merge_options *opt,
631631
632632/*** Function Grouping: functions related to threeway content merges ***/
633633
634+ static int merge_submodule (struct merge_options * opt ,
635+ const char * path ,
636+ const struct object_id * o ,
637+ const struct object_id * a ,
638+ const struct object_id * b ,
639+ struct object_id * result )
640+ {
641+ die ("Not yet implemented." );
642+ }
643+
644+ static int merge_3way (struct merge_options * opt ,
645+ const char * path ,
646+ const struct object_id * o ,
647+ const struct object_id * a ,
648+ const struct object_id * b ,
649+ const char * pathnames [3 ],
650+ const int extra_marker_size ,
651+ mmbuffer_t * result_buf )
652+ {
653+ die ("Not yet implemented." );
654+ }
655+
634656static int handle_content_merge (struct merge_options * opt ,
635657 const char * path ,
636658 const struct version_info * o ,
@@ -640,14 +662,129 @@ static int handle_content_merge(struct merge_options *opt,
640662 const int extra_marker_size ,
641663 struct version_info * result )
642664{
643- int clean = 0 ;
644665 /*
645- * TODO: Needs a two-way or three-way content merge, but we're
646- * just being lazy and copying the version from HEAD and
647- * leaving it as conflicted.
666+ * path is the target location where we want to put the file, and
667+ * is used to determine any normalization rules in ll_merge.
668+ *
669+ * The normal case is that path and all entries in pathnames are
670+ * identical, though renames can affect which path we got one of
671+ * the three blobs to merge on various sides of history.
672+ *
673+ * extra_marker_size is the amount to extend conflict markers in
674+ * ll_merge; this is neeed if we have content merges of content
675+ * merges, which happens for example with rename/rename(2to1) and
676+ * rename/add conflicts.
648677 */
649- result -> mode = a -> mode ;
650- oidcpy (& result -> oid , & a -> oid );
678+ unsigned clean = 1 ;
679+
680+ /*
681+ * handle_content_merge() needs both files to be of the same type, i.e.
682+ * both files OR both submodules OR both symlinks. Conflicting types
683+ * needs to be handled elsewhere.
684+ */
685+ assert ((S_IFMT & a -> mode ) == (S_IFMT & b -> mode ));
686+
687+ /* Merge modes */
688+ if (a -> mode == b -> mode || a -> mode == o -> mode )
689+ result -> mode = b -> mode ;
690+ else {
691+ /* must be the 100644/100755 case */
692+ assert (S_ISREG (a -> mode ));
693+ result -> mode = a -> mode ;
694+ clean = (b -> mode == o -> mode );
695+ /*
696+ * FIXME: If opt->priv->call_depth && !clean, then we really
697+ * should not make result->mode match either a->mode or
698+ * b->mode; that causes t6036 "check conflicting mode for
699+ * regular file" to fail. It would be best to use some other
700+ * mode, but we'll confuse all kinds of stuff if we use one
701+ * where S_ISREG(result->mode) isn't true, and if we use
702+ * something like 0100666, then tree-walk.c's calls to
703+ * canon_mode() will just normalize that to 100644 for us and
704+ * thus not solve anything.
705+ *
706+ * Figure out if there's some kind of way we can work around
707+ * this...
708+ */
709+ }
710+
711+ /*
712+ * Trivial oid merge.
713+ *
714+ * Note: While one might assume that the next four lines would
715+ * be unnecessary due to the fact that match_mask is often
716+ * setup and already handled, renames don't always take care
717+ * of that.
718+ */
719+ if (oideq (& a -> oid , & b -> oid ) || oideq (& a -> oid , & o -> oid ))
720+ oidcpy (& result -> oid , & b -> oid );
721+ else if (oideq (& b -> oid , & o -> oid ))
722+ oidcpy (& result -> oid , & a -> oid );
723+
724+ /* Remaining rules depend on file vs. submodule vs. symlink. */
725+ else if (S_ISREG (a -> mode )) {
726+ mmbuffer_t result_buf ;
727+ int ret = 0 , merge_status ;
728+ int two_way ;
729+
730+ /*
731+ * If 'o' is different type, treat it as null so we do a
732+ * two-way merge.
733+ */
734+ two_way = ((S_IFMT & o -> mode ) != (S_IFMT & a -> mode ));
735+
736+ merge_status = merge_3way (opt , path ,
737+ two_way ? & null_oid : & o -> oid ,
738+ & a -> oid , & b -> oid ,
739+ pathnames , extra_marker_size ,
740+ & result_buf );
741+
742+ if ((merge_status < 0 ) || !result_buf .ptr )
743+ ret = err (opt , _ ("Failed to execute internal merge" ));
744+
745+ if (!ret &&
746+ write_object_file (result_buf .ptr , result_buf .size ,
747+ blob_type , & result -> oid ))
748+ ret = err (opt , _ ("Unable to add %s to database" ),
749+ path );
750+
751+ free (result_buf .ptr );
752+ if (ret )
753+ return -1 ;
754+ clean &= (merge_status == 0 );
755+ path_msg (opt , path , 1 , _ ("Auto-merging %s" ), path );
756+ } else if (S_ISGITLINK (a -> mode )) {
757+ int two_way = ((S_IFMT & o -> mode ) != (S_IFMT & a -> mode ));
758+ clean = merge_submodule (opt , pathnames [0 ],
759+ two_way ? & null_oid : & o -> oid ,
760+ & a -> oid , & b -> oid , & result -> oid );
761+ if (opt -> priv -> call_depth && two_way && !clean ) {
762+ result -> mode = o -> mode ;
763+ oidcpy (& result -> oid , & o -> oid );
764+ }
765+ } else if (S_ISLNK (a -> mode )) {
766+ if (opt -> priv -> call_depth ) {
767+ clean = 0 ;
768+ result -> mode = o -> mode ;
769+ oidcpy (& result -> oid , & o -> oid );
770+ } else {
771+ switch (opt -> recursive_variant ) {
772+ case MERGE_VARIANT_NORMAL :
773+ clean = 0 ;
774+ oidcpy (& result -> oid , & a -> oid );
775+ break ;
776+ case MERGE_VARIANT_OURS :
777+ oidcpy (& result -> oid , & a -> oid );
778+ break ;
779+ case MERGE_VARIANT_THEIRS :
780+ oidcpy (& result -> oid , & b -> oid );
781+ break ;
782+ }
783+ }
784+ } else
785+ BUG ("unsupported object type in the tree: %06o for %s" ,
786+ a -> mode , path );
787+
651788 return clean ;
652789}
653790
0 commit comments