git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 02/20] merge-ort: add some high-level algorithm structure

From
Elijah Newren <newren@gmail.com>
Date
Oct 30, 2020, 03:41 UTC
Message-ID
<20201030034131.1479968-3-newren@gmail.com>
In-Reply-To
<20201030034131.1479968-1-newren@gmail.com>

merge_ort_nonrecursive_internal() will be used by both merge_inmemory_nonrecursive() and merge_inmemory_recursive(); let's focus on it for now. It involves some setup -- merge_start() -- followed by the following chain of functions:

  collect_merge_info()
    This function will populate merge_options_internal's paths field,
    via a call to traverse_trees() and a new callback that will be added
    later.
  detect_and_process_renames()
    This function will detect renames, and then adjust entries in paths
    to move conflict stages from old pathnames into those for new
    pathnames, so that the next step doesn't have to think about renames
    and just can do three-way content merging and such.
  process_entries()
    This function determines how to take the various stages (versions of
    a file from the three different sides) and merge them, and whether
    to mark the result as conflicted or cleanly merged.  It also writes
    out these merged file versions as it goes to create a tree.
Signed-off-by: Elijah Newren <newren@gmail.com>
---
 merge-ort.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 66 insertions(+), 1 deletion(-)
diff --git a/merge-ort.c b/merge-ort.c
index 9d5ea0930d..b53cd80104 100644
--- a/merge-ort.c
+++ b/merge-ort.c
@@ -18,6 +18,7 @@
 #include "merge-ort.h"
 
 #include "strmap.h"
+#include "tree.h"
 
 struct merge_options_internal {
 	struct strmap paths;    /* maps path -> (merged|conflict)_info */
@@ -57,6 +58,37 @@ struct conflict_info {
 	unsigned match_mask:3;
 };
 
+static int collect_merge_info(struct merge_options *opt,
+			      struct tree *merge_base,
+			      struct tree *side1,
+			      struct tree *side2)
+{
+	die("Not yet implemented.");
+}
+
+static int detect_and_process_renames(struct merge_options *opt,
+				      struct tree *merge_base,
+				      struct tree *side1,
+				      struct tree *side2)
+{
+	int clean = 1;
+
+	/*
+	 * Rename detection works by detecting file similarity.  Here we use
+	 * a really easy-to-implement scheme: files are similar IFF they have
+	 * the same filename.  Therefore, by this scheme, there are no renames.
+	 *
+	 * TODO: Actually implement a real rename detection scheme.
+	 */
+	return clean;
+}
+
+static void process_entries(struct merge_options *opt,
+			    struct object_id *result_oid)
+{
+	die("Not yet implemented.");
+}
+
 void merge_switch_to_result(struct merge_options *opt,
 			    struct tree *head,
 			    struct merge_result *result,
@@ -73,13 +105,46 @@ void merge_finalize(struct merge_options *opt,
 	die("Not yet implemented");
 }
 
+static void merge_start(struct merge_options *opt, struct merge_result *result)
+{
+	die("Not yet implemented.");
+}
+
+/*
+ * Originally from merge_trees_internal(); heavily adapted, though.
+ */
+static void merge_ort_nonrecursive_internal(struct merge_options *opt,
+					    struct tree *merge_base,
+					    struct tree *side1,
+					    struct tree *side2,
+					    struct merge_result *result)
+{
+	struct object_id working_tree_oid;
+
+	collect_merge_info(opt, merge_base, side1, side2);
+	result->clean = detect_and_process_renames(opt, merge_base,
+						   side1, side2);
+	process_entries(opt, &working_tree_oid);
+
+	/* Set return values */
+	result->tree = parse_tree_indirect(&working_tree_oid);
+	/* existence of unmerged entries implies unclean */
+	result->clean &= strmap_empty(&opt->priv->unmerged);
+	if (!opt->priv->call_depth) {
+		result->priv = opt->priv;
+		opt->priv = NULL;
+	}
+}
+
 void merge_incore_nonrecursive(struct merge_options *opt,
 			       struct tree *merge_base,
 			       struct tree *side1,
 			       struct tree *side2,
 			       struct merge_result *result)
 {
-	die("Not yet implemented");
+	assert(opt->ancestor != NULL);
+	merge_start(opt, result);
+	merge_ort_nonrecursive_internal(opt, merge_base, side1, side2, result);
 }
 
 void merge_incore_recursive(struct merge_options *opt,
-- 
2.29.1.56.ga287c268e6.dirty
Previous: Elijah NewrenNext: Elijah Newren
Message 5 of 22 in “fundamentals of merge-ort implementation”
  1. 00/20 fundamentals of merge-ort implementationElijah Newren, Oct 30, 2020
  2. 07/20 merge-ort: avoid repeating fill_tree_descriptor() on the same treeElijah Newren, Oct 30, 2020
  3. 04/20 merge-ort: use histogram diffElijah Newren, Oct 30, 2020
  4. 01/20 merge-ort: setup basic internal data structuresElijah Newren, Oct 30, 2020
  5. 02/20 merge-ort: add some high-level algorithm structureElijah Newren, Oct 30, 2020
  6. 06/20 merge-ort: implement a very basic collect_merge_info()Elijah Newren, Oct 30, 2020
  7. 13/20 merge-ort: step 1 of tree writing -- record basenames, modes, and oidsElijah Newren, Oct 30, 2020
  8. 11/20 merge-ort: add a preliminary simple process_entries() implementationElijah Newren, Oct 30, 2020
  9. 12/20 merge-ort: have process_entries operate in a defined orderElijah Newren, Oct 30, 2020
  10. 10/20 merge-ort: avoid recursing into identical treesElijah Newren, Oct 30, 2020
  11. 14/20 merge-ort: step 2 of tree writing -- function to create tree objectElijah Newren, Oct 30, 2020
  12. 15/20 merge-ort: step 3 of tree writing -- handling subdirectories as we goElijah Newren, Oct 30, 2020
  13. 20/20 merge-ort: free data structures in merge_finalize()Elijah Newren, Oct 30, 2020
  14. 19/20 merge-ort: add implementation of record_unmerged_index_entries()Elijah Newren, Oct 30, 2020
  15. 18/20 tree: enable cmp_cache_name_compare() to be used elsewhereElijah Newren, Oct 30, 2020
  16. 17/20 merge-ort: add implementation of checkout()Elijah Newren, Oct 30, 2020
  17. 16/20 merge-ort: basic outline for merge_switch_to_result()Elijah Newren, Oct 30, 2020
  18. 05/20 merge-ort: add an err() function similar to one from merge-recursiveElijah Newren, Oct 30, 2020
  19. 09/20 merge-ort: record stage and auxiliary info for every pathElijah Newren, Oct 30, 2020
  20. 03/20 merge-ort: port merge_start() from merge-recursiveElijah Newren, Oct 30, 2020
  21. 08/20 merge-ort: compute a few more useful fields for collect_merge_infoElijah Newren, Oct 30, 2020
  22. Elijah NewrenOct 30, 2020

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.