Author: stsp
Date: Sat Jul 30 01:18:20 2011
New Revision: 1152410

URL: http://svn.apache.org/viewvc?rev=1152410&view=rev
Log:
Store moved-to relpaths in the BASE tree (op_depth = 0) instead of
nodes_current. All move operations are relative to the BASE, so having
moved-to information in op_depth layer 0 is semantically more correct.

It will also make it easier to deal with stuff like cyclic moves and
replacements later. E.g. before this commit moved-to information was lost
if the delete-half of a move was replaced, and fixing this as a special
case in the code that adds the replacing node would have been ugly.

Also, clear moved-to relpaths from the BASE tree during 'revert' so
we don't leave phantom moved-to information in the DB (are there any
other places where we need to clear it?).

With help, ideas, testing, and lots of sanity-checking by Neels.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_INSERT_DELETE_NODE): Drop MOVED_TO parameter, we don't use this
   query anymore for adding moved-to relpaths because this query does not
   operate on BASE.
  (STMT_SELECT_MOVED_FROM_RELPATH,
   STMT_SELECT_MOVED_HERE_CHILDREN): Look in BASE instead of nodes_current.
  (STMT_UPDATE_MOVED_TO_RELPATH): Update BASE instead of nodes_current.
  (STMT_CLEAR_MOVED_TO_RELPATH,
   STMT_CLEAR_MOVED_TO_RELPATH_RECURSIVE): New statements for op_revert
    and op_revert_recursive.

* subversion/libsvn_wc/wc_db.c
  (op_revert_txn, op_revert_recursive_txn): Clear moved-to relpaths in BASE.
  (op_delete_txn): Use STMT_UPDATE_MOVED_TO_RELPATH instead of
   STMT_INSERT_DELETE_NODE to insert/update moved-to relpaths.

Patch by: me
          neels

Modified:
    subversion/trunk/subversion/libsvn_wc/wc-queries.sql
    subversion/trunk/subversion/libsvn_wc/wc_db.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=1152410&r1=1152409&r2=1152410&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Sat Jul 30 01:18:20 
2011
@@ -817,9 +817,9 @@ WHERE wc_id = ?1
 
 -- STMT_INSERT_DELETE_NODE
 INSERT INTO nodes (
-    wc_id, local_relpath, op_depth, parent_relpath, presence, kind, moved_to)
+    wc_id, local_relpath, op_depth, parent_relpath, presence, kind)
 SELECT wc_id, local_relpath, ?4 /*op_depth*/, parent_relpath, 'base-deleted',
-       kind, ?5 /* moved_to */
+       kind
 FROM nodes
 WHERE wc_id = ?1
   AND local_relpath = ?2
@@ -1332,19 +1332,29 @@ WHERE wc_id = ?1
   AND file_external IS NULL
 
 -- STMT_SELECT_MOVED_FROM_RELPATH
-SELECT local_relpath FROM nodes_current
-WHERE wc_id = ?1 AND moved_to = ?2
+SELECT local_relpath FROM nodes
+WHERE wc_id = ?1 AND moved_to = ?2 AND op_depth = 0
 
 -- STMT_UPDATE_MOVED_TO_RELPATH
-UPDATE NODES SET moved_to = ?3
-WHERE wc_id = ?1 AND local_relpath = ?2
-  AND op_depth =
-   (SELECT MAX(op_depth) FROM nodes
-    WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > 0)
+UPDATE nodes SET moved_to = ?3
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0
+
+-- STMT_CLEAR_MOVED_TO_RELPATH
+UPDATE nodes SET moved_to = NULL
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0
+
+-- STMT_CLEAR_MOVED_TO_RELPATH_RECURSIVE
+UPDATE nodes SET moved_to = NULL
+WHERE wc_id = ?1
+  AND (?2 = ''
+       OR local_relpath = ?2
+       OR (local_relpath > ?2 || '/' AND local_relpath < ?2 || '0'))
+  AND op_depth = 0
 
 -- STMT_SELECT_MOVED_HERE_CHILDREN
-SELECT moved_to, local_relpath FROM nodes_current
-WHERE wc_id = ?1 AND (moved_to > ?2 || '/' AND moved_to < ?2 || '0')
+SELECT moved_to, local_relpath FROM nodes
+WHERE wc_id = ?1 AND op_depth = 0
+  AND (moved_to > ?2 || '/' AND moved_to < ?2 || '0')
 
 /* ------------------------------------------------------------------------- */
 

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1152410&r1=1152409&r2=1152410&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Sat Jul 30 01:18:20 2011
@@ -5251,6 +5251,13 @@ op_revert_txn(void *baton,
                                         STMT_DELETE_WC_LOCK_ORPHAN));
       SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
       SVN_ERR(svn_sqlite__step_done(stmt));
+
+      /* Clear the moved-to path of the BASE node. */
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_CLEAR_MOVED_TO_RELPATH));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+      SVN_ERR(svn_sqlite__reset(stmt));
     }
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
@@ -5347,6 +5354,13 @@ op_revert_recursive_txn(void *baton,
                             local_relpath));
   SVN_ERR(svn_sqlite__step_done(stmt));
 
+  /* Clear any moved-to paths of the BASE nodes. */
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_CLEAR_MOVED_TO_RELPATH_RECURSIVE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+  SVN_ERR(svn_sqlite__reset(stmt));
+
   return SVN_NO_ERROR;
 }
 
@@ -6083,11 +6097,8 @@ op_delete_txn(void *baton,
       if (status == svn_wc__db_status_moved_here)
         {
           /* The node has already been moved, possibly along with a parent,
-           * and is being moved again.
-           * Update the existing moved_to path at the delete-half of
-           * the prior move. The source of a move is in the BASE tree
-           * so it remains constant if a node is moved around multiple
-           * times. */
+           * and is being moved again. Update the existing moved_to path
+           * in the BASE node. */
           SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                             STMT_UPDATE_MOVED_TO_RELPATH));
           SVN_ERR(svn_sqlite__bindf(stmt, "iss", wcroot->wc_id,
@@ -6256,18 +6267,22 @@ op_delete_txn(void *baton,
       /* Delete the node at LOCAL_RELPATH, and possibly mark it as moved. */
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                  STMT_INSERT_DELETE_NODE));
-      if (b->moved_to_relpath)
-        SVN_ERR(svn_sqlite__bindf(stmt, "isiis",
-                                  wcroot->wc_id, local_relpath,
-                                  select_depth, b->delete_depth,
-                                  b->moved_to_relpath));
-      else
-        SVN_ERR(svn_sqlite__bindf(stmt, "isii",
-                                  wcroot->wc_id, local_relpath,
-                                  select_depth, b->delete_depth));
-
+      SVN_ERR(svn_sqlite__bindf(stmt, "isii",
+                                wcroot->wc_id, local_relpath,
+                                select_depth, b->delete_depth));
       SVN_ERR(svn_sqlite__step_done(stmt));
 
+      if (b->moved_to_relpath)
+        {
+          /* Record moved-to relpath in BASE. */
+          SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                            STMT_UPDATE_MOVED_TO_RELPATH));
+          SVN_ERR(svn_sqlite__bindf(stmt, "iss",
+                                    wcroot->wc_id, local_relpath,
+                                    b->moved_to_relpath));
+          SVN_ERR(svn_sqlite__step_done(stmt));
+        }
+
       /* Delete children, if any. */
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                  STMT_INSERT_DELETE_FROM_NODE_RECURSIVE));


Reply via email to