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,