Author: philip
Date: Mon Dec 6 11:23:46 2010
New Revision: 1042586
URL: http://svn.apache.org/viewvc?rev=1042586&view=rev
Log:
For SVN_WC__OP_DEPTH, use base-deleted nodes at a higher op-depth
to represent deletes within a copy. This causes an additional 18
regression test FAILs.
* subversion/libsvn_wc/wc-queries.sql
(STMT_DELETE_NOT_PRESENT_NODES_RECURSIVE): Rename to...
(STMT_DELETE_CHILD_NODES_RECURSIVE): ...this, make presence a parameter.
(STMT_INSERT_WORKING_NODE_FROM_NODE): New.
* subversion/libsvn_wc/wc_db.c
(delete_not_present_children): Rename to...
(remove_children): ...this, add status and op_depth parameters.
* subversion/tests/libsvn_wc/op-depth-test.c
(test_delete_of_copies): Adjust expected values.
(test_delete_of_replace): New.
(test_funcs): Add test_delete_of_replace.
Modified:
subversion/trunk/subversion/libsvn_wc/wc-queries.sql
subversion/trunk/subversion/libsvn_wc/wc_db.c
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=1042586&r1=1042585&r2=1042586&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Mon Dec 6 11:23:46
2010
@@ -329,10 +329,10 @@ DELETE FROM actual_node
WHERE wc_id = ?1 AND local_relpath = ?2
AND tree_conflict_data IS NULL;
--- STMT_DELETE_NOT_PRESENT_NODES_RECURSIVE
+-- STMT_DELETE_CHILD_NODES_RECURSIVE
DELETE FROM nodes
WHERE wc_id = ?1 AND local_relpath LIKE ?2 ESCAPE '#' AND op_depth = ?3
- AND presence = 'not-present';
+ AND presence = ?4
-- STMT_CLEAR_ACTUAL_NODE_LEAVING_CHANGELIST
UPDATE actual_node
@@ -525,6 +525,19 @@ SELECT wc_id, local_relpath, ?3 AS op_de
FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
+-- STMT_INSERT_WORKING_NODE_FROM_NODE
+INSERT OR REPLACE INTO nodes (
+ wc_id, local_relpath, op_depth, parent_relpath, presence, kind, checksum,
+ changed_revision, changed_date, changed_author, depth, symlink_target,
+ translated_size, last_mod_time, properties)
+SELECT wc_id, local_relpath, ?3 AS op_depth, parent_relpath, ?4 AS presence,
+ kind, checksum, changed_revision, changed_date, changed_author, depth,
+ symlink_target, translated_size, last_mod_time, properties
+FROM nodes
+WHERE wc_id = ?1 AND local_relpath = ?2
+ORDER BY op_depth DESC
+LIMIT 1;
+
-- STMT_INSERT_WORKING_NODE_FROM_BASE_COPY
INSERT INTO nodes (
wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1042586&r1=1042585&r2=1042586&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Mon Dec 6 11:23:46 2010
@@ -4436,31 +4436,42 @@ svn_wc__db_temp_op_set_dir_depth(svn_wc_
### Do we need to handle incomplete here? */
static svn_error_t *
-delete_not_present_children(svn_wc__db_pdh_t *pdh,
- const char *local_relpath,
- apr_pool_t *scratch_pool)
+remove_children(svn_wc__db_pdh_t *pdh,
+ const char *local_relpath,
+ svn_wc__db_status_t status,
+ apr_int64_t op_depth,
+ apr_pool_t *scratch_pool)
{
svn_sqlite__stmt_t *stmt;
-#ifdef SVN_WC__OP_DEPTH
- apr_int64_t op_depth = relpath_depth(local_relpath);
-#else
- apr_int64_t op_depth = 2; /* ### temporary op_depth */
-#endif
SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
- STMT_DELETE_NOT_PRESENT_NODES_RECURSIVE));
- SVN_ERR(svn_sqlite__bindf(stmt, "isi", pdh->wcroot->wc_id,
+ STMT_DELETE_CHILD_NODES_RECURSIVE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isit", pdh->wcroot->wc_id,
construct_like_arg(local_relpath,
scratch_pool),
- op_depth));
+ op_depth, presence_map, status));
SVN_ERR(svn_sqlite__step_done(stmt));
return SVN_NO_ERROR;
}
+static svn_error_t *
+db_working_actual_remove(svn_wc__db_pdh_t *pdh,
+ const char *local_relpath,
+ apr_pool_t *scratch_pool);
+
+static svn_error_t *
+info_below_working(svn_boolean_t *have_base,
+ svn_boolean_t *have_work,
+ svn_wc__db_status_t *status,
+ svn_wc__db_pdh_t *pdh,
+ const char *local_relpath,
+ apr_pool_t *scratch_pool);
+
/* Update the working node for LOCAL_ABSPATH setting presence=STATUS */
static svn_error_t *
-db_working_update_presence(svn_wc__db_status_t status,
+db_working_update_presence(apr_int64_t op_depth,
+ svn_wc__db_status_t status,
svn_wc__db_pdh_t *pdh,
const char *local_relpath,
apr_pool_t *scratch_pool)
@@ -4475,11 +4486,55 @@ db_working_update_presence(svn_wc__db_st
if (status == svn_wc__db_status_base_deleted)
{
- /* Switching to base-deleted is undoing an add/copy. If this
- was a copy then any children of the copy will now be
- not-present and should be removed. By this stage an add will
- have no children. */
- SVN_ERR(delete_not_present_children(pdh, local_relpath, scratch_pool));
+ /* Switching to base-deleted is undoing an add/copy. By this
+ stage an add will have no children. */
+#ifdef SVN_WC__OP_DEPTH
+ const apr_array_header_t *children;
+ apr_pool_t *iterpool;
+ int i;
+
+ /* Children of the copy will be marked deleted in the layer
+ above. */
+ SVN_ERR(remove_children(pdh, local_relpath,
+ svn_wc__db_status_base_deleted, op_depth + 1,
+ scratch_pool));
+
+ /* Children of the copy that overlay a lower level become
+ base_deleted, otherwise they get removed. */
+ SVN_ERR(gather_repo_children(&children, pdh, local_relpath, op_depth,
+ scratch_pool, scratch_pool));
+ iterpool = svn_pool_create(scratch_pool);
+ for (i = 0; i < children->nelts; ++i)
+ {
+ const char *name = APR_ARRAY_IDX(children, i, const char *);
+ const char *child_relpath;
+ svn_boolean_t below_base, below_work;
+ svn_wc__db_status_t below_status;
+
+ svn_pool_clear(iterpool);
+
+ child_relpath = svn_relpath_join(local_relpath, name, iterpool);
+ SVN_ERR(info_below_working(&below_base, &below_work, &below_status,
+ pdh, child_relpath, iterpool));
+ if ((below_base || below_work)
+ && (below_status == svn_wc__db_status_normal
+ || below_status == svn_wc__db_status_added
+ || below_status == svn_wc__db_status_incomplete))
+ SVN_ERR(db_working_update_presence(op_depth,
+ svn_wc__db_status_base_deleted,
+ pdh, child_relpath, iterpool));
+ else
+ SVN_ERR(db_working_actual_remove(pdh, child_relpath, iterpool));
+ }
+ svn_pool_destroy(iterpool);
+#else
+ /* If this was a copy then any children of the copy will now be
+ not-present and should be removed. */
+ SVN_ERR(remove_children(pdh, local_relpath,
+ svn_wc__db_status_not_present,
+ 2 /* ### temporary op_depth */,
+ scratch_pool));
+#endif
/* Reset the copyfrom in case this was a copy.
### What else should be reset? Properties? Or copy the node again? */
@@ -4535,7 +4590,19 @@ db_working_actual_remove(svn_wc__db_pdh_
SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__step_done(stmt));
- SVN_ERR(delete_not_present_children(pdh, local_relpath, scratch_pool));
+#ifndef SVN_WC__OP_DEPTH
+ SVN_ERR(remove_children(pdh, local_relpath, svn_wc__db_status_not_present,
+ 2 /* ### temporary op_depth */, scratch_pool));
+#else
+ SVN_ERR(remove_children(pdh, local_relpath, svn_wc__db_status_base_deleted,
+ op_depth + 1, scratch_pool));
+ SVN_ERR(remove_children(pdh, local_relpath, svn_wc__db_status_normal,
+ op_depth, scratch_pool));
+ SVN_ERR(remove_children(pdh, local_relpath, svn_wc__db_status_not_present,
+ op_depth, scratch_pool));
+ SVN_ERR(remove_children(pdh, local_relpath, svn_wc__db_status_incomplete,
+ op_depth, scratch_pool));
+#endif
/* Postcondition: There are no NODES rows in this subtree, at same or
* greater op_depth. */
@@ -4586,8 +4653,13 @@ db_working_insert(svn_wc__db_status_t st
apr_int64_t op_depth = 2; /* ### temporary op_depth */
#endif
+#ifdef SVN_WC__OP_DEPTH
+ SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+ STMT_INSERT_WORKING_NODE_FROM_NODE));
+#else
SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
STMT_INSERT_WORKING_NODE_FROM_BASE));
+#endif
SVN_ERR(svn_sqlite__bindf(stmt, "isit", pdh->wcroot->wc_id,
local_relpath, op_depth, presence_map, status));
SVN_ERR(svn_sqlite__insert(NULL, stmt));
@@ -4795,7 +4867,10 @@ temp_op_delete_txn(void *baton, svn_sqli
{
struct temp_op_delete_baton *b = baton;
svn_wc__db_status_t status, new_working_status;
- svn_boolean_t have_work, new_have_work;
+ svn_boolean_t have_work, add_work = FALSE, del_work = FALSE, mod_work =
FALSE;
+#ifndef SVN_WC__OP_DEPTH
+ svn_boolean_t new_have_work;
+#endif
SVN_ERR(read_info(&status,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -4805,8 +4880,10 @@ temp_op_delete_txn(void *baton, svn_sqli
b->pdh, b->local_relpath,
scratch_pool, scratch_pool));
+#ifndef SVN_WC__OP_DEPTH
new_have_work = have_work;
new_working_status = status;
+#endif
if (!have_work)
{
@@ -4814,13 +4891,17 @@ temp_op_delete_txn(void *baton, svn_sqli
if (status == svn_wc__db_status_normal
|| status == svn_wc__db_status_incomplete)
{
+#ifdef SVN_WC__OP_DEPTH
+ add_work = TRUE;
+#else
new_have_work = TRUE;
new_working_status = svn_wc__db_status_base_deleted;
+#endif
}
}
else if (status == svn_wc__db_status_added)
{
- /* ADD/COPY-HERE/MOVE-HERE */
+ /* ADD/COPY-HERE/MOVE-HERE that could be a replace */
svn_boolean_t add_or_root_of_copy;
SVN_ERR(is_add_or_root_of_copy(&add_or_root_of_copy,
@@ -4833,24 +4914,51 @@ temp_op_delete_txn(void *baton, svn_sqli
SVN_ERR(info_below_working(&below_base, &below_work, &below_status,
b->pdh, b->local_relpath, scratch_pool));
+#ifdef SVN_WC__OP_DEPTH
+ if ((below_base || below_work)
+ && below_status != svn_wc__db_status_not_present)
+ mod_work = TRUE;
+ else
+ del_work = TRUE;
+#else
if (below_base && below_status != svn_wc__db_status_not_present)
new_working_status = svn_wc__db_status_base_deleted;
else
new_have_work = FALSE;
+#endif
}
else
- new_working_status = svn_wc__db_status_not_present;
+ {
+#ifdef SVN_WC__OP_DEPTH
+ add_work = TRUE;
+#else
+ new_working_status = svn_wc__db_status_not_present;
+#endif
+ }
}
else if (status == svn_wc__db_status_incomplete)
{
svn_boolean_t add_or_root_of_copy;
SVN_ERR(is_add_or_root_of_copy(&add_or_root_of_copy,
b->pdh, b->local_relpath, scratch_pool));
+#ifdef SVN_WC__OP_DEPTH
+ if (add_or_root_of_copy)
+ del_work = TRUE;
+ else
+ add_work = TRUE;
+#else
if (add_or_root_of_copy)
new_have_work = FALSE;
+#endif
}
- if (!new_have_work && have_work)
+#ifndef SVN_WC__OP_DEPTH
+ del_work = !new_have_work && have_work;
+ add_work = new_have_work && !have_work;
+ mod_work = new_have_work && have_work && new_working_status != status;
+#endif
+
+ if (del_work)
{
SVN_ERR(db_working_actual_remove(b->pdh, b->local_relpath,
scratch_pool));
@@ -4858,15 +4966,21 @@ temp_op_delete_txn(void *baton, svn_sqli
SVN_ERR(svn_wc__db_temp_forget_directory(b->db, b->local_abspath,
scratch_pool));
}
- else if (new_have_work && !have_work)
+ else if (add_work)
{
+#ifdef SVN_WC__OP_DEPTH
+ new_working_status = svn_wc__db_status_base_deleted;
+#endif
SVN_ERR(db_working_insert(new_working_status, b->pdh, b->local_relpath,
scratch_pool));
}
- else if (new_have_work && have_work
- && new_working_status != status)
+ else if (mod_work)
{
- SVN_ERR(db_working_update_presence(new_working_status, b->pdh,
+#ifdef SVN_WC__OP_DEPTH
+ new_working_status = svn_wc__db_status_base_deleted;
+#endif
+ SVN_ERR(db_working_update_presence(relpath_depth(b->local_relpath),
+ new_working_status, b->pdh,
b->local_relpath, scratch_pool));
}
else
@@ -6993,7 +7107,7 @@ scan_deletion(const char **base_del_relp
}
/* We need the presence of the WORKING node. Note that legal values
- are: normal, not-present, base-deleted. */
+ are: normal, not-present, base-deleted, incomplete. */
work_presence = svn_sqlite__column_token(stmt, 1, presence_map);
/* The starting node should be deleted. */
@@ -7006,6 +7120,8 @@ scan_deletion(const char **base_del_relp
path_for_error_message(wcroot,
local_relpath,
scratch_pool));
+
+ /* ### incomplete not handled */
SVN_ERR_ASSERT(work_presence == svn_wc__db_status_normal
|| work_presence == svn_wc__db_status_not_present
|| work_presence == svn_wc__db_status_base_deleted);
@@ -7074,9 +7190,16 @@ scan_deletion(const char **base_del_relp
svn_sqlite__column_text(stmt, 2, NULL));
}
+#ifdef SVN_WC__OP_DEPTH
+ if (work_del_relpath != NULL
+ && work_presence == svn_wc__db_status_normal
+ && (child_presence == svn_wc__db_status_not_present
+ || child_presence == svn_wc__db_status_base_deleted))
+#else
if (work_del_relpath != NULL
&& work_presence == svn_wc__db_status_normal
&& child_presence == svn_wc__db_status_not_present)
+#endif
{
/* Parent is normal, but child was deleted. Therefore, the child
is the root of a WORKING subtree deletion. */
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=1042586&r1=1042585&r2=1042586&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Mon Dec 6
11:23:46 2010
@@ -938,9 +938,12 @@ test_delete_of_copies(const svn_test_opt
FALSE, TRUE, NULL, NULL, NULL, NULL, pool));
{
nodes_row_t rows[] = {
- { 2, "A/B-copied/E", "not-present", 1, "A/B/E" },
- { 2, "A/B-copied/E/alpha", "not-present", 1, "A/B/E/alpha" },
- { 2, "A/B-copied/E/beta", "not-present", 1, "A/B/E/beta" },
+ { 2, "A/B-copied/E", "normal", 1, "A/B/E" },
+ { 2, "A/B-copied/E/alpha", "normal", 1, "A/B/E/alpha" },
+ { 2, "A/B-copied/E/beta", "normal", 1, "A/B/E/beta" },
+ { 3, "A/B-copied/E", "base-deleted", NO_COPY_FROM },
+ { 3, "A/B-copied/E/alpha", "base-deleted", NO_COPY_FROM },
+ { 3, "A/B-copied/E/beta", "base-deleted", NO_COPY_FROM },
{ 0 }
};
SVN_ERR(check_db_rows(&b, "A/B-copied/E", rows));
@@ -949,13 +952,15 @@ test_delete_of_copies(const svn_test_opt
SVN_ERR(wc_copy(&b, "A/D/G", "A/B-copied/E"));
{
nodes_row_t rows[] = {
- { 2, "A/B-copied/E", "not-present", 1, "A/B/E" },
- { 2, "A/B-copied/E/alpha", "not-present", 1, "A/B/E/alpha" },
- { 2, "A/B-copied/E/beta", "not-present", 1, "A/B/E/beta" },
- { 3, "A/B-copied/E", "normal", 1, "A/D/G" },
- { 3, "A/B-copied/E/pi", "normal", 1, "A/D/G/pi" },
- { 3, "A/B-copied/E/rho", "normal", 1, "A/D/G/rho" },
- { 3, "A/B-copied/E/tau", "normal", 1, "A/D/G/tau" },
+ { 2, "A/B-copied/E", "normal", 1, "A/B/E" },
+ { 2, "A/B-copied/E/alpha", "normal", 1, "A/B/E/alpha" },
+ { 2, "A/B-copied/E/beta", "normal", 1, "A/B/E/beta" },
+ { 3, "A/B-copied/E", "normal", 1, "A/D/G" },
+ { 3, "A/B-copied/E/alpha", "base-deleted", NO_COPY_FROM },
+ { 3, "A/B-copied/E/beta", "base-deleted", NO_COPY_FROM },
+ { 3, "A/B-copied/E/pi", "normal", 1, "A/D/G/pi" },
+ { 3, "A/B-copied/E/rho", "normal", 1, "A/D/G/rho" },
+ { 3, "A/B-copied/E/tau", "normal", 1, "A/D/G/tau" },
{ 0 }
};
SVN_ERR(check_db_rows(&b, "A/B-copied/E", rows));
@@ -965,13 +970,16 @@ test_delete_of_copies(const svn_test_opt
FALSE, TRUE, NULL, NULL, NULL, NULL, pool));
{
nodes_row_t rows[] = {
- { 2, "A/B-copied/E", "not-present", 1, "A/B/E" },
- { 2, "A/B-copied/E/alpha", "not-present", 1, "A/B/E/alpha" },
- { 2, "A/B-copied/E/beta", "not-present", 1, "A/B/E/beta" },
- { 3, "A/B-copied/E", "normal", 1, "A/D/G" },
- { 3, "A/B-copied/E/pi", "normal", 1, "A/D/G/pi" },
- { 3, "A/B-copied/E/rho", "not-present", 1, "A/D/G/rho" },
- { 3, "A/B-copied/E/tau", "normal", 1, "A/D/G/tau" },
+ { 2, "A/B-copied/E", "normal", 1, "A/B/E" },
+ { 2, "A/B-copied/E/alpha", "normal", 1, "A/B/E/alpha" },
+ { 2, "A/B-copied/E/beta", "normal", 1, "A/B/E/beta" },
+ { 3, "A/B-copied/E", "normal", 1, "A/D/G" },
+ { 3, "A/B-copied/E/alpha", "base-deleted", NO_COPY_FROM },
+ { 3, "A/B-copied/E/beta", "base-deleted", NO_COPY_FROM },
+ { 3, "A/B-copied/E/pi", "normal", 1, "A/D/G/pi" },
+ { 3, "A/B-copied/E/rho", "normal", 1, "A/D/G/rho" },
+ { 3, "A/B-copied/E/tau", "normal", 1, "A/D/G/tau" },
+ { 4, "A/B-copied/E/rho", "base-deleted", NO_COPY_FROM },
{ 0 }
};
SVN_ERR(check_db_rows(&b, "A/B-copied/E", rows));
@@ -981,9 +989,12 @@ test_delete_of_copies(const svn_test_opt
FALSE, TRUE, NULL, NULL, NULL, NULL, pool));
{
nodes_row_t rows[] = {
- { 2, "A/B-copied/E", "not-present", 1, "A/B/E" },
- { 2, "A/B-copied/E/alpha", "not-present", 1, "A/B/E/alpha" },
- { 2, "A/B-copied/E/beta", "not-present", 1, "A/B/E/beta" },
+ { 2, "A/B-copied/E", "normal", 1, "A/B/E" },
+ { 2, "A/B-copied/E/alpha", "normal", 1, "A/B/E/alpha" },
+ { 2, "A/B-copied/E/beta", "normal", 1, "A/B/E/beta" },
+ { 3, "A/B-copied/E", "base-deleted", NO_COPY_FROM },
+ { 3, "A/B-copied/E/alpha", "base-deleted", NO_COPY_FROM },
+ { 3, "A/B-copied/E/beta", "base-deleted", NO_COPY_FROM },
{ 0 }
};
SVN_ERR(check_db_rows(&b, "A/B-copied/E", rows));
@@ -995,7 +1006,8 @@ test_delete_of_copies(const svn_test_opt
FALSE, TRUE, NULL, NULL, NULL, NULL, pool));
{
nodes_row_t rows[] = {
- { 3, "A/B-copied/E/F", "not-present", 1, "A/B/F" },
+ { 3, "A/B-copied/E/F", "normal", 1, "A/B/F" },
+ { 4, "A/B-copied/E/F", "base-deleted", NO_COPY_FROM },
{ 0 }
};
SVN_ERR(check_db_rows(&b, "A/B-copied/E/F", rows));
@@ -1750,6 +1762,79 @@ test_mixed_rev_copy(const svn_test_opts_
return SVN_NO_ERROR;
}
+static svn_error_t *
+test_delete_of_replace(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ wc_baton_t b;
+
+ b.pool = pool;
+ SVN_ERR(svn_test__create_repos_and_wc(&b.repos_url, &b.wc_abspath,
+ "delete_of_replace", opts, pool));
+ SVN_ERR(svn_wc_context_create(&b.wc_ctx, NULL, pool, pool));
+ SVN_ERR(wc_mkdir(&b, "A"));
+ SVN_ERR(wc_mkdir(&b, "A/B"));
+ SVN_ERR(wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(wc_mkdir(&b, "A/B/C/F"));
+ SVN_ERR(wc_mkdir(&b, "A/B/C/F/K"));
+ SVN_ERR(wc_mkdir(&b, "A/B/C/G"));
+ SVN_ERR(wc_mkdir(&b, "A/B/C/G/K"));
+ SVN_ERR(wc_commit(&b, ""));
+ SVN_ERR(wc_update(&b, "", 1));
+
+ SVN_ERR(wc_copy(&b, "A", "X"));
+ SVN_ERR(wc_move(&b, "X/B/C/F", "X/B/C/H"));
+ SVN_ERR(wc_commit(&b, ""));
+ SVN_ERR(wc_update(&b, "", 2));
+
+ SVN_ERR(wc_delete(&b, "A/B"));
+ SVN_ERR(wc_copy(&b, "X/B", "A/B"));
+ {
+ nodes_row_t rows[] = {
+ { 0, "A", "normal", 2, "A" },
+ { 0, "A/B", "normal", 2, "A/B" },
+ { 0, "A/B/C", "normal", 2, "A/B/C" },
+ { 0, "A/B/C/F", "normal", 2, "A/B/C/F" },
+ { 0, "A/B/C/F/K", "normal", 2, "A/B/C/F/K" },
+ { 0, "A/B/C/G", "normal", 2, "A/B/C/G" },
+ { 0, "A/B/C/G/K", "normal", 2, "A/B/C/G/K" },
+ { 2, "A/B", "normal", 2, "X/B" },
+ { 2, "A/B/C", "normal", 2, "X/B/C" },
+ { 2, "A/B/C/F", "base-deleted", NO_COPY_FROM },
+ { 2, "A/B/C/F/K", "base-deleted", NO_COPY_FROM },
+ { 2, "A/B/C/G", "normal", 2, "X/B/C/G" },
+ { 2, "A/B/C/G/K", "normal", 2, "X/B/C/G/K" },
+ { 2, "A/B/C/H", "normal", 2, "X/B/C/H" },
+ { 2, "A/B/C/H/K", "normal", 2, "X/B/C/H/K" },
+ { 0 }
+ };
+ SVN_ERR(check_db_rows(&b, "A", rows));
+ }
+
+ SVN_ERR(wc_delete(&b, "A/B"));
+ {
+ nodes_row_t rows[] = {
+ { 0, "A", "normal", 2, "A" },
+ { 0, "A/B", "normal", 2, "A/B" },
+ { 0, "A/B/C", "normal", 2, "A/B/C" },
+ { 0, "A/B/C/F", "normal", 2, "A/B/C/F" },
+ { 0, "A/B/C/F/K", "normal", 2, "A/B/C/F/K" },
+ { 0, "A/B/C/G", "normal", 2, "A/B/C/G" },
+ { 0, "A/B/C/G/K", "normal", 2, "A/B/C/G/K" },
+ { 2, "A/B", "base-deleted", NO_COPY_FROM },
+ { 2, "A/B/C", "base-deleted", NO_COPY_FROM },
+ { 2, "A/B/C/F", "base-deleted", NO_COPY_FROM },
+ { 2, "A/B/C/F/K", "base-deleted", NO_COPY_FROM },
+ { 2, "A/B/C/G", "base-deleted", NO_COPY_FROM },
+ { 2, "A/B/C/G/K", "base-deleted", NO_COPY_FROM },
+ { 0 }
+ };
+ SVN_ERR(check_db_rows(&b, "A", rows));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+
/* ---------------------------------------------------------------------- */
/* The list of test functions */
@@ -1794,5 +1879,8 @@ struct svn_test_descriptor_t test_funcs[
SVN_TEST_OPTS_WIMP(test_mixed_rev_copy,
"test_mixed_rev_copy",
"needs op_depth"),
+ SVN_TEST_OPTS_WIMP(test_delete_of_replace,
+ "test_delete_of_replace",
+ "needs op_depth"),
SVN_TEST_NULL
};