Author: rhuijben
Date: Thu Feb 21 19:30:53 2013
New Revision: 1448781
URL: http://svn.apache.org/r1448781
Log:
Fix a minor correctness issue in the wc-wc copy code that made us copy
nodes that were only used to shadow lower layers as not-present children
of their parent.
The commit logic automatically handles the not-present case correctly, so
it merely affects database correctness. But the difference is visible
in our move logic.
Note that I reviewed the direct and indirect users of
STMT_SELECT_OP_DEPTH_CHILDREN before committing. This part is necessary to
avoid insert invalid children as incomplete during copy, while not changing
them to a not-incomplete state later.
* subversion/libsvn_wc/wc-queries.sql
(STMT_SELECT_OP_DEPTH_CHILDREN): Really select the repository children, not
just all children. Just like STMT_SELECT_GE_OP_DEPTH_CHILDREN already
does.
* subversion/libsvn_wc/wc_db.c
(get_info_for_copy): Simplify logic for adds by using more data from
read_info.
Avoid unneeded work for non-op-root-deletes, as we do want to trigger
special behavior for them instead of seeing everything as a delete.
* subversion/tests/libsvn_wc/op-depth-test.c
(move_to_swap): Add comment. Enable additional test. Expect the current buggy
result.
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=1448781&r1=1448780&r2=1448781&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Thu Feb 21 19:30:53
2013
@@ -276,8 +276,11 @@ WHERE wc_id = ?1 AND local_relpath = ?2
-- STMT_SELECT_OP_DEPTH_CHILDREN
SELECT local_relpath, kind FROM nodes
-WHERE wc_id = ?1 AND parent_relpath = ?2 AND op_depth = ?3
- AND (?3 != 0 OR file_external is NULL)
+WHERE wc_id = ?1
+ AND parent_relpath = ?2
+ AND op_depth = ?3
+ AND presence != MAP_BASE_DELETED
+ AND file_external is NULL
/* Used by non-recursive revert to detect higher level children, and
actual-only rows that would be left orphans, if the revert
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1448781&r1=1448780&r2=1448781&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Thu Feb 21 19:30:53 2013
@@ -4051,15 +4051,21 @@ get_info_for_copy(apr_int64_t *copyfrom_
const char *repos_relpath;
svn_revnum_t revision;
svn_wc__db_status_t node_status;
+ apr_int64_t repos_id;
+ svn_boolean_t is_op_root;
- SVN_ERR(read_info(&node_status, kind, &revision, &repos_relpath, copyfrom_id,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, op_root, NULL, NULL,
+ SVN_ERR(read_info(&node_status, kind, &revision, &repos_relpath, &repos_id,
+ NULL, NULL, NULL, NULL, NULL, NULL, copyfrom_relpath,
+ copyfrom_id, copyfrom_rev, NULL, NULL, NULL, NULL,
+ NULL, &is_op_root, NULL, NULL,
NULL /* have_base */,
NULL /* have_more_work */,
NULL /* have_work */,
wcroot, local_relpath, result_pool, scratch_pool));
+ if (op_root)
+ *op_root = is_op_root;
+
if (node_status == svn_wc__db_status_excluded)
{
/* The parent cannot be excluded, so look at the parent and then
@@ -4078,23 +4084,11 @@ get_info_for_copy(apr_int64_t *copyfrom_
}
else if (node_status == svn_wc__db_status_added)
{
- const char *op_root_relpath;
-
- SVN_ERR(scan_addition(&node_status, &op_root_relpath,
- NULL, NULL, /* repos_* */
- copyfrom_relpath, copyfrom_id, copyfrom_rev,
+ SVN_ERR(scan_addition(&node_status, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, wcroot, local_relpath,
scratch_pool, scratch_pool));
- if (*copyfrom_relpath)
- {
- *copyfrom_relpath
- = svn_relpath_join(*copyfrom_relpath,
- svn_relpath_skip_ancestor(op_root_relpath,
- local_relpath),
- result_pool);
- }
}
- else if (node_status == svn_wc__db_status_deleted)
+ else if (node_status == svn_wc__db_status_deleted && is_op_root)
{
const char *base_del_relpath, *work_del_relpath;
@@ -4135,10 +4129,16 @@ get_info_for_copy(apr_int64_t *copyfrom_
else
SVN_ERR_MALFUNCTION();
}
+ else if (node_status == svn_wc__db_status_deleted)
+ {
+ /* Keep original_* from read_info() to allow seeing the difference
+ between base-deleted and not present */
+ }
else
{
*copyfrom_relpath = repos_relpath;
*copyfrom_rev = revision;
+ *copyfrom_id = repos_id;
}
if (status)
@@ -4351,8 +4351,24 @@ db_op_copy(svn_wc__db_wcroot_t *src_wcro
return SVN_NO_ERROR;
}
}
- /* ### Else what??? (Reproducable with op_depth_tests.py move_to_swap */
- /* else: fall through */
+ else
+ {
+ /* This node is either a not-present node (which should be copied),
or
+ a base-delete of some lower layer (which shouldn't).
+ Subversion <= 1.7 always added a not-present node here, which is
+ safe (as it postpones the hard work until commit time and then we
+ ask the repository), but it breaks some move scenarios.
+ */
+
+ if (! copyfrom_relpath)
+ {
+ SVN_ERR(add_work_items(dst_wcroot->sdb, work_items,
+ scratch_pool));
+ return SVN_NO_ERROR;
+ }
+
+ /* Fall through. Install not present node */
+ }
case svn_wc__db_status_not_present:
case svn_wc__db_status_excluded:
/* These presence values should not create a new op depth */
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=1448781&r1=1448780&r2=1448781&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Thu Feb 21
19:30:53 2013
@@ -4078,6 +4078,7 @@ move_to_swap(const svn_test_opts_t *opts
SVN_ERR(sbox_wc_move(&b, "X/Y", "A/Y"));
{
+ /* Exact the same as before the initial moves */
nodes_row_t nodes[] = {
{0, "", "normal", 1, ""},
{0, "A", "normal", 1, "A"},
@@ -4095,7 +4096,6 @@ move_to_swap(const svn_test_opts_t *opts
SVN_ERR(check_db_rows(&b, "", nodes));
}
-#if 0
/* And try to undo the rest */
SVN_ERR(sbox_wc_move(&b, "A", "A2"));
SVN_ERR(sbox_wc_move(&b, "X", "A"));
@@ -4108,13 +4108,21 @@ move_to_swap(const svn_test_opts_t *opts
{0, "A/B", "normal", 1, "A/B"},
{0, "X", "normal", 1, "X"},
{0, "X/Y", "normal", 1, "X/Y"},
+
+ /* We shouldn't see this move, but somehow our move information
+ is lost in this move-back, so we can't find if it is copy-back
+ or a move-back */
+ {1, "A", "normal", 1, "A"},
+ {1, "A/B", "normal", 1, "A/B", MOVED_HERE},
+
+ {1, "X", "normal", 1, "X", FALSE, "A"},
+ {1, "X/Y", "normal", 1, "X/Y", MOVED_HERE},
+
{0}
};
- /* ### Currently this breaks hard. Introducing not-present nodes, etc.
- ### but that is not caused by this change */
+
SVN_ERR(check_db_rows(&b, "", nodes));
}
-#endif
return SVN_NO_ERROR;
}