Author: rhuijben
Date: Sun Feb  8 13:59:12 2015
New Revision: 1658171

URL: http://svn.apache.org/r1658171
Log:
Add obstruction detection when applying a file or directory edit during
move-update handling. This fixes the test scenario added in r1658166.

* subversion/libsvn_wc/wc_db_update_move.c
  (create_conflict_markers): Allow skipping operation setting when combining
    conflicts.

  (tc_editor_alter_directory,
   tc_editor_alter_file): Detect local obstructions and in that case don't
     apply in-wc updates, but do apply property changes.

* subversion/tests/libsvn_wc/op-depth-test.c
  (move_edit_obstruction): Use C syntax for comment. Extend.
  (test_list): Remove XFail marker from move_edit_obstruction.

Modified:
    subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c
    subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c

Modified: subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c?rev=1658171&r1=1658170&r2=1658171&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c Sun Feb  8 
13:59:12 2015
@@ -793,6 +793,7 @@ create_conflict_markers(svn_skel_t **wor
                         const working_node_version_t *old_version,
                         const working_node_version_t *new_version,
                         svn_node_kind_t kind,
+                        svn_boolean_t set_operation,
                         apr_pool_t *result_pool,
                         apr_pool_t *scratch_pool)
 {
@@ -813,19 +814,22 @@ create_conflict_markers(svn_skel_t **wor
     = svn_relpath_join(conflicted_version->path_in_repos, part, scratch_pool);
   original_version->path_in_repos = repos_relpath;
 
-  if (operation == svn_wc_operation_update)
+  if (set_operation)
     {
-      SVN_ERR(svn_wc__conflict_skel_set_op_update(
-                conflict_skel, original_version,
-                conflicted_version,
-                scratch_pool, scratch_pool));
-    }
-  else
-    {
-      SVN_ERR(svn_wc__conflict_skel_set_op_switch(
-                conflict_skel, original_version,
-                conflicted_version,
-                scratch_pool, scratch_pool));
+      if (operation == svn_wc_operation_update)
+        {
+          SVN_ERR(svn_wc__conflict_skel_set_op_update(
+                    conflict_skel, original_version,
+                    conflicted_version,
+                    scratch_pool, scratch_pool));
+        }
+      else
+        {
+          SVN_ERR(svn_wc__conflict_skel_set_op_switch(
+                    conflict_skel, original_version,
+                    conflicted_version,
+                    scratch_pool, scratch_pool));
+        }
     }
 
   /* According to this func's doc string, it is "Currently only used for
@@ -910,11 +914,26 @@ tc_editor_alter_directory(node_move_bato
   svn_wc_notify_state_t prop_state;
   apr_hash_t *actual_props;
   apr_array_header_t *propchanges;
+  svn_node_kind_t wc_kind;
+  svn_boolean_t obstructed = FALSE;
 
   SVN_ERR(mark_node_edited(nmb, scratch_pool));
   if (nmb->skip)
     return SVN_NO_ERROR;
 
+  SVN_ERR(svn_io_check_path(local_abspath, &wc_kind, scratch_pool));
+  if (wc_kind != svn_node_none && wc_kind != svn_node_dir)
+    {
+      SVN_ERR(create_node_tree_conflict(&conflict_skel, nmb, dst_relpath,
+                                        wc_kind, svn_node_dir,
+                                        NULL /* local obstruction relpath */,
+                                        svn_wc_conflict_reason_obstructed,
+                                        svn_wc_conflict_action_edit,
+                                        NULL,
+                                        scratch_pool, scratch_pool));
+      obstructed = TRUE;
+    }
+
   old_version.location_and_kind = b->old_version;
   new_version.location_and_kind = b->new_version;
 
@@ -929,7 +948,7 @@ tc_editor_alter_directory(node_move_bato
                                 &old_version, &new_version,
                                 scratch_pool, scratch_pool));
 
-  if (conflict_skel)
+  if (prop_state == svn_wc_notify_state_conflicted)
     {
       const char *move_dst_repos_relpath;
 
@@ -945,7 +964,7 @@ tc_editor_alter_directory(node_move_bato
                                       b->db, move_dst_repos_relpath,
                                       conflict_skel, b->operation,
                                       &old_version, &new_version,
-                                      svn_node_dir,
+                                      svn_node_dir, !obstructed,
                                       scratch_pool, scratch_pool));
     }
 
@@ -998,11 +1017,26 @@ tc_editor_alter_file(node_move_baton_t *
   enum svn_wc_merge_outcome_t merge_outcome;
   svn_wc_notify_state_t prop_state, content_state;
   svn_skel_t *work_item, *work_items = NULL;
+  svn_node_kind_t wc_kind;
+  svn_boolean_t obstructed = FALSE;
 
   SVN_ERR(mark_node_edited(nmb, scratch_pool));
   if (nmb->skip)
     return SVN_NO_ERROR;
 
+  SVN_ERR(svn_io_check_path(local_abspath, &wc_kind, scratch_pool));
+  if (wc_kind != svn_node_none && wc_kind != svn_node_file)
+    {
+      SVN_ERR(create_node_tree_conflict(&conflict_skel, nmb, dst_relpath,
+                                        wc_kind, svn_node_file,
+                                        NULL /* local obstruction relpath */,
+                                        svn_wc_conflict_reason_obstructed,
+                                        svn_wc_conflict_action_edit,
+                                        NULL,
+                                        scratch_pool, scratch_pool));
+      obstructed = TRUE;
+    }
+
   old_version.location_and_kind = b->old_version;
   new_version.location_and_kind = b->new_version;
 
@@ -1017,7 +1051,8 @@ tc_editor_alter_file(node_move_baton_t *
                                &old_version, &new_version,
                                scratch_pool, scratch_pool));
 
