You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2013/11/05 15:19:32 UTC
svn commit: r1539007 - in /subversion/trunk/subversion/libsvn_wc:
wc-queries.sql wc_db.c
Author: rhuijben
Date: Tue Nov 5 14:19:32 2013
New Revision: 1539007
URL: http://svn.apache.org/r1539007
Log:
Apply more strict op_depth fixes to move handling to properly handle
shadowed moves.
* subversion/libsvn_wc/wc-queries.sql
(STMT_SELECT_OP_DEPTH_MOVED_TO): Match the requested node with its direct
shadowing move by a join.
(STMT_SELECT_MOVED_HERE): Remove unused query.
* subversion/libsvn_wc/wc_db.c
(clear_moved_here): Use the moved_to relative path, as that is unique,
because the moved_from relpath doesn't have to be. This also allows
removing a now unused query. Return error when the target is not found.
(db_base_remove): Update caller. Use different column of existing query.
(follow_moved_to): Simplify code, based on the new query. Don't hide moves
that don't specify the same revision or repos_relpath. While they are
out of sync they are still moves, that need to be tracked... or the
conflict handling isn't able to resolve the problem.
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=1539007&r1=1539006&r2=1539007&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Tue Nov 5 14:19:32 2013
@@ -425,24 +425,23 @@ WHERE work.wc_id = ?1 AND work.local_rel
LIMIT 1
-- STMT_SELECT_OP_DEPTH_MOVED_TO
-SELECT op_depth, moved_to, repos_path, revision
-FROM nodes
-WHERE wc_id = ?1 AND local_relpath = ?2
- AND op_depth <= (SELECT MIN(op_depth) FROM nodes
- WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > ?3)
-ORDER BY op_depth DESC
+SELECT n.op_depth, n.moved_to, p.repos_path, p.revision
+FROM nodes p
+LEFT JOIN nodes n
+ ON p.wc_id=n.wc_id AND p.local_relpath = n.local_relpath
+ AND n.op_depth = (SELECT MIN(d.op_depth)
+ FROM nodes d
+ WHERE d.wc_id = ?1
+ AND d.local_relpath = n.local_relpath
+ AND d.op_depth > ?3)
+WHERE p.wc_id = ?1 AND p.local_relpath = ?2 AND p.op_depth = ?3
+LIMIT 1
-- STMT_SELECT_MOVED_TO
SELECT moved_to
FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3
--- STMT_SELECT_MOVED_HERE
-SELECT moved_here, presence, repos_path, revision
-FROM nodes
-WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth >= ?3
-ORDER BY op_depth
-
-- STMT_SELECT_MOVED_BACK
SELECT u.local_relpath,
u.presence, u.repos_id, u.repos_path, u.revision,
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1539007&r1=1539006&r2=1539007&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Tue Nov 5 14:19:32 2013
@@ -2101,28 +2101,29 @@ svn_wc__db_base_add_not_present_node(svn
}
/* Recursively clear moved-here information at the copy-half of the move
- * which moved the node at SRC_RELPATH away. This transforms the move into
- * a simple copy. */
+ * which moved a node to MOVED_TO_RELPATH. This transforms this side of the
+ * move into a simple copy.
+ */
static svn_error_t *
-clear_moved_here(const char *src_relpath,
- svn_wc__db_wcroot_t *wcroot,
+clear_moved_here(svn_wc__db_wcroot_t *wcroot,
+ const char *moved_to_relpath,
apr_pool_t *scratch_pool)
{
svn_sqlite__stmt_t *stmt;
- const char *dst_relpath;
-
- SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_SELECT_MOVED_TO));
- SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
- src_relpath, relpath_depth(src_relpath)));
- SVN_ERR(svn_sqlite__step_row(stmt));
- dst_relpath = svn_sqlite__column_text(stmt, 0, scratch_pool);
- SVN_ERR(svn_sqlite__reset(stmt));
+ int affected_rows;
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_CLEAR_MOVED_HERE_RECURSIVE));
- SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
- dst_relpath, relpath_depth(dst_relpath)));
- SVN_ERR(svn_sqlite__step_done(stmt));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, moved_to_relpath,
+ relpath_depth(moved_to_relpath)));
+
+ SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
+
+ if (affected_rows == 0)
+ return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+ _("The node '%s' was not found."),
+ path_for_error_message(wcroot, moved_to_relpath,
+ scratch_pool));
return SVN_NO_ERROR;
}
@@ -2313,12 +2314,12 @@ db_base_remove(svn_wc__db_wcroot_t *wcro
iterpool = svn_pool_create(scratch_pool);
while (have_row)
{
- const char *child_relpath;
+ const char *moved_to_relpath;
svn_error_t *err;
svn_pool_clear(iterpool);
- child_relpath = svn_sqlite__column_text(stmt, 0, iterpool);
- err = clear_moved_here(child_relpath, wcroot, iterpool);
+ moved_to_relpath = svn_sqlite__column_text(stmt, 1, iterpool);
+ err = clear_moved_here(wcroot, moved_to_relpath, iterpool);
if (err)
return svn_error_compose_create(err, svn_sqlite__reset(stmt));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
@@ -12200,23 +12201,20 @@ svn_wc__db_scan_moved(const char **moved
/* ###
*/
static svn_error_t *
-follow_moved_to(apr_array_header_t **moved_tos,
- int op_depth,
- const char *repos_path,
- svn_revnum_t revision,
- svn_wc__db_wcroot_t *wcroot,
+follow_moved_to(svn_wc__db_wcroot_t *wcroot,
const char *local_relpath,
+ int op_depth,
+ apr_array_header_t **moved_tos,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
int working_op_depth;
- const char *ancestor_relpath, *node_moved_to = NULL;
+ const char *ancestor_relpath;
+ const char *node_moved_to = NULL;
int i;
- SVN_ERR_ASSERT((!op_depth && !repos_path) || (op_depth && repos_path));
-
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_SELECT_OP_DEPTH_MOVED_TO));
SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
@@ -12226,50 +12224,26 @@ follow_moved_to(apr_array_header_t **mov
{
working_op_depth = svn_sqlite__column_int(stmt, 0);
node_moved_to = svn_sqlite__column_text(stmt, 1, result_pool);
- if (!repos_path)
- {
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- if (!have_row || svn_sqlite__column_revnum(stmt, 0))
- return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND,
- svn_sqlite__reset(stmt),
- _("The base node '%s' was not found."),
- path_for_error_message(wcroot,
- local_relpath,
- scratch_pool));
- repos_path = svn_sqlite__column_text(stmt, 2, scratch_pool);
- revision = svn_sqlite__column_revnum(stmt, 3);
- }
- }
- SVN_ERR(svn_sqlite__reset(stmt));
- if (node_moved_to)
- {
- svn_boolean_t have_row2;
+ if (node_moved_to)
+ {
+ struct svn_wc__db_moved_to_t *moved_to;
- SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_SELECT_MOVED_HERE));
- SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, node_moved_to,
- relpath_depth(node_moved_to)));
- SVN_ERR(svn_sqlite__step(&have_row2, stmt));
- if (!have_row2 || !svn_sqlite__column_int(stmt, 0)
- || revision != svn_sqlite__column_revnum(stmt, 3)
- || strcmp(repos_path, svn_sqlite__column_text(stmt, 2, NULL)))
- node_moved_to = NULL;
- SVN_ERR(svn_sqlite__reset(stmt));
+ moved_to = apr_palloc(result_pool, sizeof(*moved_to));
+ moved_to->op_depth = working_op_depth;
+ moved_to->local_relpath = node_moved_to;
+ APR_ARRAY_PUSH(*moved_tos, struct svn_wc__db_moved_to_t *) = moved_to;
+ }
}
- if (node_moved_to)
- {
- struct svn_wc__db_moved_to_t *moved_to;
-
- moved_to = apr_palloc(result_pool, sizeof(*moved_to));
- moved_to->op_depth = working_op_depth;
- moved_to->local_relpath = node_moved_to;
- APR_ARRAY_PUSH(*moved_tos, struct svn_wc__db_moved_to_t *) = moved_to;
- }
+ SVN_ERR(svn_sqlite__reset(stmt));
- /* A working row with moved_to, or no working row, and we are done. */
- if (node_moved_to || !have_row)
+ if (!have_row)
+ return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+ _("The node '%s' was not found."),
+ path_for_error_message(wcroot, local_relpath,
+ scratch_pool));
+ else if (node_moved_to)
return SVN_NO_ERROR;
/* Need to handle being moved via an ancestor. */
@@ -12284,55 +12258,29 @@ follow_moved_to(apr_array_header_t **mov
STMT_SELECT_MOVED_TO));
SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, ancestor_relpath,
working_op_depth));
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- SVN_ERR_ASSERT(have_row);
+ SVN_ERR(svn_sqlite__step_row(stmt));
+
ancestor_moved_to = svn_sqlite__column_text(stmt, 0, scratch_pool);
SVN_ERR(svn_sqlite__reset(stmt));
if (ancestor_moved_to)
{
- node_moved_to
- = svn_relpath_join(ancestor_moved_to,
- svn_relpath_skip_ancestor(ancestor_relpath,
- local_relpath),
- result_pool);
-
- SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_SELECT_MOVED_HERE));
- SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, node_moved_to,
- relpath_depth(ancestor_moved_to)));
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- if (!have_row)
- ancestor_moved_to = NULL;
- else if (!svn_sqlite__column_int(stmt, 0))
- {
- svn_wc__db_status_t presence
- = svn_sqlite__column_token(stmt, 1, presence_map);
- if (presence != svn_wc__db_status_not_present)
- ancestor_moved_to = NULL;
- else
- {
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- if (!have_row && !svn_sqlite__column_int(stmt, 0))
- ancestor_moved_to = NULL;
- }
- }
- SVN_ERR(svn_sqlite__reset(stmt));
- if (!ancestor_moved_to)
- break;
- /* verify repos_path points back? */
- }
- if (ancestor_moved_to)
- {
struct svn_wc__db_moved_to_t *moved_to;
+ node_moved_to
+ = svn_relpath_join(ancestor_moved_to,
+ svn_relpath_skip_ancestor(ancestor_relpath,
+ local_relpath),
+ result_pool);
+
moved_to = apr_palloc(result_pool, sizeof(*moved_to));
moved_to->op_depth = working_op_depth;
moved_to->local_relpath = node_moved_to;
APR_ARRAY_PUSH(*moved_tos, struct svn_wc__db_moved_to_t *) = moved_to;
- SVN_ERR(follow_moved_to(moved_tos, relpath_depth(ancestor_moved_to),
- repos_path, revision, wcroot, node_moved_to,
- result_pool, scratch_pool));
+ SVN_ERR(follow_moved_to(wcroot, node_moved_to,
+ relpath_depth(ancestor_moved_to),
+ moved_tos, result_pool, scratch_pool));
+
break;
}
}
@@ -12360,9 +12308,9 @@ svn_wc__db_follow_moved_to(apr_array_hea
sizeof(struct svn_wc__db_moved_to_t *));
/* ### Wrap in a transaction */
- SVN_ERR(follow_moved_to(moved_tos, 0, NULL, SVN_INVALID_REVNUM,
- wcroot, local_relpath,
- result_pool, scratch_pool));
+ SVN_WC__DB_WITH_TXN(follow_moved_to(wcroot, local_relpath, 0, moved_tos,
+ result_pool, scratch_pool),
+ wcroot);
/* ### Convert moved_to to abspath */