Author: rhuijben
Date: Thu Feb 21 19:30:53 2013
New Revision: 1448781

URL: http://svn.apache.org/r1448781
Log:
Fix a minor correctness issue in the wc-wc copy code that made us copy
nodes that were only used to shadow lower layers as not-present children
of their parent.

The commit logic automatically handles the not-present case correctly, so
it merely affects database correctness. But the difference is visible
in our move logic.

Note that I reviewed the direct and indirect users of
STMT_SELECT_OP_DEPTH_CHILDREN before committing. This part is necessary to
avoid insert invalid children as incomplete during copy, while not changing
them to a not-incomplete state later.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_SELECT_OP_DEPTH_CHILDREN): Really select the repository children, not
    just all children. Just like STMT_SELECT_GE_OP_DEPTH_CHILDREN already
    does.

* subversion/libsvn_wc/wc_db.c
  (get_info_for_copy): Simplify logic for adds by using more data from 
read_info.
     Avoid unneeded work for non-op-root-deletes, as we do want to trigger
     special behavior for them instead of seeing everything as a delete.

* subversion/tests/libsvn_wc/op-depth-test.c
  (move_to_swap): Add comment. Enable additional test. Expect the current buggy
     result.

Modified:
    subversion/trunk/subversion/libsvn_wc/wc-queries.sql
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c

Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1448781&r1=1448780&r2=1448781&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Thu Feb 21 19:30:53 
2013
@@ -276,8 +276,11 @@ WHERE wc_id = ?1 AND local_relpath = ?2 
 
 -- STMT_SELECT_OP_DEPTH_CHILDREN
 SELECT local_relpath, kind FROM nodes
-WHERE wc_id = ?1 AND parent_relpath = ?2 AND op_depth = ?3
-  AND (?3 != 0 OR file_external is NULL)
+WHERE wc_id = ?1 
+  AND parent_relpath = ?2
+  AND op_depth = ?3
+  AND presence != MAP_BASE_DELETED
+  AND file_external is NULL
 
 /* Used by non-recursive revert to detect higher level children, and
    actual-only rows that would be left orphans, if the revert

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1448781&r1=1448780&r2=1448781&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Thu Feb 21 19:30:53 2013
@@ -4051,15 +4051,21 @@ get_info_for_copy(apr_int64_t *copyfrom_
   const char *repos_relpath;
   svn_revnum_t revision;
   svn_wc__db_status_t node_status;
+  apr_int64_t repos_id;
+  svn_boolean_t is_op_root;
 
-  SVN_ERR(read_info(&node_status, kind, &revision, &repos_relpath, copyfrom_id,
-                    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                    NULL, NULL, NULL, NULL, NULL, op_root, NULL, NULL,
+  SVN_ERR(read_info(&node_status, kind, &revision, &repos_relpath, &repos_id,
+                    NULL, NULL, NULL, NULL, NULL, NULL, copyfrom_relpath,
+                    copyfrom_id, copyfrom_rev, NULL, NULL, NULL, NULL,
+                    NULL, &is_op_root, NULL, NULL,
                     NULL /* have_base */,
                     NULL /* have_more_work */,
                     NULL /* have_work */,
                     wcroot, local_relpath, result_pool, scratch_pool));
 
+  if (op_root)
+    *op_root = is_op_root;
+
   if (node_status == svn_wc__db_status_excluded)
     {
       /* The parent cannot be excluded, so look at the parent and then
@@ -4078,23 +4084,11 @@ get_info_for_copy(apr_int64_t *copyfrom_
     }
   else if (node_status == svn_wc__db_status_added)
     {
-      const char *op_root_relpath;
-
-      SVN_ERR(scan_addition(&node_status, &op_root_relpath,
-                            NULL, NULL, /* repos_* */
-                            copyfrom_relpath, copyfrom_id, copyfrom_rev,
+      SVN_ERR(scan_addition(&node_status, NULL, NULL, NULL, NULL, NULL, NULL,
                             NULL, NULL, NULL, wcroot, local_relpath,
                             scratch_pool, scratch_pool));
-      if (*copyfrom_relpath)
-        {
-          *copyfrom_relpath
-            = svn_relpath_join(*copyfrom_relpath,
-                               svn_relpath_skip_ancestor(op_root_relpath,
-                                                         local_relpath),
-                               result_pool);
-        }
     }
