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

[PATCH v3 08/20] merge-ort: compute a few more useful fields for collect_merge_info

From
Elijah Newren via GitGitGadget <gitgitgadget@gmail.com>
Date
Dec 13, 2020, 08:04 UTC
Message-ID
<be5708dc628b23e9f6d9b6088f86f033605759a4.1607846667.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.923.v3.git.git.1607846667.gitgitgadget@gmail.com>
From: Elijah Newren <newren@gmail.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
---
 merge-ort.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)
diff --git a/merge-ort.c b/merge-ort.c
index 690c64fe264..a6876191c02 100644
--- a/merge-ort.c
+++ b/merge-ort.c
@@ -220,6 +220,7 @@ static int collect_merge_info_callback(int n,
 	size_t len;
 	char *fullpath;
 	unsigned filemask = mask & ~dirmask;
+	unsigned match_mask = 0; /* will be updated below */
 	unsigned mbase_null = !(mask & 1);
 	unsigned side1_null = !(mask & 2);
 	unsigned side2_null = !(mask & 4);
@@ -233,6 +234,22 @@ static int collect_merge_info_callback(int n,
 				names[1].mode == names[2].mode &&
 				oideq(&names[1].oid, &names[2].oid));
 
+	/*
+	 * Note: When a path is a file on one side of history and a directory
+	 * in another, we have a directory/file conflict.  In such cases, if
+	 * the conflict doesn't resolve from renames and deletions, then we
+	 * always leave directories where they are and move files out of the
+	 * way.  Thus, while struct conflict_info has a df_conflict field to
+	 * track such conflicts, we ignore that field for any directories at
+	 * a path and only pay attention to it for files at the given path.
+	 * The fact that we leave directories were they are also means that
+	 * we do not need to worry about getting additional df_conflict
+	 * information propagated from parent directories down to children
+	 * (unlike, say traverse_trees_recursive() in unpack-trees.c, which
+	 * sets a newinfo.df_conflicts field specifically to propagate it).
+	 */
+	unsigned df_conflict = (filemask != 0) && (dirmask != 0);
+
 	/* n = 3 is a fundamental assumption. */
 	if (n != 3)
 		BUG("Called collect_merge_info_callback wrong");
@@ -248,6 +265,14 @@ static int collect_merge_info_callback(int n,
 	assert(!mbase_null || !side1_null || !side2_null);
 	assert(mask > 0 && mask < 8);
 
+	/* Determine match_mask */
+	if (side1_matches_mbase)
+		match_mask = (side2_matches_mbase ? 7 : 3);
+	else if (side2_matches_mbase)
+		match_mask = 5;
+	else if (sides_match)
+		match_mask = 6;
+
 	/*
 	 * Get the name of the relevant filepath, which we'll pass to
 	 * setup_path_info() for tracking.
@@ -266,6 +291,8 @@ static int collect_merge_info_callback(int n,
 	 * so we can resolve later in process_entries.
 	 */
 	ci = xcalloc(1, sizeof(struct conflict_info));
+	ci->df_conflict = df_conflict;
+	ci->match_mask = match_mask;
 	strmap_put(&opti->paths, fullpath, ci);
 
 	/* If dirmask, recurse into subdirectories */
@@ -282,6 +309,15 @@ static int collect_merge_info_callback(int n,
 		newinfo.name = p->path;
 		newinfo.namelen = p->pathlen;
 		newinfo.pathlen = st_add3(newinfo.pathlen, p->pathlen, 1);
+		/*
+		 * If this directory we are about to recurse into cared about
+		 * its parent directory (the current directory) having a D/F
+		 * conflict, then we'd propagate the masks in this way:
+		 *    newinfo.df_conflicts |= (mask & ~dirmask);
+		 * But we don't worry about propagating D/F conflicts.  (See
+		 * comment near setting of local df_conflict variable near
+		 * the beginning of this function).
+		 */
 
 		for (i = MERGE_BASE; i <= MERGE_SIDE2; i++) {
 			if (i == 1 && side1_matches_mbase)
-- 
gitgitgadget
Previous: Elijah Newren via GitGitGadgetNext: Elijah Newren via GitGitGadget
Message 53 of 70 in “fundamentals of merge-ort implementation”
  1. 00/20 fundamentals of merge-ort implementationElijah Newren via GitGitGadget, Nov 29, 2020
  2. 03/20 merge-ort: port merge_start() from merge-recursiveElijah Newren via GitGitGadget, Nov 29, 2020
  3. 02/20 merge-ort: add some high-level algorithm structureElijah Newren via GitGitGadget, Nov 29, 2020
  4. 04/20 merge-ort: use histogram diffElijah Newren via GitGitGadget, Nov 29, 2020
  5. 01/20 merge-ort: setup basic internal data structuresElijah Newren via GitGitGadget, Nov 29, 2020
  6. 07/20 merge-ort: avoid repeating fill_tree_descriptor() on the same treeElijah Newren via GitGitGadget, Nov 29, 2020
  7. 05/20 merge-ort: add an err() function similar to one from merge-recursiveElijah Newren via GitGitGadget, Nov 29, 2020
  8. Ævar Arnfjörð BjarmasonNov 29, 2020
  9. Elijah NewrenNov 30, 2020
  10. Ævar Arnfjörð BjarmasonNov 29, 2020
  11. 10/20 merge-ort: avoid recursing into identical treesElijah Newren via GitGitGadget, Nov 29, 2020
  12. 08/20 merge-ort: compute a few more useful fields for collect_merge_infoElijah Newren via GitGitGadget, Nov 29, 2020
  13. 06/20 merge-ort: implement a very basic collect_merge_info()Elijah Newren via GitGitGadget, Nov 29, 2020
  14. 11/20 merge-ort: add a preliminary simple process_entries() implementationElijah Newren via GitGitGadget, Nov 29, 2020
  15. 12/20 merge-ort: have process_entries operate in a defined orderElijah Newren via GitGitGadget, Nov 29, 2020
  16. 14/20 merge-ort: step 2 of tree writing -- function to create tree objectElijah Newren via GitGitGadget, Nov 29, 2020
  17. 09/20 merge-ort: record stage and auxiliary info for every pathElijah Newren via GitGitGadget, Nov 29, 2020
  18. 15/20 merge-ort: step 3 of tree writing -- handling subdirectories as we goElijah Newren via GitGitGadget, Nov 29, 2020
  19. 16/20 merge-ort: basic outline for merge_switch_to_result()Elijah Newren via GitGitGadget, Nov 29, 2020
  20. 13/20 merge-ort: step 1 of tree writing -- record basenames, modes, and oidsElijah Newren via GitGitGadget, Nov 29, 2020
  21. 19/20 merge-ort: add implementation of record_conflicted_index_entries()Elijah Newren via GitGitGadget, Nov 29, 2020
  22. Ævar Arnfjörð BjarmasonNov 29, 2020
  23. 18/20 tree: enable cmp_cache_name_compare() to be used elsewhereElijah Newren via GitGitGadget, Nov 29, 2020
  24. 17/20 merge-ort: add implementation of checkout()Elijah Newren via GitGitGadget, Nov 29, 2020
  25. 20/20 merge-ort: free data structures in merge_finalize()Elijah Newren via GitGitGadget, Nov 29, 2020
  26. Elijah NewrenNov 29, 2020
  27. 00/20 fundamentals of merge-ort implementationElijah Newren via GitGitGadget, Dec 4, 2020
  28. 02/20 merge-ort: add some high-level algorithm structureElijah Newren via GitGitGadget, Dec 4, 2020
  29. 03/20 merge-ort: port merge_start() from merge-recursiveElijah Newren via GitGitGadget, Dec 4, 2020
  30. 01/20 merge-ort: setup basic internal data structuresElijah Newren via GitGitGadget, Dec 4, 2020
  31. 05/20 merge-ort: add an err() function similar to one from merge-recursiveElijah Newren via GitGitGadget, Dec 4, 2020
  32. 04/20 merge-ort: use histogram diffElijah Newren via GitGitGadget, Dec 4, 2020
  33. 15/20 merge-ort: step 3 of tree writing -- handling subdirectories as we goElijah Newren via GitGitGadget, Dec 4, 2020
  34. 14/20 merge-ort: step 2 of tree writing -- function to create tree objectElijah Newren via GitGitGadget, Dec 4, 2020
  35. 07/20 merge-ort: avoid repeating fill_tree_descriptor() on the same treeElijah Newren via GitGitGadget, Dec 4, 2020
  36. 09/20 merge-ort: record stage and auxiliary info for every pathElijah Newren via GitGitGadget, Dec 4, 2020
  37. 11/20 merge-ort: add a preliminary simple process_entries() implementationElijah Newren via GitGitGadget, Dec 4, 2020
  38. 10/20 merge-ort: avoid recursing into identical treesElijah Newren via GitGitGadget, Dec 4, 2020
  39. 08/20 merge-ort: compute a few more useful fields for collect_merge_infoElijah Newren via GitGitGadget, Dec 4, 2020
  40. 19/20 merge-ort: add implementation of record_conflicted_index_entries()Elijah Newren via GitGitGadget, Dec 4, 2020
  41. 18/20 tree: enable cmp_cache_name_compare() to be used elsewhereElijah Newren via GitGitGadget, Dec 4, 2020
  42. 12/20 merge-ort: have process_entries operate in a defined orderElijah Newren via GitGitGadget, Dec 4, 2020
  43. 13/20 merge-ort: step 1 of tree writing -- record basenames, modes, and oidsElijah Newren via GitGitGadget, Dec 4, 2020
  44. 06/20 merge-ort: implement a very basic collect_merge_info()Elijah Newren via GitGitGadget, Dec 4, 2020
  45. 17/20 merge-ort: add implementation of checkout()Elijah Newren via GitGitGadget, Dec 4, 2020
  46. 16/20 merge-ort: basic outline for merge_switch_to_result()Elijah Newren via GitGitGadget, Dec 4, 2020
  47. 20/20 merge-ort: free data structures in merge_finalize()Elijah Newren via GitGitGadget, Dec 4, 2020
  48. 00/20 fundamentals of merge-ort implementationElijah Newren via GitGitGadget, Dec 13, 2020
  49. 01/20 merge-ort: setup basic internal data structuresElijah Newren via GitGitGadget, Dec 13, 2020
  50. 04/20 merge-ort: use histogram diffElijah Newren via GitGitGadget, Dec 13, 2020
  51. 03/20 merge-ort: port merge_start() from merge-recursiveElijah Newren via GitGitGadget, Dec 13, 2020
  52. 02/20 merge-ort: add some high-level algorithm structureElijah Newren via GitGitGadget, Dec 13, 2020
  53. 08/20 merge-ort: compute a few more useful fields for collect_merge_infoElijah Newren via GitGitGadget, Dec 13, 2020
  54. 06/20 merge-ort: implement a very basic collect_merge_info()Elijah Newren via GitGitGadget, Dec 13, 2020
  55. 07/20 merge-ort: avoid repeating fill_tree_descriptor() on the same treeElijah Newren via GitGitGadget, Dec 13, 2020
  56. 05/20 merge-ort: add an err() function similar to one from merge-recursiveElijah Newren via GitGitGadget, Dec 13, 2020
  57. 10/20 merge-ort: avoid recursing into identical treesElijah Newren via GitGitGadget, Dec 13, 2020
  58. 14/20 merge-ort: step 2 of tree writing -- function to create tree objectElijah Newren via GitGitGadget, Dec 13, 2020
  59. 12/20 merge-ort: have process_entries operate in a defined orderElijah Newren via GitGitGadget, Dec 13, 2020
  60. 16/20 merge-ort: basic outline for merge_switch_to_result()Elijah Newren via GitGitGadget, Dec 13, 2020
  61. 09/20 merge-ort: record stage and auxiliary info for every pathElijah Newren via GitGitGadget, Dec 13, 2020
  62. 18/20 tree: enable cmp_cache_name_compare() to be used elsewhereElijah Newren via GitGitGadget, Dec 13, 2020
  63. 15/20 merge-ort: step 3 of tree writing -- handling subdirectories as we goElijah Newren via GitGitGadget, Dec 13, 2020
  64. 17/20 merge-ort: add implementation of checkout()Elijah Newren via GitGitGadget, Dec 13, 2020
  65. 19/20 merge-ort: add implementation of record_conflicted_index_entries()Elijah Newren via GitGitGadget, Dec 13, 2020
  66. 20/20 merge-ort: free data structures in merge_finalize()Elijah Newren via GitGitGadget, Dec 13, 2020
  67. 13/20 merge-ort: step 1 of tree writing -- record basenames, modes, and oidsElijah Newren via GitGitGadget, Dec 13, 2020
  68. 11/20 merge-ort: add a preliminary simple process_entries() implementationElijah Newren via GitGitGadget, Dec 13, 2020
  69. Felipe ContrerasDec 14, 2020
  70. Elijah NewrenDec 14, 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.