You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ph...@apache.org on 2011/02/21 18:53:42 UTC
svn commit: r1073093 - in /subversion/trunk/subversion:
libsvn_wc/wc-queries.sql libsvn_wc/wc_db.c libsvn_wc/wc_db.h
tests/libsvn_wc/op-depth-test.c
Author: philip
Date: Mon Feb 21 17:53:41 2011
New Revision: 1073093
URL: http://svn.apache.org/viewvc?rev=1073093&view=rev
Log:
Start a new recursive revert implementation, the library and client
still use the old implementation.
* subversion/libsvn_wc/wc_db.h
(svn_wc__db_op_revert): Add depth parameter
* subversion/libsvn_wc/wc_db.c
(op_revert_recursive_txn): New.
(svn_wc__db_op_revert): Add depth parameter
* subversion/libsvn_wc/wc-queries.sql
(STMT_DELETE_NODES_RECURSIVE, STMT_DELETE_ACTUAL_NODE_RECURSIVE): New.
* subversion/tests/libsvn_wc/op-depth-test.c
(revert): Add depth parameter.
(test_op_revert): Adjust calls to revert, add recursive cases.
Modified:
subversion/trunk/subversion/libsvn_wc/wc-queries.sql
subversion/trunk/subversion/libsvn_wc/wc_db.c
subversion/trunk/subversion/libsvn_wc/wc_db.h
subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.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=1073093&r1=1073092&r2=1073093&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Mon Feb 21 17:53:41 2011
@@ -338,10 +338,19 @@ WHERE wc_id = ?1 AND local_relpath = ?2
DELETE FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2;
+-- STMT_DELETE_NODES_RECURSIVE
+DELETE FROM nodes
+WHERE wc_id = ?1 AND (local_relpath = ?2 OR local_relpath LIKE ?3 ESCAPE '#')
+ AND op_depth >= ?4;
+
-- STMT_DELETE_ACTUAL_NODE
DELETE FROM actual_node
WHERE wc_id = ?1 AND local_relpath = ?2;
+-- STMT_DELETE_ACTUAL_NODE_RECURSIVE
+DELETE FROM actual_node
+WHERE wc_id = ?1 AND (local_relpath = ?2 OR local_relpath LIKE ?3 ESCAPE '#');
+
-- STMT_DELETE_ACTUAL_NODE_WITHOUT_CONFLICT
DELETE FROM actual_node
WHERE wc_id = ?1 AND local_relpath = ?2
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1073093&r1=1073092&r2=1073093&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Mon Feb 21 17:53:41 2011
@@ -3556,6 +3556,9 @@ op_revert_txn(void *baton, svn_sqlite__d
apr_int64_t op_depth;
int affected_rows;
+ /* ### Similar structure to op_revert_recursive_txn, should they be
+ combined? */
+
SVN_ERR(svn_sqlite__get_statement(&stmt, b->wcroot->sdb,
STMT_DELETE_ACTUAL_NODE));
SVN_ERR(svn_sqlite__bindf(stmt, "is", b->wcroot->wc_id,
@@ -3646,21 +3649,104 @@ op_revert_txn(void *baton, svn_sqlite__d
}
+static svn_error_t *
+op_revert_recursive_txn(void *baton,
+ svn_sqlite__db_t *sdb,
+ apr_pool_t *scratch_pool)
+{
+ struct op_revert_baton *b = baton;
+ svn_sqlite__stmt_t *stmt;
+ svn_boolean_t have_row;
+ apr_int64_t op_depth;
+ int affected_rows;
+
+ /* ### Similar structure to op_revert_txn, should they be
+ combined? */
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, b->wcroot->sdb,
+ STMT_DELETE_ACTUAL_NODE_RECURSIVE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "iss", b->wcroot->wc_id,
+ b->local_relpath,
+ construct_like_arg(b->local_relpath,
+ scratch_pool)));
+ SVN_ERR(svn_sqlite__step(&affected_rows, stmt));
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, b->wcroot->sdb,
+ STMT_SELECT_NODE_INFO));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", b->wcroot->wc_id,
+ b->local_relpath));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ if (!have_row)
+ {
+ SVN_ERR(svn_sqlite__reset(stmt));
+ if (affected_rows)
+ return SVN_NO_ERROR; /* actual-only revert */
+
+ return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+ _("The node '%s' was not found."),
+ path_for_error_message(b->wcroot,
+ b->local_relpath,
+ scratch_pool));
+ }
+
+ op_depth = svn_sqlite__column_int64(stmt, 0);
+ SVN_ERR(svn_sqlite__reset(stmt));
+
+ if (op_depth > 0 && op_depth != relpath_depth(b->local_relpath))
+ return svn_error_createf(SVN_ERR_WC_INVALID_OPERATION_DEPTH, NULL,
+ _("Can't revert '%s' without"
+ " reverting parent"),
+ path_for_error_message(b->wcroot,
+ b->local_relpath,
+ scratch_pool));
+
+ if (!op_depth)
+ op_depth = 1; /* Don't delete BASE nodes */
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, b->wcroot->sdb,
+ STMT_DELETE_NODES_RECURSIVE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "issi", b->wcroot->wc_id,
+ b->local_relpath,
+ construct_like_arg(b->local_relpath,
+ scratch_pool),
+ op_depth));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+
+ return SVN_NO_ERROR;
+}
+
svn_error_t *
svn_wc__db_op_revert(svn_wc__db_t *db,
const char *local_abspath,
+ svn_depth_t depth,
apr_pool_t *scratch_pool)
{
struct op_revert_baton b;
+ svn_sqlite__transaction_callback_t txn_func;
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+ switch (depth)
+ {
+ case svn_depth_empty:
+ txn_func = op_revert_txn;
+ break;
+ case svn_depth_infinity:
+ txn_func = op_revert_recursive_txn;
+ break;
+ default:
+ return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+ _("Unsupported depth for revert of '%s'"),
+ svn_dirent_local_style(local_abspath,
+ scratch_pool));
+ }
+
SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&b.wcroot, &b.local_relpath,
db, local_abspath, svn_sqlite__mode_readwrite,
scratch_pool, scratch_pool));
VERIFY_USABLE_WCROOT(b.wcroot);
- SVN_ERR(svn_sqlite__with_transaction(b.wcroot->sdb, op_revert_txn,
+ SVN_ERR(svn_sqlite__with_transaction(b.wcroot->sdb, txn_func,
&b, scratch_pool));
return SVN_NO_ERROR;
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1073093&r1=1073092&r2=1073093&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Mon Feb 21 17:53:41 2011
@@ -1246,15 +1246,19 @@ svn_wc__db_op_revert_actual(svn_wc__db_t
/* Revert all local changes which are being maintained in the database,
* including conflict storage, properties and text modification status.
*
- * This is a non-recursive operation.
- *
* Returns SVN_ERR_WC_INVALID_OPERATION_DEPTH if the revert is not
* possible, e.g. copy/delete but not a root, or a copy root with
* children.
+ *
+ * At present only depth=empty and depth=infinity are supported.
+ *
+ * ### Need to return the modified paths for notification. An array
+ * ### or hash? A temporary SQLite table?
*/
svn_error_t *
svn_wc__db_op_revert(svn_wc__db_t *db,
const char *local_abspath,
+ svn_depth_t depth,
apr_pool_t *scratch_pool);
Modified: subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c?rev=1073093&r1=1073092&r2=1073093&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Mon Feb 21 17:53:41 2011
@@ -2024,6 +2024,7 @@ check_db_actual(wc_baton_t* b,
static svn_error_t *
revert(wc_baton_t *b,
const char *local_relpath,
+ svn_depth_t depth,
nodes_row_t *before_nodes,
nodes_row_t *after_nodes,
const char **before_actual,
@@ -2042,7 +2043,7 @@ revert(wc_baton_t *b,
SVN_ERR(insert_actual(b, before_actual));
SVN_ERR(check_db_rows(b, "", before_nodes));
SVN_ERR(check_db_actual(b, before_actual));
- err = svn_wc__db_op_revert(b->wc_ctx->db, local_abspath, b->pool);
+ err = svn_wc__db_op_revert(b->wc_ctx->db, local_abspath, depth, b->pool);
if (err)
{
/* If db_op_revert returns an error the DB should be unchanged so
@@ -2091,15 +2092,22 @@ test_op_revert(const svn_test_opts_t *op
const char *after_actual4[] = { "A/B", NULL };
const char *common_actual5[] = { "A/B", "A/B/C", NULL };
const char *common_actual6[] = { "A/B", "A/B/C", "A/B/C/D", NULL };
- SVN_ERR(revert(&b, "A/B", before, after, NULL, NULL));
- SVN_ERR(revert(&b, "A/B", before, after, before_actual1, after_actual1));
- SVN_ERR(revert(&b, "A/B/C", before, before, before_actual2, after_actual2));
- SVN_ERR(revert(&b, "A", before, before, before_actual3, after_actual3));
- SVN_ERR(revert(&b, "", before, before, before_actual4, after_actual4));
- err = revert(&b, "A/B", before, before, common_actual5, common_actual5);
+ SVN_ERR(revert(&b, "A/B", svn_depth_empty,
+ before, after, NULL, NULL));
+ SVN_ERR(revert(&b, "A/B", svn_depth_empty,
+ before, after, before_actual1, after_actual1));
+ SVN_ERR(revert(&b, "A/B/C", svn_depth_empty,
+ before, before, before_actual2, after_actual2));
+ SVN_ERR(revert(&b, "A", svn_depth_empty,
+ before, before, before_actual3, after_actual3));
+ SVN_ERR(revert(&b, "", svn_depth_empty,
+ before, before, before_actual4, after_actual4));
+ err = revert(&b, "A/B", svn_depth_empty,
+ before, before, common_actual5, common_actual5);
SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_WC_INVALID_OPERATION_DEPTH);
svn_error_clear(err);
- err = revert(&b, "A/B/C", before, before, common_actual6, common_actual6);
+ err = revert(&b, "A/B/C", svn_depth_empty,
+ before, before, common_actual6, common_actual6);
SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_WC_INVALID_OPERATION_DEPTH);
svn_error_clear(err);
}
@@ -2121,38 +2129,48 @@ test_op_revert(const svn_test_opts_t *op
};
const char *common_actual[] = { "A/B/C/D", "A/B/C", "A/B", "P", "X", NULL};
- err = revert(&b, "A/B/C/D", common, common, NULL, NULL);
+ err = revert(&b, "A/B/C/D", svn_depth_empty,
+ common, common, NULL, NULL);
SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_WC_INVALID_OPERATION_DEPTH);
svn_error_clear(err);
- err = revert(&b, "A/B/C/D", common, common, common_actual, common_actual);
+ err = revert(&b, "A/B/C/D", svn_depth_empty,
+ common, common, common_actual, common_actual);
SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_WC_INVALID_OPERATION_DEPTH);
svn_error_clear(err);
- err = revert(&b, "A/B/C", common, common, NULL, NULL);
+ err = revert(&b, "A/B/C", svn_depth_empty,
+ common, common, NULL, NULL);
SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_WC_INVALID_OPERATION_DEPTH);
svn_error_clear(err);
- err = revert(&b, "A/B/C", common, common, common_actual, common_actual);
+ err = revert(&b, "A/B/C", svn_depth_empty,
+ common, common, common_actual, common_actual);
SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_WC_INVALID_OPERATION_DEPTH);
svn_error_clear(err);
- err = revert(&b, "A/B", common, common, NULL, NULL);
+ err = revert(&b, "A/B", svn_depth_empty,
+ common, common, NULL, NULL);
SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_WC_INVALID_OPERATION_DEPTH);
svn_error_clear(err);
- err = revert(&b, "A/B", common, common, common_actual, common_actual);
+ err = revert(&b, "A/B", svn_depth_empty,
+ common, common, common_actual, common_actual);
SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_WC_INVALID_OPERATION_DEPTH);
svn_error_clear(err);
- err = revert(&b, "P", common, common, NULL, NULL);
+ err = revert(&b, "P", svn_depth_empty,
+ common, common, NULL, NULL);
SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_WC_INVALID_OPERATION_DEPTH);
svn_error_clear(err);
- err = revert(&b, "P", common, common, common_actual, common_actual);
+ err = revert(&b, "P", svn_depth_empty,
+ common, common, common_actual, common_actual);
SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_WC_INVALID_OPERATION_DEPTH);
svn_error_clear(err);
- err = revert(&b, "X", common, common, NULL, NULL);
+ err = revert(&b, "X", svn_depth_empty,
+ common, common, NULL, NULL);
SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_WC_INVALID_OPERATION_DEPTH);
svn_error_clear(err);
- err = revert(&b, "X", common, common, common_actual, common_actual);
+ err = revert(&b, "X", svn_depth_empty,
+ common, common, common_actual, common_actual);
SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_WC_INVALID_OPERATION_DEPTH);
svn_error_clear(err);
}
@@ -2175,8 +2193,10 @@ test_op_revert(const svn_test_opts_t *op
};
const char *before_actual[] = { "A/B", "A/B/C", NULL };
const char *after_actual[] = {"A/B", NULL };
- SVN_ERR(revert(&b, "A/B/C", before, after, NULL, NULL));
- SVN_ERR(revert(&b, "A/B/C", before, after, before_actual, after_actual));
+ SVN_ERR(revert(&b, "A/B/C", svn_depth_empty,
+ before, after, NULL, NULL));
+ SVN_ERR(revert(&b, "A/B/C", svn_depth_empty,
+ before, after, before_actual, after_actual));
}
{
@@ -2199,7 +2219,8 @@ test_op_revert(const svn_test_opts_t *op
{ 3, "A/B/C/D", "base-deleted", NO_COPY_FROM },
{ 0 },
};
- SVN_ERR(revert(&b, "A/B", before, after, NULL, NULL));
+ SVN_ERR(revert(&b, "A/B", svn_depth_empty,
+ before, after, NULL, NULL));
}
{
@@ -2236,8 +2257,10 @@ test_op_revert(const svn_test_opts_t *op
{ 1, "A/B/C", "base-deleted", NO_COPY_FROM },
{ 0 },
};
- SVN_ERR(revert(&b, "A/B/C", before, after1, NULL, NULL));
- SVN_ERR(revert(&b, "A/B", after1, after2, NULL, NULL));
+ SVN_ERR(revert(&b, "A/B/C", svn_depth_empty,
+ before, after1, NULL, NULL));
+ SVN_ERR(revert(&b, "A/B", svn_depth_empty,
+ after1, after2, NULL, NULL));
}
{
@@ -2262,7 +2285,8 @@ test_op_revert(const svn_test_opts_t *op
{ 3, "A/B/C/D", "base-deleted", NO_COPY_FROM },
{ 0 },
};
- SVN_ERR(revert(&b, "A/B", before, after, NULL, NULL));
+ SVN_ERR(revert(&b, "A/B", svn_depth_empty,
+ before, after, NULL, NULL));
}
{
@@ -2278,7 +2302,49 @@ test_op_revert(const svn_test_opts_t *op
{ 1, "A/B/C/D", "base-deleted", NO_COPY_FROM },
{ 0 },
};
- err = revert(&b, "A", common, common, NULL, NULL);
+ err = revert(&b, "A", svn_depth_empty,
+ common, common, NULL, NULL);
+ SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_WC_INVALID_OPERATION_DEPTH);
+ svn_error_clear(err);
+ }
+
+ {
+ nodes_row_t before[] = {
+ { 0, "", "normal", 4, "" },
+ { 0, "A", "normal", 4, "A" },
+ { 0, "A/B", "normal", 4, "A/B" },
+ { 0, "A/B/C", "normal", 4, "A/B/C" },
+ { 1, "A", "normal", NO_COPY_FROM },
+ { 1, "A/B", "base-deleted", NO_COPY_FROM },
+ { 1, "A/B/C", "base-deleted", NO_COPY_FROM },
+ { 2, "A/B", "normal", NO_COPY_FROM },
+ { 0 },
+ };
+ nodes_row_t after1[] = {
+ { 0, "", "normal", 4, "" },
+ { 0, "A", "normal", 4, "A" },
+ { 0, "A/B", "normal", 4, "A/B" },
+ { 0, "A/B/C", "normal", 4, "A/B/C" },
+ { 0 },
+ };
+ nodes_row_t after2[] = {
+ { 0, "", "normal", 4, "" },
+ { 0, "A", "normal", 4, "A" },
+ { 0, "A/B", "normal", 4, "A/B" },
+ { 0, "A/B/C", "normal", 4, "A/B/C" },
+ { 1, "A", "normal", NO_COPY_FROM },
+ { 1, "A/B", "base-deleted", NO_COPY_FROM },
+ { 1, "A/B/C", "base-deleted", NO_COPY_FROM },
+ { 0 },
+ };
+ SVN_ERR(revert(&b, "", svn_depth_infinity,
+ before, after1, NULL, NULL));
+ SVN_ERR(revert(&b, "A", svn_depth_infinity,
+ before, after1, NULL, NULL));
+ SVN_ERR(revert(&b, "A/B", svn_depth_infinity,
+ before, after2, NULL, NULL));
+ err = revert(&b, "A/B/C", svn_depth_empty,
+ before, before, NULL, NULL);
SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_WC_INVALID_OPERATION_DEPTH);
svn_error_clear(err);
}