Author: stsp
Date: Wed Oct 12 12:34:18 2016
New Revision: 1764447

URL: http://svn.apache.org/viewvc?rev=1764447&view=rev
Log:
Don't flag an unnecessary tree conflict while resolving 'add vs add'.

* subversion/libsvn_client/conflicts.c
  (merge_added_files): New helper function.
  (diff_file_added): If a file already exists then just merge with the
   incoming file and return.

* subversion/tests/libsvn_client/conflicts-test.c
  (test_merge_incoming_added_dir_merge, test_merge_incoming_added_dir_merge2,
   test_merge_incoming_added_dir_merge3): Adjust test expectations accordingly.



Modified:
    subversion/trunk/subversion/libsvn_client/conflicts.c
    subversion/trunk/subversion/tests/libsvn_client/conflicts-test.c

Modified: subversion/trunk/subversion/libsvn_client/conflicts.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/conflicts.c?rev=1764447&r1=1764446&r2=1764447&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/conflicts.c (original)
+++ subversion/trunk/subversion/libsvn_client/conflicts.c Wed Oct 12 12:34:18 
2016
@@ -5640,6 +5640,66 @@ diff_dir_added(const char *relpath,
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+merge_added_files(const char *local_abspath,
+                  const char *incoming_added_file_abspath,
+                  apr_hash_t *incoming_added_file_props,
+                  svn_client_ctx_t *ctx,
+                  apr_pool_t *scratch_pool)
+{
+  svn_wc_merge_outcome_t merge_content_outcome;
+  svn_wc_notify_state_t merge_props_outcome;
+  apr_file_t *empty_file;
+  const char *empty_file_abspath;
+  apr_array_header_t *propdiffs;
+  apr_hash_t *working_props;
+
+  /* Create an empty file as fake "merge-base" for the two added files.
+   * The files are not ancestrally related so this is the best we can do. */
+  SVN_ERR(svn_io_open_unique_file3(&empty_file, &empty_file_abspath, NULL,
+                                   svn_io_file_del_on_pool_cleanup,
+                                   scratch_pool, scratch_pool));
+
+  /* Get a copy of the working file's properties. */
+  SVN_ERR(svn_wc_prop_list2(&working_props, ctx->wc_ctx, local_abspath,
+                            scratch_pool, scratch_pool));
+
+  /* Create a property diff for the files. */
+  SVN_ERR(svn_prop_diffs(&propdiffs, incoming_added_file_props,
+                         working_props, scratch_pool));
+
+  /* Perform the file merge. */
+  SVN_ERR(svn_wc_merge5(&merge_content_outcome, &merge_props_outcome,
+                        ctx->wc_ctx, empty_file_abspath,
+                        incoming_added_file_abspath, local_abspath,
+                        NULL, NULL, NULL, /* labels */
+                        NULL, NULL, /* conflict versions */
+                        FALSE, /* dry run */
+                        NULL, NULL, /* diff3_cmd, merge_options */
+                        NULL, propdiffs,
+                        NULL, NULL, /* conflict func/baton */
+                        NULL, NULL, /* don't allow user to cancel here */
+                        scratch_pool));
+
+  if (ctx->notify_func2)
+    {
+      svn_wc_notify_t *notify = svn_wc_create_notify(
+                                   local_abspath,
+                                   svn_wc_notify_update_update,
+                                   scratch_pool);
+
+      if (merge_content_outcome == svn_wc_merge_conflict)
+        notify->content_state = svn_wc_notify_state_conflicted;
+      else
+        notify->content_state = svn_wc_notify_state_merged;
+      notify->prop_state = merge_props_outcome;
+      notify->kind = svn_node_file;
+      ctx->notify_func2(ctx->notify_baton2, notify, scratch_pool);
+    }
+
+  return SVN_NO_ERROR;
+}
+
 /* An svn_diff_tree_processor_t callback. */
 static svn_error_t *
 diff_file_added(const char *relpath,
@@ -5666,6 +5726,18 @@ diff_file_added(const char *relpath,
                             FALSE, FALSE, scratch_pool));
   SVN_ERR(svn_io_check_path(local_abspath, &on_disk_kind, scratch_pool));
 
+  if (db_kind == svn_node_file && db_kind == svn_node_file)
+    {
+      propsarray = svn_prop_hash_to_array(right_props, scratch_pool);
+      SVN_ERR(svn_categorize_props(propsarray, NULL, NULL, &regular_props,
+                                   scratch_pool));
+      SVN_ERR(merge_added_files(local_abspath, right_file,
+                                svn_prop_array_to_hash(regular_props,
+                                                       scratch_pool),
+                                b->ctx, scratch_pool));
+      return SVN_NO_ERROR;
+    }
+
   if (db_kind != svn_node_none && db_kind != svn_node_unknown)
     {
       SVN_ERR(raise_tree_conflict(

Modified: subversion/trunk/subversion/tests/libsvn_client/conflicts-test.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_client/conflicts-test.c?rev=1764447&r1=1764446&r2=1764447&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_client/conflicts-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_client/conflicts-test.c Wed Oct 12 
12:34:18 2016
@@ -792,31 +792,10 @@ test_merge_incoming_added_dir_merge(cons
                   props_conflicted->nelts == 0 &&
                   !tree_conflicted);
 
-
-  /* There should now be an 'add vs add' conflict on the new file. */
   new_file_path = svn_relpath_join(branch_path,
                                    svn_relpath_join(new_dir_name,
                                                     new_file_name, b->pool),
                                    b->pool);
-  SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, new_file_path),
-                                  ctx, b->pool, b->pool));
-  SVN_ERR(svn_client_conflict_get_conflicted(&text_conflicted,
-                                             &props_conflicted,
-                                             &tree_conflicted,
-                                             conflict, b->pool, b->pool));
-  SVN_TEST_ASSERT(!text_conflicted &&
-                  props_conflicted->nelts == 0 &&
-                  tree_conflicted);
-
-  /* Resolve the tree conflict. */
-  SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
-  SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, new_file_path),
-                                  ctx, b->pool, b->pool));
-  SVN_ERR(svn_client_conflict_tree_get_details(conflict, ctx, b->pool));
-  SVN_ERR(svn_client_conflict_tree_resolve_by_id(
-            conflict,
-            svn_client_conflict_option_incoming_added_file_text_merge, ctx,
-            b->pool));
 
   /* Ensure that the file has the expected status. */
   SVN_ERR(svn_client_status6(NULL, ctx, sbox_wc_path(b, new_file_path),
@@ -923,30 +902,10 @@ test_merge_incoming_added_dir_merge2(con
                   props_conflicted->nelts == 0 &&
                   !tree_conflicted);
 
-  /* There should now be an 'add vs add' conflict on the new file. */
   new_file_path = svn_relpath_join(branch_path,
                                    svn_relpath_join(new_dir_name,
                                                     new_file_name, b->pool),
                                    b->pool);
-  SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, new_file_path),
-                                  ctx, b->pool, b->pool));
-  SVN_ERR(svn_client_conflict_get_conflicted(&text_conflicted,
-                                             &props_conflicted,
-                                             &tree_conflicted,
-                                             conflict, b->pool, b->pool));
-  SVN_TEST_ASSERT(!text_conflicted &&
-                  props_conflicted->nelts == 0 &&
-                  tree_conflicted);
-
-  /* Resolve the tree conflict. */
-  SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
-  SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, new_file_path),
-                                  ctx, b->pool, b->pool));
-  SVN_ERR(svn_client_conflict_tree_get_details(conflict, ctx, b->pool));
-  SVN_ERR(svn_client_conflict_tree_resolve_by_id(
-            conflict,
-            svn_client_conflict_option_incoming_added_file_text_merge, ctx,
-            b->pool));
 
   /* Ensure that the file has the expected status. */
   SVN_ERR(svn_client_status6(NULL, ctx, sbox_wc_path(b, new_file_path),
@@ -1063,25 +1022,6 @@ test_merge_incoming_added_dir_merge3(con
                                    svn_relpath_join(new_dir_name,
                                                     new_file_name, b->pool),
                                    b->pool);
-  SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, new_file_path),
-                                  ctx, b->pool, b->pool));
-  SVN_ERR(svn_client_conflict_get_conflicted(&text_conflicted,
-                                             &props_conflicted,
-                                             &tree_conflicted,
-                                             conflict, b->pool, b->pool));
-  SVN_TEST_ASSERT(!text_conflicted &&
-                  props_conflicted->nelts == 0 &&
-                  tree_conflicted);
-
-  /* Resolve the tree conflict. */
-  SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
-  SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, new_file_path),
-                                  ctx, b->pool, b->pool));
-  SVN_ERR(svn_client_conflict_tree_get_details(conflict, ctx, b->pool));
-  SVN_ERR(svn_client_conflict_tree_resolve_by_id(
-            conflict,
-            svn_client_conflict_option_incoming_added_file_text_merge, ctx,
-            b->pool));
 
   /* Ensure that the file has the expected status. */
   SVN_ERR(svn_client_status6(NULL, ctx, sbox_wc_path(b, new_file_path),


Reply via email to