subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rhuij...@apache.org
Subject svn commit: r1536383 - in /subversion/trunk/subversion: libsvn_wc/wc-queries.sql libsvn_wc/wc_db.c tests/libsvn_wc/op-depth-test.c
Date Mon, 28 Oct 2013 15:49:59 GMT
Author: rhuijben
Date: Mon Oct 28 15:49:58 2013
New Revision: 1536383

URL: http://svn.apache.org/r1536383
Log:
Following up on r1536350 update the detection logic of moves affected by the
delete operation to properly find moves 'through' the to be deleted nodes.

This resolves the assertion triggered by r1536350, by no longer updating nodes
that are not in the database. The proper handling for these node is left as
a TODO for a separate patch.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_SELECT_MOVED_FOR_DELETE): Extend query to directly report nodes that
    were moved in.

* subversion/libsvn_wc/wc_db.c
  (delete_node): Only clear move information after checking for to be updated
    moves. Update logic to use nested ifs and add a branch for the case where
    moves outside the delete range must be updated when the delete is not a
    move.

* subversion/tests/libsvn_wc/op-depth-test.c
  (move_twice_within_delete): New test, testing a case where multiple moves
    must be handled.
  (test_funcs): Add move_twice_within_delete.

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=1536383&r1=1536382&r2=1536383&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Mon Oct 28 15:49:58 2013
@@ -1530,8 +1530,17 @@ SELECT moved_to, local_relpath FROM node
 WHERE wc_id = ?1 AND op_depth > 0
   AND IS_STRICT_DESCENDANT_OF(moved_to, ?2)
 
+/* If the node is moved here (r.moved_here = 1) we are really interested in
+   where the node was moved from. To obtain that we need the op_depth, but
+   this form of select only allows a single return value */
 -- STMT_SELECT_MOVED_FOR_DELETE
-SELECT local_relpath, moved_to, op_depth FROM nodes
+SELECT local_relpath, moved_to, op_depth,
+       (SELECT CASE WHEN r.moved_here THEN r.op_depth END FROM nodes r
+        WHERE r.wc_id = ?1
+          AND r.local_relpath = n.local_relpath
+          AND r.op_depth < n.op_depth
+        ORDER BY r.op_depth DESC LIMIT 1) AS moved_here_op_depth
+ FROM nodes n
 WHERE wc_id = ?1
   AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND moved_to IS NOT NULL

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1536383&r1=1536382&r2=1536383&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Mon Oct 28 15:49:58 2013
@@ -7591,14 +7591,6 @@ delete_node(void *baton,
                                              b->moved_to_relpath));
       SVN_ERR(svn_sqlite__update(NULL, stmt));
     }
-  else
-    {
-      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                        STMT_CLEAR_MOVED_TO_DESCENDANTS));
-      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id,
-                                            local_relpath));
-      SVN_ERR(svn_sqlite__update(NULL, stmt));
-    }
 
   /* Find children that were moved out of the subtree rooted at this node.
    * We'll need to update their op-depth columns because their deletion
@@ -7618,42 +7610,74 @@ delete_node(void *baton,
           const char *child_relpath = svn_sqlite__column_text(stmt, 0, NULL);
           const char *mv_to_relpath = svn_sqlite__column_text(stmt, 1, NULL);
           int child_op_depth = svn_sqlite__column_int(stmt, 2);
+          svn_boolean_t child_moved_here = !svn_sqlite__column_is_null(stmt, 3);
+          
           svn_boolean_t fixup = FALSE;
 
-          if (!b->moved_to_relpath
-              && ! svn_relpath_skip_ancestor(local_relpath, mv_to_relpath))
-            {
-              /* Update the op-depth of an moved node below this tree */
-              fixup = TRUE;
-              child_op_depth = delete_depth;
-            }
-          else if (b->moved_to_relpath
-                   && delete_depth == child_op_depth)
+          if (! b->moved_to_relpath)
             {
-              /* Update the op-depth of a tree shadowed by this tree */
-              fixup = TRUE;
-              child_op_depth = delete_depth;
-            }
-          else if (b->moved_to_relpath
-                   && child_op_depth >= delete_depth
-                   && !svn_relpath_skip_ancestor(local_relpath, mv_to_relpath))
-            {
-              /* Update the move destination of something that is now moved
-                 away further */
+              int moved_here_depth;
 
-              child_relpath = svn_relpath_skip_ancestor(local_relpath, child_relpath);
+              /* Plain delete. Fixup move information of descendants that were
+                 moved here, or that were moved out */
 
-              if (child_relpath)
+              if (child_moved_here
+                  && (moved_here_depth = svn_sqlite__column_int(stmt, 3)) 
+                               >= delete_depth)
                 {
-                  child_relpath = svn_relpath_join(b->moved_to_relpath, child_relpath,
scratch_pool);
+                  /* The move we recorded here must be moved to the location
+                     this node had before it was moved here.
 
-                  if (child_op_depth > delete_depth
-                      && svn_relpath_skip_ancestor(local_relpath, child_relpath))
-                    child_op_depth = delete_depth;
-                  else
-                    child_op_depth = relpath_depth(child_relpath);
+                     This might contain multiple steps when the node was moved
+                     in several places within the to be deleted tree */
 
+                  /* ### TODO: Add logic */
+                }
+              else
+                {
+                  if (!svn_relpath_skip_ancestor(local_relpath, mv_to_relpath))
+                    {
+                      /* Update the op-depth of an moved node below this tree */
+                      fixup = TRUE;
+                      child_op_depth = delete_depth;
+                    }
+                }
+            }
+          else
+            {
+              /* The node is moved to a new location */
+
+              if (delete_depth == child_op_depth)
+                {
+                  /* Update the op-depth of a tree shadowed by this tree */
                   fixup = TRUE;
+                  child_op_depth = delete_depth;
+                }
+              else if (child_op_depth >= delete_depth
+                       && !svn_relpath_skip_ancestor(local_relpath,
+                                                     mv_to_relpath))
+                {
+                  /* Update the move destination of something that is now moved
+                     away further */
+
+                  child_relpath = svn_relpath_skip_ancestor(local_relpath,
+                                                            child_relpath);
+
+                  if (child_relpath)
+                    {
+                      child_relpath = svn_relpath_join(b->moved_to_relpath,
+                                                       child_relpath,
+                                                       scratch_pool);
+
+                      if (child_op_depth > delete_depth
+                           && svn_relpath_skip_ancestor(local_relpath,
+                                                        child_relpath))
+                        child_op_depth = delete_depth;
+                      else
+                        child_op_depth = relpath_depth(child_relpath);
+
+                      fixup = TRUE;
+                    }
                 }
             }
 
