Author: philip
Date: Fri Dec 14 19:04:15 2012
New Revision: 1422041

URL: http://svn.apache.org/viewvc?rev=1422041&view=rev
Log:
Start adding tree-conflicts when following a move to resolve
a tree-conflict.

* subversion/libsvn_wc/wc_db_update_move.c
  (check_shadowed_node): Remove.
  (check_tree_conflict): New.
  (tc_editor_alter_directory, tc_editor_alter_file): Use check_tree_conflict
   instead of check_shadowed_node and do it earlier.
  (get_tc_info): Do the scan dance to get tree-conflicts from the working
   tree.

* subversion/tests/libsvn_wc/op-depth-test.c
  (test_funcs): Remove XFAIL from nested_move_update.

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=1422041&r1=1422040&r2=1422041&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c Fri Dec 14 
19:04:15 2012
@@ -220,26 +220,64 @@ update_working_props(svn_wc_notify_state
 }
 
 
-/* Check whether the node at LOCAL_RELPATH in the working copy at WCROOT
- * is shadowed by some node at a higher op depth than EXPECTED_OP_DEPTH. */
+/* If LOCAL_ABSPATH is shadowed then raise a tree-conflict on the root
+   of the obstruction if such a tree-conflict does not already exist. */
 static svn_error_t *
-check_shadowed_node(svn_boolean_t *is_shadowed,
-                    int expected_op_depth,
+check_tree_conflict(svn_boolean_t *is_conflicted,
+                    struct tc_editor_baton *b,
                     const char *local_relpath,
-                    svn_wc__db_wcroot_t *wcroot)
+                    apr_pool_t *scratch_pool)
 {
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
+  int dst_op_depth = relpath_depth(b->move_root_dst_relpath);
+  int op_depth;
+  const char *conflict_root_relpath = local_relpath;
+  svn_skel_t *conflict;
 
-  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+  SVN_ERR(svn_sqlite__get_statement(&stmt, b->wcroot->sdb,
                                     STMT_SELECT_LOWEST_WORKING_NODE));
-  SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
-                            expected_op_depth));
+  SVN_ERR(svn_sqlite__bindf(stmt, "isd", b->wcroot->wc_id, local_relpath,
+                            dst_op_depth));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
+  if (have_row)
+    op_depth = svn_sqlite__column_int(stmt, 0);
   SVN_ERR(svn_sqlite__reset(stmt));
 
-  *is_shadowed = have_row;
+  if (!have_row)
+    {
+      *is_conflicted = FALSE;
+      return SVN_NO_ERROR;
+    }
+
+  while (relpath_depth(conflict_root_relpath) > op_depth)
+    conflict_root_relpath = svn_relpath_dirname(conflict_root_relpath,
+                                                scratch_pool);
+
+  SVN_ERR(svn_wc__db_read_conflict_internal(&conflict, b->wcroot,
+                                            conflict_root_relpath,
+                                            scratch_pool, scratch_pool));
+
+  if (conflict)
+    /* ### TODO: check this is the right sort of tree-conflict? */
+    return SVN_NO_ERROR;
+
+  conflict = svn_wc__conflict_skel_create(scratch_pool);
+  SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(
+                     conflict, NULL,
+                     svn_dirent_join(b->wcroot->abspath, conflict_root_relpath,
+                                     scratch_pool),
+                     svn_wc_conflict_reason_moved_away,
+                     svn_wc_conflict_action_edit,
+                     scratch_pool,
+                     scratch_pool));
+
+  SVN_ERR(svn_wc__conflict_skel_set_op_update(conflict, b->old_version,
+                                              scratch_pool, scratch_pool));
+  SVN_ERR(svn_wc__db_mark_conflict_internal(b->wcroot, conflict_root_relpath,
+                                            conflict, scratch_pool));
 
+  *is_conflicted = TRUE;
   return SVN_NO_ERROR;
 }
 
