Author: stsp
Date: Thu Jul 28 12:48:58 2011
New Revision: 1151824

URL: http://svn.apache.org/viewvc?rev=1151824&view=rev
Log:
Record correct moved-from information for nodes which are moved multiple times.

The sequence "svn mv A B; svn mv B C;" ended up incorrectly recording
"C moved-from B". It must record "C moved-from A" instead.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_UPDATE_MOVED_TO_RELPATH): New. Updates the moved-to relpath on the
   delete-half of a move. (Note that we update the moved-to column to get
   valid moved-from queries because, in the current implementation,
   moved-from information is inferred by a query on moved-to columns
   and is not actually stored in the DB.)

* subversion/libsvn_wc/wc_db.c
  (op_delete_txn): If the delete is the delete-half of a move, and the
   node being deleted was previously moved-here, fix up the moved-to
   relpath recorded on the delete-half of the original move.

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=1151824&r1=1151823&r2=1151824&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Thu Jul 28 12:48:58 
2011
@@ -1335,6 +1335,13 @@ WHERE wc_id = ?1
 SELECT local_relpath FROM nodes_current
 WHERE wc_id = ?1 AND moved_to = ?2
 
+-- 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)
+
 /* ------------------------------------------------------------------------- */
 
 /* Queries for verification. */

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1151824&r1=1151823&r2=1151824&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Thu Jul 28 12:48:58 2011
@@ -6033,6 +6033,7 @@ op_delete_txn(void *baton,
   svn_sqlite__stmt_t *stmt;
   apr_int64_t select_depth; /* Depth of what is to be deleted */
   svn_boolean_t refetch_depth = FALSE;
+  svn_boolean_t is_valid_moved_to_relpath = TRUE;
 
   SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb, STMT_CREATE_DELETE_LIST));
 
@@ -6067,6 +6068,40 @@ op_delete_txn(void *baton,
     }
   SVN_ERR(svn_sqlite__reset(stmt));
 
+  if (b->moved_to_relpath)
+    {
+      const char *moved_from_relpath;
+      const char *delete_op_root_relpath;
+
+      /* ### call scan_addition_txn() directly? */
+      if (status == svn_wc__db_status_added)
+        SVN_ERR(scan_addition(&status, NULL, NULL, NULL,
+                              NULL, NULL, NULL,
+                              &moved_from_relpath,
+                              &delete_op_root_relpath,
+                              wcroot, local_relpath,
+                              scratch_pool, scratch_pool));
+
+      if (status == svn_wc__db_status_moved_here &&
+          strcmp(moved_from_relpath, delete_op_root_relpath) == 0)
+        {
+          /* The node has already been moved 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. */
+          SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                            STMT_UPDATE_MOVED_TO_RELPATH));
+          SVN_ERR(svn_sqlite__bindf(stmt, "iss", wcroot->wc_id,
+                                    moved_from_relpath, b->moved_to_relpath));
+          SVN_ERR(svn_sqlite__step_done(stmt));
+          SVN_ERR(svn_sqlite__reset(stmt));
+
+          /* Make the delete processing below ignore moved-to info. */
+          is_valid_moved_to_relpath = FALSE;
+        }
+    }
+
   if (op_root)
     {
       svn_boolean_t below_base;
@@ -6134,7 +6169,7 @@ 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)
+      if (b->moved_to_relpath && is_valid_moved_to_relpath)
         SVN_ERR(svn_sqlite__bindf(stmt, "isiis",
                                   wcroot->wc_id, local_relpath,
                                   select_depth, b->delete_depth,


Reply via email to