Author: rhuijben
Date: Thu Apr 21 10:26:51 2011
New Revision: 1095645
URL: http://svn.apache.org/viewvc?rev=1095645&view=rev
Log:
Resolve two issues I found by writing the op-depth test 'test_shadowed_update'
Most importantly stop adding base-deleted nodes above base nodes that don't
describe a present node and start removing the base-deletes for that case.
And when updating a node to a revision in which it does not exist, mark
it as not existing in that revision instead of not-present in its former
revision (where it was present).
* subversion/libsvn_wc/update_editor.c
(delete_entry): Update caller to pass explicit not-present revision.
* subversion/libsvn_wc/wc_db.c
(extend_parent_delete,
retract_parent_delete): Take a svn_wc__db_wcroot_t* argument instead of a
sqlite database and a working copy id.
(insert_base_node): Don't extend deletes over not-present nodes, instead
retract existing deletes.
* subversion/libsvn_wc/workqueue.c
(run_base_remove): Read the not-present revision and kind from the skel
instead of determining them locally.
(svn_wc__wq_build_base_remove): Accept an explicit revision and kind for the
not present node.
* subversion/libsvn_wc/workqueue.h
(svn_wc__wq_build_base_remove): Accept an explicit revision and kind for the
not present node.
* subversion/tests/libsvn_wc/op-depth-test.c
(test_mixed_rev_copy,
test_del_replace_not_present): Expect the update target revision on
not-present nodes.
(test_shadowed_update): Also verify the same operations on the A-tree.
(test_funcs): Remove XFail marking.
Modified:
subversion/trunk/subversion/libsvn_wc/update_editor.c
subversion/trunk/subversion/libsvn_wc/wc_db.c
subversion/trunk/subversion/libsvn_wc/workqueue.c
subversion/trunk/subversion/libsvn_wc/workqueue.h
subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c
Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=1095645&r1=1095644&r2=1095645&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Thu Apr 21 10:26:51
2011
@@ -1572,7 +1572,7 @@ delete_entry(const char *path,
const char *base = svn_relpath_basename(path, NULL);
const char *local_abspath;
const char *repos_relpath;
- svn_wc__db_kind_t kind;
+ svn_wc__db_kind_t kind, base_kind;
svn_boolean_t conflicted;
svn_boolean_t have_base;
svn_boolean_t have_work;
@@ -1623,9 +1623,13 @@ delete_entry(const char *path,
scratch_pool, scratch_pool));
if (!have_work)
- base_status = status;
+ {
+ base_status = status;
+ base_kind = kind;
+ }
else
- SVN_ERR(svn_wc__db_base_get_info(&base_status, NULL, NULL, &repos_relpath,
+ SVN_ERR(svn_wc__db_base_get_info(&base_status, &base_kind, NULL,
+ &repos_relpath,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
eb->db, local_abspath,
@@ -1740,14 +1744,18 @@ delete_entry(const char *path,
{
/* Delete, and do not leave a not-present node. */
SVN_ERR(svn_wc__wq_build_base_remove(&work_item,
- eb->db, local_abspath, FALSE,
+ eb->db, local_abspath,
+ SVN_INVALID_REVNUM,
+ svn_wc__db_kind_unknown,
scratch_pool, scratch_pool));
}
else
{
/* Delete, leaving a not-present node. */
SVN_ERR(svn_wc__wq_build_base_remove(&work_item,
- eb->db, local_abspath, TRUE,
+ eb->db, local_abspath,
+ *eb->target_revision,
+ base_kind,
scratch_pool, scratch_pool));
eb->target_deleted = TRUE;
}
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1095645&r1=1095644&r2=1095645&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Thu Apr 21 10:26:51 2011
@@ -685,8 +685,7 @@ blank_ibb(insert_base_baton_t *pibb)
the extended delete, A/B/C is already deleted.
*/
static svn_error_t *
-extend_parent_delete(svn_sqlite__db_t *sdb,
- apr_int64_t wc_id,
+extend_parent_delete(svn_wc__db_wcroot_t *wcroot,
const char *local_relpath,
apr_pool_t *scratch_pool)
{
@@ -697,9 +696,9 @@ extend_parent_delete(svn_sqlite__db_t *s
SVN_ERR_ASSERT(local_relpath[0]);
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_SELECT_LOWEST_WORKING_NODE));
- SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, parent_relpath));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, parent_relpath));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
if (have_row)
parent_op_depth = svn_sqlite__column_int64(stmt, 0);
@@ -708,16 +707,16 @@ extend_parent_delete(svn_sqlite__db_t *s
{
apr_int64_t op_depth;
- SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
if (have_row)
op_depth = svn_sqlite__column_int64(stmt, 0);
SVN_ERR(svn_sqlite__reset(stmt));
if (!have_row || parent_op_depth < op_depth)
{
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_INSERT_WORKING_NODE_FROM_BASE));
- SVN_ERR(svn_sqlite__bindf(stmt, "isit", wc_id,
+ SVN_ERR(svn_sqlite__bindf(stmt, "isit", wcroot->wc_id,
local_relpath, parent_op_depth,
presence_map,
svn_wc__db_status_base_deleted));
@@ -736,16 +735,15 @@ extend_parent_delete(svn_sqlite__db_t *s
this node must be removed.
*/
static svn_error_t *
-retract_parent_delete(svn_sqlite__db_t *sdb,
- apr_int64_t wc_id,
+retract_parent_delete(svn_wc__db_wcroot_t *wcroot,
const char *local_relpath,
apr_pool_t *scratch_pool)
{
svn_sqlite__stmt_t *stmt;
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_DELETE_LOWEST_WORKING_NODE));
- SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__step_done(stmt));
return SVN_NO_ERROR;
@@ -849,9 +847,22 @@ insert_base_node(void *baton,
0 /* BASE */,
scratch_pool));
- if (parent_relpath)
- SVN_ERR(extend_parent_delete(wcroot->sdb, wcroot->wc_id, local_relpath,
- scratch_pool));
+ /* When this is not the root node, check shadowing behavior */
+ if (*local_relpath)
+ {
+ if (parent_relpath
+ && (pibb->status == svn_wc__db_status_normal)
+ || (pibb->status == svn_wc__db_status_incomplete))
+ {
+ SVN_ERR(extend_parent_delete(wcroot, local_relpath, scratch_pool));
+ }
+ else if (pibb->status == svn_wc__db_status_not_present
+ || pibb->status == svn_wc__db_status_absent
+ || pibb->status == svn_wc__db_status_excluded)
+ {
+ SVN_ERR(retract_parent_delete(wcroot, local_relpath, scratch_pool));
+ }
+ }
SVN_ERR(add_work_items(wcroot->sdb, pibb->work_items, scratch_pool));
@@ -1833,8 +1844,7 @@ db_base_remove(void *baton,
SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__step_done(stmt));
- SVN_ERR(retract_parent_delete(wcroot->sdb, wcroot->wc_id, local_relpath,
- scratch_pool));
+ SVN_ERR(retract_parent_delete(wcroot, local_relpath, scratch_pool));
/* If there is no working node then any actual node must be deleted,
unless it marks a conflict */
Modified: subversion/trunk/subversion/libsvn_wc/workqueue.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/workqueue.c?rev=1095645&r1=1095644&r2=1095645&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/trunk/subversion/libsvn_wc/workqueue.c Thu Apr 21 10:26:51 2011
@@ -246,40 +246,70 @@ run_base_remove(svn_wc__db_t *db,
const svn_skel_t *arg1 = work_item->children->next;
const char *local_relpath;
const char *local_abspath;
- svn_boolean_t keep_not_present;
- svn_revnum_t revision;
+ svn_revnum_t not_present_rev = SVN_INVALID_REVNUM;
+ svn_wc__db_kind_t not_present_kind;
const char *repos_relpath, *repos_root_url, *repos_uuid;
- svn_wc__db_kind_t kind;
apr_int64_t val;
local_relpath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
SVN_ERR(svn_wc__db_from_relpath(&local_abspath, db, wri_abspath,
local_relpath, scratch_pool, scratch_pool));
SVN_ERR(svn_skel__parse_int(&val, arg1->next, scratch_pool));
- keep_not_present = (val != 0);
- if (keep_not_present)
+ if (arg1->next->next)
{
- SVN_ERR(svn_wc__db_base_get_info(NULL, &kind, &revision, &repos_relpath,
- &repos_root_url, &repos_uuid, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL,
- db, local_abspath,
- scratch_pool, scratch_pool));
+ not_present_rev = (svn_revnum_t)val;
+ SVN_ERR(svn_skel__parse_int(&val, arg1->next->next, scratch_pool));
+ not_present_kind = val;
+
+ if (SVN_IS_VALID_REVNUM(not_present_rev))
+ {
+ const char *dir_abspath, *name;
+
+ /* This wq operation is restartable, so we can't assume the node
+ to be here. But we can assume that the parent is still there */
+ svn_dirent_split(&dir_abspath, &name, local_abspath, scratch_pool);
+
+ SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath, &repos_root_url,
+ &repos_uuid,
+ db, dir_abspath,
+ scratch_pool, scratch_pool));
+
+ repos_relpath = svn_relpath_join(repos_relpath, name, scratch_pool);
+ }
+ }
+ else
+ {
+ svn_boolean_t keep_not_present;
+
+ SVN_ERR_ASSERT(SVN_WC__VERSION <= 28); /* Case unused in later versions*/
+
+ keep_not_present = (val != 0);
+
+ if (keep_not_present)
+ {
+ SVN_ERR(svn_wc__db_base_get_info(NULL, ¬_present_kind,
+ ¬_present_rev, &repos_relpath,
+ &repos_root_url, &repos_uuid, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ db, local_abspath,
+ scratch_pool, scratch_pool));
+ }
}
SVN_ERR(remove_base_node(db, local_abspath,
cancel_func, cancel_baton,
scratch_pool));
- if (keep_not_present)
+ if (SVN_IS_VALID_REVNUM(not_present_rev))
{
SVN_ERR(svn_wc__db_base_add_not_present_node(db, local_abspath,
repos_relpath,
repos_root_url,
repos_uuid,
- revision,
- kind,
+ not_present_rev,
+ not_present_kind,
NULL,
NULL,
scratch_pool));
@@ -292,7 +322,8 @@ svn_error_t *
svn_wc__wq_build_base_remove(svn_skel_t **work_item,
svn_wc__db_t *db,
const char *local_abspath,
- svn_boolean_t keep_not_present,
+ svn_revnum_t not_present_revision,
+ svn_wc__db_kind_t not_present_kind,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@@ -302,7 +333,8 @@ svn_wc__wq_build_base_remove(svn_skel_t
SVN_ERR(svn_wc__db_to_relpath(&local_relpath, db, local_abspath,
local_abspath, result_pool, scratch_pool));
- svn_skel__prepend_int(keep_not_present, *work_item, result_pool);
+ svn_skel__prepend_int(not_present_kind, *work_item, result_pool);
+ svn_skel__prepend_int(not_present_revision, *work_item, result_pool);
svn_skel__prepend_str(local_relpath, *work_item, result_pool);
svn_skel__prepend_str(OP_BASE_REMOVE, *work_item, result_pool);
Modified: subversion/trunk/subversion/libsvn_wc/workqueue.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/workqueue.h?rev=1095645&r1=1095644&r2=1095645&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/workqueue.h (original)
+++ subversion/trunk/subversion/libsvn_wc/workqueue.h Thu Apr 21 10:26:51 2011
@@ -211,7 +211,8 @@ svn_error_t *
svn_wc__wq_build_base_remove(svn_skel_t **work_item,
svn_wc__db_t *db,
const char *local_abspath,
- svn_boolean_t keep_not_present,
+ svn_revnum_t not_present_revision,
+ svn_wc__db_kind_t not_present_kind,
apr_pool_t *result_pool,
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=1095645&r1=1095644&r2=1095645&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Thu Apr 21
10:26:51 2011
@@ -1747,7 +1747,7 @@ test_mixed_rev_copy(const svn_test_opts_
{ 0, "", "normal", 0, "" },
{ 0, "A", "normal", 1, "A" },
{ 0, "A/B", "normal", 2, "A/B" },
- { 0, "A/B/C", "not-present", 3, "A/B/C" },
+ { 0, "A/B/C", "not-present", 0, "A/B/C" },
{ 0 }
};
SVN_ERR(check_db_rows(&b, "", rows));
@@ -1759,7 +1759,7 @@ test_mixed_rev_copy(const svn_test_opts_
{ 1, "X", "normal", 1, "A" },
{ 1, "X/B", "not-present", 2, "A/B" },
{ 2, "X/B", "normal", 2, "A/B" },
- { 2, "X/B/C", "not-present", 3, "A/B/C" },
+ { 2, "X/B/C", "not-present", 0, "A/B/C" },
{ 0 }
};
SVN_ERR(check_db_rows(&b, "X", rows));
@@ -1866,8 +1866,8 @@ test_del_replace_not_present(const svn_t
nodes_row_t rows[] = {
{ 0, "A", "normal", 2, "A" },
{ 0, "A/B", "normal", 2, "A/B" },
- { 0, "A/B/X", "not-present", 2, "A/B/X" },
- { 0, "A/B/Y", "not-present", 2, "A/B/Y" },
+ { 0, "A/B/X", "not-present", 0, "A/B/X" },
+ { 0, "A/B/Y", "not-present", 0, "A/B/Y" },
{ 0, "A/B/Z", "normal", 2, "A/B/Z" },
{ 1, "A", "base-deleted", NO_COPY_FROM },
{ 1, "A/B", "base-deleted", NO_COPY_FROM },
@@ -1882,15 +1882,15 @@ test_del_replace_not_present(const svn_t
nodes_row_t rows[] = {
{ 0, "A", "normal", 2, "A" },
{ 0, "A/B", "normal", 2, "A/B" },
- { 0, "A/B/X", "not-present", 2, "A/B/X" },
- { 0, "A/B/Y", "not-present", 2, "A/B/Y" },
+ { 0, "A/B/X", "not-present", 0, "A/B/X" },
+ { 0, "A/B/Y", "not-present", 0, "A/B/Y" },
{ 0, "A/B/Z", "normal", 2, "A/B/Z" },
{ 1, "A", "normal", 2, "X" },
{ 1, "A/B", "normal", 2, "X/B" },
- { 1, "A/B/W", "not-present", 2, "X/B/W" },
+ { 1, "A/B/W", "not-present", 0, "X/B/W" },
{ 1, "A/B/X", "normal", 2, "X/B/X" },
- { 1, "A/B/Y", "not-present", 2, "X/B/Y" },
- { 1, "A/B/Z", "not-present", 2, "X/B/Z" },
+ { 1, "A/B/Y", "not-present", 0, "X/B/Y" },
+ { 1, "A/B/Z", "not-present", 0, "X/B/Z" },
{ 0 }
};
SVN_ERR(check_db_rows(&b, "A", rows));
@@ -1901,8 +1901,8 @@ test_del_replace_not_present(const svn_t
nodes_row_t rows[] = {
{ 0, "A", "normal", 2, "A" },
{ 0, "A/B", "normal", 2, "A/B" },
- { 0, "A/B/X", "not-present", 2, "A/B/X" },
- { 0, "A/B/Y", "not-present", 2, "A/B/Y" },
+ { 0, "A/B/X", "not-present", 0, "A/B/X" },
+ { 0, "A/B/Y", "not-present", 0, "A/B/Y" },
{ 0, "A/B/Z", "normal", 2, "A/B/Z" },
{ 1, "A", "base-deleted", NO_COPY_FROM },
{ 1, "A/B", "base-deleted", NO_COPY_FROM },
@@ -3042,6 +3042,16 @@ test_shadowed_update(const svn_test_opts
SVN_ERR(wc_delete(&b, "K/L/M"));
{
nodes_row_t rows[] = {
+ {0, "", "normal", 3, ""},
+ {0, "iota", "normal", 3, "iota"},
+
+ {0, "A", "normal", 3, "A"},
+ {0, "A/B", "normal", 3, "A/B"},
+ {0, "A/B/C", "normal", 3, "A/B/C"},
+
+ {1, "A", "normal", 2, "A"},
+ {1, "A/B", "normal", 2, "A/B"},
+ {1, "A/B/C", "normal", 2, "A/B/C"},
{0, "K", "normal", 3, "K"},
{0, "K/L", "normal", 3, "K/L"},
@@ -3055,7 +3065,7 @@ test_shadowed_update(const svn_test_opts
{ 0 }
};
- SVN_ERR(check_db_rows(&b, "K", rows));
+ SVN_ERR(check_db_rows(&b, "", rows));
}
/* Resolve conflict on K and go back to r1 */
@@ -3085,13 +3095,26 @@ test_shadowed_update(const svn_test_opts
SVN_ERR(check_db_rows(&b, "K", rows));
}
- /* Update the shadowed K/L/M to r4 where it does not exits */
+ /* Update the shadowed K/L/M to r4 where they do not exit */
SVN_ERR(wc_resolved(&b, "K"));
SVN_ERR(wc_update(&b, "K/L/M", 4));
+ SVN_ERR(wc_resolved(&b, "A"));
+ SVN_ERR(wc_update(&b, "A/B/C", 4));
{
nodes_row_t rows[] = {
+ {0, "", "normal", 3, ""},
+ {0, "iota", "normal", 3, "iota"},
+
+ {0, "A", "normal", 3, "A"},
+ {0, "A/B", "normal", 3, "A/B"},
+ {0, "A/B/C", "not-present", 4, "A/B/C"},
+
+ {1, "A", "normal", 2, "A"},
+ {1, "A/B", "normal", 2, "A/B"},
+ {1, "A/B/C", "normal", 2, "A/B/C"},
+
{0, "K", "normal", 3, "K"},
{0, "K/L", "normal", 3, "K/L"},
{0, "K/L/M", "not-present", 4, "K/L/M"},
@@ -3101,13 +3124,9 @@ test_shadowed_update(const svn_test_opts
{2, "K/L", "normal", NO_COPY_FROM},
- /* ### Currently I see an unexpected
- { 1, "K/L/M", "base-deleted", NO_COPY_FROM},
- ### Which shadows the not-present node */
-
{ 0 }
};
- SVN_ERR(check_db_rows(&b, "K", rows));
+ SVN_ERR(check_db_rows(&b, "", rows));
}
@@ -3160,7 +3179,7 @@ struct svn_test_descriptor_t test_funcs[
"test_op_delete"),
SVN_TEST_OPTS_PASS(test_child_replace_with_same_origin,
"test_child_replace_with_same"),
- SVN_TEST_OPTS_XFAIL(test_shadowed_update,
+ SVN_TEST_OPTS_PASS(test_shadowed_update,
"test_shadowed_update"),
SVN_TEST_NULL
};