@@ -7677,6 +7701,15 @@ delete_node(void *baton,
       SVN_ERR(svn_sqlite__reset(stmt));
     }
 
+  if (!b->moved_to_relpath)
+    {
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+          STMT_CLEAR_MOVED_TO_DESCENDANTS));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id,
+          local_relpath));
+      SVN_ERR(svn_sqlite__update(NULL, stmt));
+    }
+
   if (op_root)
     {
       svn_boolean_t below_base;

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=1536383&r1=1536382&r2=1536383&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Mon Oct 28 15:49:58 2013
@@ -8670,6 +8670,83 @@ move_replace_ancestor_with_child(const s
     return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+move_twice_within_delete(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+    svn_test__sandbox_t b;
+
+    SVN_ERR(svn_test__sandbox_create(&b, "move_twice_within_delete", opts,
+        pool));
+
+    SVN_ERR(sbox_wc_mkdir(&b, "A"));
+    SVN_ERR(sbox_wc_mkdir(&b, "A/A"));
+    SVN_ERR(sbox_wc_mkdir(&b, "A/A/A"));
+
+    SVN_ERR(sbox_wc_commit(&b, ""));
+    SVN_ERR(sbox_wc_update(&b, "", 1));
+
+    SVN_ERR(sbox_wc_mkdir(&b, "B"));
+    SVN_ERR(sbox_wc_move(&b, "A", "B/A"));
+    SVN_ERR(sbox_wc_move(&b, "B/A/A", "B/AA"));
+    SVN_ERR(sbox_wc_move(&b, "B/AA/A", "AA"));
+
+    {
+      nodes_row_t nodes[] = {
+
+        { 0, "",          "normal",       1, "" },
+                          
+        { 0, "A",         "normal",       1, "A" },
+        { 0, "A/A",       "normal",       1, "A/A" },
+        { 0, "A/A/A",     "normal",       1, "A/A/A" },
+                          
+        { 1, "A",         "base-deleted", NO_COPY_FROM, "B/A" },
+        { 1, "A/A",       "base-deleted", NO_COPY_FROM },
+        { 1, "A/A/A",     "base-deleted", NO_COPY_FROM },
+                          
+        { 1, "AA",        "normal",       1, "A/A/A", MOVED_HERE },
+
+        { 1, "B",         "normal",       NO_COPY_FROM },
+        { 2, "B/A",       "normal",       1, "A",       MOVED_HERE },
+        { 2, "B/A/A",     "normal",       1, "A/A",     MOVED_HERE },
+        { 2, "B/A/A/A",   "normal",       1, "A/A/A",   MOVED_HERE },
+
+        { 3, "B/A/A",     "base-deleted", NO_COPY_FROM, "B/AA" },
+        { 3, "B/A/A/A",   "base-deleted", NO_COPY_FROM },
+
+        { 2, "B/AA",      "normal",       1, "A/A", MOVED_HERE},
+        { 2, "B/AA/A",    "normal",       1, "A/A/A", MOVED_HERE },
+
+        { 3, "B/AA/A",    "base-deleted", NO_COPY_FROM, "AA" },
+
+        { 0 },
+      };
+      SVN_ERR(check_db_rows(&b, "", nodes));
+    }
+
+    SVN_ERR(sbox_wc_delete(&b, "B"));
+
+    {
+      nodes_row_t nodes[] = {
+        { 0, "",        "normal", 1, "" },
+
+        { 0, "A",       "normal", 1, "A" },
+        { 0, "A/A",     "normal", 1, "A/A" },
+        { 0, "A/A/A",   "normal", 1, "A/A/A" },
+
+        { 1, "A",       "base-deleted", NO_COPY_FROM },
+        { 1, "A/A",     "base-deleted", NO_COPY_FROM },
+        { 1, "A/A/A",   "base-deleted", NO_COPY_FROM, "AA" },
+
+        { 1, "AA", "normal", 1, "A/A/A", MOVED_HERE },
+
+        { 0 },
+      };
+        SVN_ERR(check_db_rows(&b, "", nodes));
+    }
+
+    return SVN_NO_ERROR;
+}
+
 /* ---------------------------------------------------------------------- */
 /* The list of test functions */
 
@@ -8835,5 +8912,7 @@ struct svn_test_descriptor_t test_funcs[
                        "move more than once, revert intermediate"),
     SVN_TEST_OPTS_XFAIL(move_replace_ancestor_with_child,
                         "move replace ancestor with child"),
+    SVN_TEST_OPTS_XFAIL(move_twice_within_delete,
+                        "move twice and then delete"),
     SVN_TEST_NULL
   };



Mime
View raw message