Re: [PATCH v7 25/31] merge-recursive: apply necessary modifications for directory renames

2018-02-15 Thread SZEDER Gábor
On Wed, Jan 31, 2018 at 12:25 AM, Elijah Newren  wrote:
> This commit hooks together all the directory rename logic by making the
> necessary changes to the rename struct, it's dst_entry, and the
> diff_filepair under consideration.
>
> Signed-off-by: Elijah Newren 
> ---
>  merge-recursive.c   | 187 
> +++-
>  t/t6043-merge-rename-directories.sh |  50 +-
>  2 files changed, 211 insertions(+), 26 deletions(-)
>
> diff --git a/merge-recursive.c b/merge-recursive.c
> index 38dc0eefaf..7c78dc2dc1 100644
> --- a/merge-recursive.c
> +++ b/merge-recursive.c

> @@ -641,6 +643,27 @@ static int update_stages(struct merge_options *opt, 
> const char *path,
> return 0;
>  }
>
> +static int update_stages_for_stage_data(struct merge_options *opt,
> +   const char *path,
> +   const struct stage_data *stage_data)
> +{
> +   struct diff_filespec o, a, b;
> +
> +   o.mode = stage_data->stages[1].mode;
> +   oidcpy(&o.oid, &stage_data->stages[1].oid);
> +
> +   a.mode = stage_data->stages[2].mode;
> +   oidcpy(&a.oid, &stage_data->stages[2].oid);
> +
> +   b.mode = stage_data->stages[3].mode;
> +   oidcpy(&b.oid, &stage_data->stages[3].oid);
> +
> +   return update_stages(opt, path,
> +is_null_sha1(o.oid.hash) ? NULL : &o,
> +is_null_sha1(a.oid.hash) ? NULL : &a,
> +is_null_sha1(b.oid.hash) ? NULL : &b);

Please use is_null_oid(&o.oid) etc. instead of is_null_sha1().


[PATCH v7 25/31] merge-recursive: apply necessary modifications for directory renames

2018-01-30 Thread Elijah Newren
This commit hooks together all the directory rename logic by making the
necessary changes to the rename struct, it's dst_entry, and the
diff_filepair under consideration.

Signed-off-by: Elijah Newren 
---
 merge-recursive.c   | 187 +++-
 t/t6043-merge-rename-directories.sh |  50 +-
 2 files changed, 211 insertions(+), 26 deletions(-)

diff --git a/merge-recursive.c b/merge-recursive.c
index 38dc0eefaf..7c78dc2dc1 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -177,6 +177,7 @@ static int oid_eq(const struct object_id *a, const struct 
object_id *b)
 
 enum rename_type {
RENAME_NORMAL = 0,
+   RENAME_DIR,
RENAME_DELETE,
RENAME_ONE_FILE_TO_ONE,
RENAME_ONE_FILE_TO_TWO,
@@ -607,6 +608,7 @@ struct rename {
 */
struct stage_data *src_entry;
struct stage_data *dst_entry;
+   unsigned add_turned_into_rename:1;
unsigned processed:1;
 };
 
@@ -641,6 +643,27 @@ static int update_stages(struct merge_options *opt, const 
char *path,
return 0;
 }
 
+static int update_stages_for_stage_data(struct merge_options *opt,
+   const char *path,
+   const struct stage_data *stage_data)
+{
+   struct diff_filespec o, a, b;
+
+   o.mode = stage_data->stages[1].mode;
+   oidcpy(&o.oid, &stage_data->stages[1].oid);
+
+   a.mode = stage_data->stages[2].mode;
+   oidcpy(&a.oid, &stage_data->stages[2].oid);
+
+   b.mode = stage_data->stages[3].mode;
+   oidcpy(&b.oid, &stage_data->stages[3].oid);
+
+   return update_stages(opt, path,
+is_null_sha1(o.oid.hash) ? NULL : &o,
+is_null_sha1(a.oid.hash) ? NULL : &a,
+is_null_sha1(b.oid.hash) ? NULL : &b);
+}
+
 static void update_entry(struct stage_data *entry,
 struct diff_filespec *o,
 struct diff_filespec *a,
@@ -1117,6 +1140,18 @@ static int merge_file_one(struct merge_options *o,
return merge_file_1(o, &one, &a, &b, branch1, branch2, mfi);
 }
 
+static int conflict_rename_dir(struct merge_options *o,
+  struct diff_filepair *pair,
+  const char *rename_branch,
+  const char *other_branch)
+{
+   const struct diff_filespec *dest = pair->two;
+
+   if (update_file(o, 1, &dest->oid, dest->mode, dest->path))
+   return -1;
+   return 0;
+}
+
 static int handle_change_delete(struct merge_options *o,
 const char *path, const char *old_path,
 const struct object_id *o_oid, int o_mode,
@@ -1386,6 +1421,24 @@ static int conflict_rename_rename_2to1(struct 
merge_options *o,
if (!ret)
ret = update_file(o, 0, &mfi_c2.oid, mfi_c2.mode,
  new_path2);
+   /*
+* unpack_trees() actually populates the index for us for
+* "normal" rename/rename(2to1) situtations so that the
+* correct entries are at the higher stages, which would
+* make the call below to update_stages_for_stage_data
+* unnecessary.  However, if either of the renames came
+* from a directory rename, then unpack_trees() will not
+* have gotten the right data loaded into the index, so we
+* need to do so now.  (While it'd be tempting to move this
+* call to update_stages_for_stage_data() to
+* apply_directory_rename_modifications(), that would break
+* our intermediate calls to would_lose_untracked() since
+* those rely on the current in-memory index.  See also the
+* big "NOTE" in update_stages()).
+*/
+   if (update_stages_for_stage_data(o, path, ci->dst_entry1))
+   ret = -1;
+
free(new_path2);
free(new_path1);
}
@@ -1919,6 +1972,111 @@ static char *check_for_directory_rename(struct 
merge_options *o,
return new_path;
 }
 
+static void apply_directory_rename_modifications(struct merge_options *o,
+struct diff_filepair *pair,
+char *new_path,
+struct rename *re,
+struct tree *tree,
+struct tree *o_tree,
+struct tree *a_tree,
+struct tree *b_tree,
+struct string_list *entries,
+