Thread (37 messages) 37 messages, 4 authors, 2021-03-08

[PATCH v2 04/10] merge-ort: handle book-keeping around two- and three-way content merge

flat view
STALE2047d

From: Elijah Newren via GitGitGadget <hidden>
Date: 2021-01-01 02:35:52
Subsystem: the rest · Maintainer: Linus Torvalds

Revision v2 of 2 in this series.

Revisions (2)
  1. v1 [diff vs current]
  2. v2 current
From: Elijah Newren <redacted>

In addition to the content merge (which will go in a subsequent commit),
we need to worry about conflict messages, placing results in higher
order stages in case of a df_conflict, and making sure the results are
placed in ci->merged.result so that they will show up in the working
tree.  Take care of all that external book-keeping, moving the
simplistic just-take-HEAD code into the barebones handle_content_merge()
function for now.  Subsequent commits will flesh out
handle_content_merge().

Signed-off-by: Elijah Newren <redacted>
---
 merge-ort.c | 52 +++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 41 insertions(+), 11 deletions(-)
diff --git a/merge-ort.c b/merge-ort.c
index 1adc27a11bc..47e230fe341 100644
--- a/merge-ort.c
+++ b/merge-ort.c
@@ -640,7 +640,15 @@ static int handle_content_merge(struct merge_options *opt,
 				const int extra_marker_size,
 				struct version_info *result)
 {
-	die("Not yet implemented");
+	int clean = 0;
+	/*
+	 * TODO: Needs a two-way or three-way content merge, but we're
+	 * just being lazy and copying the version from HEAD and
+	 * leaving it as conflicted.
+	 */
+	result->mode = a->mode;
+	oidcpy(&result->oid, &a->oid);
+	return clean;
 }
 
 /*** Function Grouping: functions related to detect_and_process_renames(), ***
@@ -1138,16 +1146,38 @@ static void process_entry(struct merge_options *opt,
 		 */
 		die("Not yet implemented.");
 	} else if (ci->filemask >= 6) {
-		/*
-		 * TODO: Needs a two-way or three-way content merge, but we're
-		 * just being lazy and copying the version from HEAD and
-		 * leaving it as conflicted.
-		 */
-		ci->merged.clean = 0;
-		ci->merged.result.mode = ci->stages[1].mode;
-		oidcpy(&ci->merged.result.oid, &ci->stages[1].oid);
-		/* When we fix above, we'll call handle_content_merge() */
-		(void)handle_content_merge;
+		/* Need a two-way or three-way content merge */
+		struct version_info merged_file;
+		unsigned clean_merge;
+		struct version_info *o = &ci->stages[0];
+		struct version_info *a = &ci->stages[1];
+		struct version_info *b = &ci->stages[2];
+
+		clean_merge = handle_content_merge(opt, path, o, a, b,
+						   ci->pathnames,
+						   opt->priv->call_depth * 2,
+						   &merged_file);
+		ci->merged.clean = clean_merge &&
+				   !ci->df_conflict && !ci->path_conflict;
+		ci->merged.result.mode = merged_file.mode;
+		ci->merged.is_null = (merged_file.mode == 0);
+		oidcpy(&ci->merged.result.oid, &merged_file.oid);
+		if (clean_merge && ci->df_conflict) {
+			assert(df_file_index == 1 || df_file_index == 2);
+			ci->filemask = 1 << df_file_index;
+			ci->stages[df_file_index].mode = merged_file.mode;
+			oidcpy(&ci->stages[df_file_index].oid, &merged_file.oid);
+		}
+		if (!clean_merge) {
+			const char *reason = _("content");
+			if (ci->filemask == 6)
+				reason = _("add/add");
+			if (S_ISGITLINK(merged_file.mode))
+				reason = _("submodule");
+			path_msg(opt, path, 0,
+				 _("CONFLICT (%s): Merge conflict in %s"),
+				 reason, path);
+		}
 	} else if (ci->filemask == 3 || ci->filemask == 5) {
 		/* Modify/delete */
 		const char *modify_branch, *delete_branch;
-- 
gitgitgadget
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help