-  if (!svn_checksum_match(new_version.checksum, old_version.checksum))
+  if (!obstructed
+      && !svn_checksum_match(new_version.checksum, old_version.checksum))
     {
       svn_boolean_t is_locally_modified;
 
@@ -1097,7 +1132,7 @@ tc_editor_alter_file(node_move_baton_t *
       SVN_ERR(create_conflict_markers(&work_item, local_abspath, b->db,
                                       move_dst_repos_relpath, conflict_skel,
                                       b->operation, &old_version, &new_version,
-                                      svn_node_file,
+                                      svn_node_file, !obstructed,
                                       scratch_pool, scratch_pool));
 
       work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);

Modified: subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c?rev=1658171&r1=1658170&r2=1658171&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Sun Feb  8 
13:59:12 2015
@@ -10493,7 +10493,7 @@ move_edit_obstruction(const svn_test_opt
 
   SVN_ERR(sbox_file_write(&b, "A/B/E/alpha", "Update alpha"));
   SVN_ERR(sbox_wc_propset(&b, "a", "b", "A/B/F"));
-  SVN_ERR(sbox_wc_commit(&b, "")); // r2
+  SVN_ERR(sbox_wc_commit(&b, "")); /* r2 */
 
   SVN_ERR(sbox_wc_update(&b, "", 1));
 
@@ -10547,6 +10547,28 @@ move_edit_obstruction(const svn_test_opt
                           svn_wc_conflict_choose_mine_conflict));
 
   {
+    nodes_row_t nodes[] = {
+      {1, "A_mv",             "normal",       2, "A", MOVED_HERE},
+      {1, "A_mv/B",           "normal",       2, "A/B", MOVED_HERE},
+      {1, "A_mv/B/E",         "normal",       2, "A/B/E", MOVED_HERE},
+      {1, "A_mv/B/E/alpha",   "normal",       2, "A/B/E/alpha", MOVED_HERE},
+      {1, "A_mv/B/E/beta",    "normal",       2, "A/B/E/beta", MOVED_HERE},
+      {1, "A_mv/B/F",         "normal",       2, "A/B/F", MOVED_HERE, "a"},
+      {1, "A_mv/B/lambda",    "normal",       2, "A/B/lambda", MOVED_HERE},
+      {1, "A_mv/C",           "normal",       2, "A/C", MOVED_HERE},
+      {1, "A_mv/D",           "normal",       2, "A/D", MOVED_HERE},
+      {1, "A_mv/D/G",         "normal",       2, "A/D/G", MOVED_HERE},
+      {1, "A_mv/D/G/pi",      "normal",       2, "A/D/G/pi", MOVED_HERE},
+      {1, "A_mv/D/G/rho",     "normal",       2, "A/D/G/rho", MOVED_HERE},
+      {1, "A_mv/D/G/tau",     "normal",       2, "A/D/G/tau", MOVED_HERE},
+      {1, "A_mv/D/gamma",     "normal",       2, "A/D/gamma", MOVED_HERE},
+      {1, "A_mv/D/H",         "normal",       2, "A/D/H", MOVED_HERE},
+      {1, "A_mv/D/H/chi",     "normal",       2, "A/D/H/chi", MOVED_HERE},
+      {1, "A_mv/D/H/omega",   "normal",       2, "A/D/H/omega", MOVED_HERE},
+      {1, "A_mv/D/H/psi",     "normal",       2, "A/D/H/psi", MOVED_HERE},
+      {1, "A_mv/mu",          "normal",       2, "A/mu", MOVED_HERE},
+      {0}
+    };
     conflict_info_t conflicts[] = {
       { "A_mv/B/E/alpha", FALSE, FALSE, TRUE },
       { "A_mv/B/F", FALSE, FALSE, TRUE },
@@ -10554,6 +10576,7 @@ move_edit_obstruction(const svn_test_opt
       {0}
     };
 
+    SVN_ERR(check_db_rows(&b, "A_mv", nodes));
     SVN_ERR(check_db_conflicts(&b, "", conflicts));
   }
 
@@ -10765,7 +10788,7 @@ static struct svn_test_descriptor_t test
                        "nested move delete"),
     SVN_TEST_OPTS_XFAIL(move_within_mixed_move,
                         "move within mixed move"),
-    SVN_TEST_OPTS_XFAIL(move_edit_obstruction,
+    SVN_TEST_OPTS_PASS(move_edit_obstruction,
                        "move edit obstruction"),
     SVN_TEST_NULL
   };


Reply via email to