-  else if (node_status == svn_wc__db_status_deleted)
+  else if (node_status == svn_wc__db_status_deleted && is_op_root)
     {
       const char *base_del_relpath, *work_del_relpath;
 
@@ -4135,10 +4129,16 @@ get_info_for_copy(apr_int64_t *copyfrom_
       else
         SVN_ERR_MALFUNCTION();
     }
+  else if (node_status == svn_wc__db_status_deleted)
+    {
+      /* Keep original_* from read_info() to allow seeing the difference
+         between base-deleted and not present */
+    }
   else
     {
       *copyfrom_relpath = repos_relpath;
       *copyfrom_rev = revision;
+      *copyfrom_id = repos_id;
     }
 
   if (status)
@@ -4351,8 +4351,24 @@ db_op_copy(svn_wc__db_wcroot_t *src_wcro
               return SVN_NO_ERROR;
             }
         }
-      /* ### Else what??? (Reproducable with op_depth_tests.py move_to_swap */
-      /* else: fall through */
+      else
+        {
+          /* This node is either a not-present node (which should be copied), 
or
+             a base-delete of some lower layer (which shouldn't).
+             Subversion <= 1.7 always added a not-present node here, which is
+             safe (as it postpones the hard work until commit time and then we
+             ask the repository), but it breaks some move scenarios.
+             */
+
+           if (! copyfrom_relpath)
+             {
+               SVN_ERR(add_work_items(dst_wcroot->sdb, work_items,
+                                     scratch_pool));
+               return SVN_NO_ERROR;
+             }
+
+           /* Fall through. Install not present node */
+        }
     case svn_wc__db_status_not_present:
     case svn_wc__db_status_excluded:
       /* These presence values should not create a new op depth */

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=1448781&r1=1448780&r2=1448781&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Thu Feb 21 
19:30:53 2013
@@ -4078,6 +4078,7 @@ move_to_swap(const svn_test_opts_t *opts
   SVN_ERR(sbox_wc_move(&b, "X/Y", "A/Y"));
 
   {
+    /* Exact the same as before the initial moves */
     nodes_row_t nodes[] = {
       {0, "",    "normal",       1, ""},
       {0, "A",   "normal",       1, "A"},
@@ -4095,7 +4096,6 @@ move_to_swap(const svn_test_opts_t *opts
     SVN_ERR(check_db_rows(&b, "", nodes));
   }
 
-#if 0
   /* And try to undo the rest */
   SVN_ERR(sbox_wc_move(&b, "A", "A2"));
   SVN_ERR(sbox_wc_move(&b, "X", "A"));
@@ -4108,13 +4108,21 @@ move_to_swap(const svn_test_opts_t *opts
       {0, "A/B", "normal",       1, "A/B"},
       {0, "X",   "normal",       1, "X"},
       {0, "X/Y", "normal",       1, "X/Y"},
+
+      /* We shouldn't see this move, but somehow our move information
+         is lost in this move-back, so we can't find if it is copy-back
+         or a move-back */
+      {1, "A",   "normal",       1, "A"},
+      {1, "A/B", "normal",       1, "A/B", MOVED_HERE},
+
+      {1, "X",   "normal",       1, "X", FALSE, "A"},
+      {1, "X/Y", "normal",       1, "X/Y", MOVED_HERE},
+
       {0}
     };
-    /* ### Currently this breaks hard. Introducing not-present nodes, etc. 
-       ### but that is not caused by this change */
+
     SVN_ERR(check_db_rows(&b, "", nodes));
   }
-#endif
 
   return SVN_NO_ERROR;
 }


Reply via email to