@@ -258,9 +296,14 @@ tc_editor_alter_directory(void *baton,
   svn_kind_t move_dst_kind;
   working_node_version_t old_version, new_version;
   svn_wc__db_status_t status;
+  svn_boolean_t is_conflicted;
 
   SVN_ERR_ASSERT(expected_move_dst_revision == b->old_version->peg_rev);
 
+  SVN_ERR(check_tree_conflict(&is_conflicted, b, dst_relpath, scratch_pool));
+  if (is_conflicted)
+    return SVN_NO_ERROR;
+
   /* Get kind, revision, and checksum of the moved-here node. */
   SVN_ERR(svn_wc__db_depth_get_info(&status, &move_dst_kind, 
&move_dst_revision,
                                     &move_dst_repos_relpath, NULL, NULL, NULL,
@@ -280,59 +323,45 @@ tc_editor_alter_directory(void *baton,
 
   if (new_props)
     {
-      svn_boolean_t is_shadowed;
+      const char *dst_abspath = svn_dirent_join(b->wcroot->abspath,
+                                                dst_relpath,
+                                                scratch_pool);
+      svn_wc_notify_state_t prop_state;
+      svn_skel_t *conflict_skel = NULL;
+      apr_hash_t *actual_props;
+      apr_array_header_t *propchanges;
+
+      SVN_ERR(update_working_props(&prop_state, &conflict_skel,
+                                   &propchanges, &actual_props,
+                                   b->db, dst_abspath,
+                                   &old_version, &new_version,
+                                   b->result_pool, scratch_pool));
 
-      /* If the node is shadowed by a higher layer, we need to flag a 
-       * tree conflict and must not touch the working node. */
-      SVN_ERR(check_shadowed_node(&is_shadowed,
-                                  relpath_depth(b->move_root_dst_relpath),
-                                  dst_relpath, b->wcroot));
-      if (is_shadowed)
+      if (conflict_skel)
         {
-          /* ### TODO flag tree conflict */
+          SVN_ERR(create_conflict_markers(b->work_items, dst_abspath,
+                                          b->db, move_dst_repos_relpath,
+                                          conflict_skel,
+                                          &old_version, &new_version,
+                                          b->result_pool, scratch_pool));
+          SVN_ERR(svn_wc__db_mark_conflict_internal(b->wcroot, dst_relpath,
+                                                    conflict_skel,
+                                                    scratch_pool));
         }
-      else
-        {
-          const char *dst_abspath = svn_dirent_join(b->wcroot->abspath,
-                                                    dst_relpath,
-                                                    scratch_pool);
-          svn_wc_notify_state_t prop_state;
-          svn_skel_t *conflict_skel = NULL;
-          apr_hash_t *actual_props;
-          apr_array_header_t *propchanges;
-
-          SVN_ERR(update_working_props(&prop_state, &conflict_skel,
-                                       &propchanges, &actual_props,
-                                       b->db, dst_abspath,
-                                       &old_version, &new_version,
-                                       b->result_pool, scratch_pool));
-
-          if (conflict_skel)
-            {
-              SVN_ERR(create_conflict_markers(b->work_items, dst_abspath,
-                                              b->db, move_dst_repos_relpath,
-                                              conflict_skel,
-                                              &old_version, &new_version,
-                                              b->result_pool, scratch_pool));
-              SVN_ERR(svn_wc__db_mark_conflict_internal(b->wcroot, dst_relpath,
-                                                        conflict_skel,
-                                                        scratch_pool));
-            }
 
-          if (b->notify_func)
-            {
-              svn_wc_notify_t *notify;
+      if (b->notify_func)
+        {
+          svn_wc_notify_t *notify;
 
-              notify = svn_wc_create_notify(dst_abspath,
-                                            svn_wc_notify_update_update,
-                                            scratch_pool);
-              notify->kind = svn_node_dir;
-              notify->content_state = svn_wc_notify_state_inapplicable;
-              notify->prop_state = prop_state;
-              notify->old_revision = b->old_version->peg_rev;
-              notify->revision = b->new_version->peg_rev;
-              b->notify_func(b->notify_baton, notify, scratch_pool);
-            }
+          notify = svn_wc_create_notify(dst_abspath,
+                                        svn_wc_notify_update_update,
+                                        scratch_pool);
+          notify->kind = svn_node_dir;
+          notify->content_state = svn_wc_notify_state_inapplicable;
+          notify->prop_state = prop_state;
+          notify->old_revision = b->old_version->peg_rev;
+          notify->revision = b->new_version->peg_rev;
+          b->notify_func(b->notify_baton, notify, scratch_pool);
         }
     }
 
@@ -489,6 +518,11 @@ tc_editor_alter_file(void *baton,
   svn_revnum_t move_dst_revision;
   svn_kind_t move_dst_kind;
   working_node_version_t old_version, new_version;
+  svn_boolean_t is_conflicted;
+
+  SVN_ERR(check_tree_conflict(&is_conflicted, b, dst_relpath, scratch_pool));
+  if (is_conflicted)
+    return SVN_NO_ERROR;
 
   /* Get kind, revision, and checksum of the moved-here node. */
   SVN_ERR(svn_wc__db_depth_get_info(NULL, &move_dst_kind, &move_dst_revision,
@@ -514,30 +548,16 @@ tc_editor_alter_file(void *baton,
   if (!svn_checksum_match(new_checksum, old_version.checksum)
       /* ### || props have changed */)
     {
-      svn_boolean_t is_shadowed;
+      svn_skel_t *work_item;
 
-      /* If the node is shadowed by a higher layer, we need to flag a 
-       * tree conflict and must not touch the working file. */
-      SVN_ERR(check_shadowed_node(&is_shadowed,
-                                  relpath_depth(b->move_root_dst_relpath),
-                                  dst_relpath, b->wcroot));
-      if (is_shadowed)
-        {
-          /* ### TODO flag tree conflict */
-        }
-      else
-        {
-          svn_skel_t *work_item;
-
-          SVN_ERR(update_working_file(&work_item, dst_relpath,
-                                      move_dst_repos_relpath,
-                                      &old_version, &new_version,
-                                      b->wcroot, b->db,
-                                      b->notify_func, b->notify_baton,
-                                      b->result_pool, scratch_pool));
-          *b->work_items = svn_wc__wq_merge(*b->work_items, work_item,
-                                            b->result_pool);
-        }
+      SVN_ERR(update_working_file(&work_item, dst_relpath,
+                                  move_dst_repos_relpath,
+                                  &old_version, &new_version,
+                                  b->wcroot, b->db,
+                                  b->notify_func, b->notify_baton,
+                                  b->result_pool, scratch_pool));
+      *b->work_items = svn_wc__wq_merge(*b->work_items, work_item,
+                                        b->result_pool);
     }
 
   return SVN_NO_ERROR;
@@ -739,14 +759,55 @@ get_tc_info(svn_wc_operation_t *operatio
           const char *repos_relpath;
           svn_revnum_t revision;
           svn_node_kind_t node_kind;
+          svn_wc__db_status_t status;
+
+          /* The scan dance: read_info then scan_delete then base_get
+             or scan_addition.  Use the internal/relpath functions
+             here? */
+          SVN_ERR(svn_wc__db_read_info(&status, &kind, &revision,
+                                       &repos_relpath, &repos_root_url,
+                                       &repos_uuid, NULL, NULL, NULL, NULL,
+                                       NULL, NULL, NULL, NULL, NULL, NULL,
+                                       NULL, NULL, NULL, NULL, NULL, NULL,
+                                       NULL, NULL, NULL, NULL, NULL,
+                                       db, src_abspath, result_pool,
+                                       scratch_pool));
+          if (status == svn_wc__db_status_deleted)
+            {
+              const char *base_del_abspath, *work_del_abspath;
+              SVN_ERR(svn_wc__db_scan_deletion(&base_del_abspath, NULL,
+                                               &work_del_abspath,
+                                               NULL, db, src_abspath,
+                                               scratch_pool, scratch_pool));
+              SVN_ERR_ASSERT(base_del_abspath || work_del_abspath);
+              if (base_del_abspath)
+                {
+                  SVN_ERR(svn_wc__db_base_get_info(NULL, &kind, &revision,
+                                                   &repos_relpath,
+                                                   &repos_root_url,
+                                                   &repos_uuid,
+                                                   NULL, NULL, NULL, NULL, 
NULL,
+                                                   NULL, NULL, NULL, NULL, 
NULL,
+                                                   db, src_abspath, 
result_pool,
+                                                   scratch_pool));
+                }
+              else if (work_del_abspath)
+                {
+                  work_del_abspath = svn_dirent_dirname(work_del_abspath,
+                                                        scratch_pool);
+                  SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, &repos_relpath,
+                                                   &repos_root_url, 
&repos_uuid,
+                                                   NULL, NULL, NULL,
+                                                   &revision, NULL, NULL,
+                                                   db, work_del_abspath,
+                                                   scratch_pool, 
scratch_pool));
+                  repos_relpath = svn_relpath_join(repos_relpath,
+                                     svn_dirent_skip_ancestor(work_del_abspath,
+                                                              src_abspath),
+                                                   scratch_pool);
+                }
+            }
 
-          /* Construct new_version from BASE info. */
-          SVN_ERR(svn_wc__db_base_get_info(NULL, &kind, &revision,
-                                           &repos_relpath, &repos_root_url,
-                                           &repos_uuid, NULL, NULL, NULL, NULL,
-                                           NULL, NULL, NULL, NULL, NULL, NULL,
-                                           db, src_abspath, result_pool,
-                                           scratch_pool));
           node_kind = svn__node_kind_from_kind(kind);
           *new_version = svn_wc_conflict_version_create2(repos_root_url,
                                                          repos_uuid,

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=1422041&r1=1422040&r2=1422041&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Fri Dec 14 
19:04:15 2012
@@ -5325,7 +5325,7 @@ struct svn_test_descriptor_t test_funcs[
                        "mixed_rev_move"),
     SVN_TEST_OPTS_PASS(update_prop_mod_into_moved,
                        "update_prop_mod_into_moved"),
-    SVN_TEST_OPTS_XFAIL(nested_move_update,
+    SVN_TEST_OPTS_PASS(nested_move_update,
                        "nested_move_update"),
     SVN_TEST_NULL
   };


Reply via email to