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));