diff mbox series

[18/18] DO NOT SUBMIT: directory rename stuff for redo_after_renames

Message ID 786dc8f0c449958174a4cf5e98704d36f3ae4076.1610049687.git.gitgitgadget@gmail.com (mailing list archive)
State New, archived
Headers show
Series Add directory rename detection to merge-ort | expand

Commit Message

Elijah Newren Jan. 7, 2021, 8:01 p.m. UTC
From: Elijah Newren <newren@gmail.com>

I believe the
   ci->dirmask & sidemask
stuff was leftovers from before I added dirs_removed.  I think it's
dead, useless code; just need to check.

Also, the
   !mi || mi->clean
portions should only be triggerable once I do the redo_after_renames
stuff.

Signed-off-by: Elijah Newren <newren@gmail.com>
---
 merge-ort.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

Comments

Elijah Newren Jan. 7, 2021, 8:02 p.m. UTC | #1
Whoops.  Ignore this patch, of course.

On Thu, Jan 7, 2021 at 12:01 PM Elijah Newren via GitGitGadget
<gitgitgadget@gmail.com> wrote:
>
> From: Elijah Newren <newren@gmail.com>
>
> I believe the
>    ci->dirmask & sidemask
> stuff was leftovers from before I added dirs_removed.  I think it's
> dead, useless code; just need to check.
>
> Also, the
>    !mi || mi->clean
> portions should only be triggerable once I do the redo_after_renames
> stuff.
>
> Signed-off-by: Elijah Newren <newren@gmail.com>
> ---
>  merge-ort.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 45 insertions(+)
>
> diff --git a/merge-ort.c b/merge-ort.c
> index 55a835f8b97..1eb3a2e0fbb 100644
> --- a/merge-ort.c
> +++ b/merge-ort.c
> @@ -1031,6 +1031,48 @@ static void get_provisional_directory_renames(struct merge_options *opt,
>         }
>  }
>
> +static void remove_invalid_dir_renames(struct merge_options *opt,
> +                                      struct strmap *side_dir_renames,
> +                                      unsigned side_mask)
> +{
> +       struct hashmap_iter iter;
> +       struct strmap_entry *entry;
> +       struct string_list removable = STRING_LIST_INIT_NODUP;
> +       int i;
> +
> +       strmap_for_each_entry(side_dir_renames, &iter, entry) {
> +               struct merged_info *mi;
> +               struct conflict_info *ci;
> +
> +               mi = strmap_get(&opt->priv->paths, entry->key);
> +               INITIALIZE_CI(ci, mi);
> +               if (!mi ||
> +                   mi->clean ||
> +                   (ci->dirmask & side_mask)) {
> +                       /*
> +                        * !mi: This rename came from a directory that was
> +                        * unchanged on the other side of history, and NULL on
> +                        * our side.  No directory rename detection needed.
> +                        *
> +                        * mi->clean: Due to redo_after_renames, on the second
> +                        * run, collect_merge_info_callback was able to
> +                        * cleanly resolve the trivial directory merge without
> +                        * recursing.  As such, we know we don't need
> +                        * directory rename detection for it.
> +                        *
> +                        * ci->dirmask & side_mask: this directory "rename"
> +                        * isn't valid because the source directory name still
> +                        * exists on the destination side.
> +                        */
> +                       string_list_append(&removable, entry->key);
> +               }
> +       }
> +
> +       for (i=0; i<removable.nr; ++i)
> +               strmap_remove(side_dir_renames, removable.items[i].string, 0);
> +       string_list_clear(&removable, 0);
> +}
> +
>  static void handle_directory_level_conflicts(struct merge_options *opt)
>  {
>         struct hashmap_iter iter;
> @@ -1050,6 +1092,9 @@ static void handle_directory_level_conflicts(struct merge_options *opt)
>                 strmap_remove(side2_dir_renames, duplicated.items[i].string, 0);
>         }
>         string_list_clear(&duplicated, 0);
> +
> +       remove_invalid_dir_renames(opt, side1_dir_renames, (1 << MERGE_SIDE1));
> +       remove_invalid_dir_renames(opt, side2_dir_renames, (1 << MERGE_SIDE2));
>  }
>
>  static struct strmap_entry *check_dir_renamed(const char *path,
> --
> gitgitgadget
diff mbox series

Patch

diff --git a/merge-ort.c b/merge-ort.c
index 55a835f8b97..1eb3a2e0fbb 100644
--- a/merge-ort.c
+++ b/merge-ort.c
@@ -1031,6 +1031,48 @@  static void get_provisional_directory_renames(struct merge_options *opt,
 	}
 }
 
+static void remove_invalid_dir_renames(struct merge_options *opt,
+				       struct strmap *side_dir_renames,
+				       unsigned side_mask)
+{
+	struct hashmap_iter iter;
+	struct strmap_entry *entry;
+	struct string_list removable = STRING_LIST_INIT_NODUP;
+	int i;
+
+	strmap_for_each_entry(side_dir_renames, &iter, entry) {
+		struct merged_info *mi;
+		struct conflict_info *ci;
+
+		mi = strmap_get(&opt->priv->paths, entry->key);
+		INITIALIZE_CI(ci, mi);
+		if (!mi ||
+		    mi->clean ||
+		    (ci->dirmask & side_mask)) {
+			/*
+			 * !mi: This rename came from a directory that was
+			 * unchanged on the other side of history, and NULL on
+			 * our side.  No directory rename detection needed.
+			 *
+			 * mi->clean: Due to redo_after_renames, on the second
+			 * run, collect_merge_info_callback was able to
+			 * cleanly resolve the trivial directory merge without
+			 * recursing.  As such, we know we don't need
+			 * directory rename detection for it.
+			 *
+			 * ci->dirmask & side_mask: this directory "rename"
+			 * isn't valid because the source directory name still
+			 * exists on the destination side.
+			 */
+			string_list_append(&removable, entry->key);
+		}
+	}
+
+	for (i=0; i<removable.nr; ++i)
+		strmap_remove(side_dir_renames, removable.items[i].string, 0);
+	string_list_clear(&removable, 0);
+}
+
 static void handle_directory_level_conflicts(struct merge_options *opt)
 {
 	struct hashmap_iter iter;
@@ -1050,6 +1092,9 @@  static void handle_directory_level_conflicts(struct merge_options *opt)
 		strmap_remove(side2_dir_renames, duplicated.items[i].string, 0);
 	}
 	string_list_clear(&duplicated, 0);
+
+	remove_invalid_dir_renames(opt, side1_dir_renames, (1 << MERGE_SIDE1));
+	remove_invalid_dir_renames(opt, side2_dir_renames, (1 << MERGE_SIDE2));
 }
 
 static struct strmap_entry *check_dir_renamed(const char *path,