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/10/10 16:35:24 UTC
svn commit: r1531002 - in /subversion/trunk/subversion:
libsvn_wc/wc-queries.sql libsvn_wc/wc_db.h libsvn_wc/wc_db_private.h
libsvn_wc/wc_db_update_move.c tests/cmdline/revert_tests.py
tests/libsvn_wc/op-depth-test.c
Author: rhuijben
Date: Thu Oct 10 14:35:24 2013
New Revision: 1531002
URL: http://svn.apache.org/r1531002
Log:
Resolve the issue reported as issue #4436, where a revert of a specific
move case fails. Add XFail tests for a related case where a move is
accidentally turned into a copy.
* subversion/libsvn_wc/wc-queries.sql
(STMT_SELECT_MOVED_OUTSIDE): Add op_depth column to result.
* subversion/libsvn_wc/wc_db.c
(db_base_remove): Extend TODO comment.
(op_revert_txn,
op_revert_recursive_txn): Pass the op-depth of the row to revert.
* subversion/libsvn_wc/wc_db.h
(svn_wc__db_resolve_break_moved_away): Document definition failure.
* subversion/libsvn_wc/wc_db_private.h
(svn_wc__db_resolve_break_moved_away_internal): Document function and add
argument.
* subversion/libsvn_wc/wc_db_update_move.c
(svn_wc__db_resolve_break_moved_away_internal): Use an explicit op-depth.
* subversion/tests/cmdline/revert_tests.py
(revert_move): Remove test that now only duplicates a test in
op-depth-tests.c that is more thorough.
* subversion/tests/libsvn_wc/op-depth-test.c
(move_child_to_parent_revert): Verify result after reverting.
(move_abspath_more_than_once): New test.
(test_funcs): Remove XFail marker from move_child_to_parent_revert and
add move_abspath_more_than_once as XFail.
Modified:
subversion/trunk/subversion/libsvn_wc/wc-queries.sql
subversion/trunk/subversion/libsvn_wc/wc_db.h
subversion/trunk/subversion/libsvn_wc/wc_db_private.h
subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c
subversion/trunk/subversion/tests/cmdline/revert_tests.py
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=1531002&r1=1531001&r2=1531002&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Thu Oct 10 14:35:24 2013
@@ -1571,7 +1571,7 @@ WHERE wc_id = ?1
AND moved_to IS NOT NULL
-- STMT_SELECT_MOVED_OUTSIDE
-SELECT local_relpath, moved_to FROM nodes
+SELECT local_relpath, moved_to, op_depth FROM nodes
WHERE wc_id = ?1
AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
AND op_depth >= ?3
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1531002&r1=1531001&r2=1531002&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Thu Oct 10 14:35:24 2013
@@ -3382,7 +3382,14 @@ svn_wc__db_resolve_delete_raise_moved_aw
apr_pool_t *scratch_pool);
/* Like svn_wc__db_resolve_delete_raise_moved_away this should be
- combined. */
+ combined.
+
+ ### LOCAL_ABSPATH specifies the move origin, but the move origin
+ ### is not necessary unique enough. This function needs an op_root_abspath
+ ### argument to differentiate between different origins.
+
+ ### See move_tests.py: move_many_update_delete for an example case.
+ */
svn_error_t *
svn_wc__db_resolve_break_moved_away(svn_wc__db_t *db,
const char *local_abspath,
Modified: subversion/trunk/subversion/libsvn_wc/wc_db_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db_private.h?rev=1531002&r1=1531001&r2=1531002&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db_private.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db_private.h Thu Oct 10 14:35:24 2013
@@ -477,9 +477,12 @@ svn_wc__db_bump_moved_away(svn_wc__db_wc
svn_wc__db_t *db,
apr_pool_t *scratch_pool);
+/* Unbreak the move from LOCAL_RELPATH on op-depth in WCROOT, by making
+ the destination a normal copy */
svn_error_t *
svn_wc__db_resolve_break_moved_away_internal(svn_wc__db_wcroot_t *wcroot,
const char *local_relpath,
+ int op_depth,
apr_pool_t *scratch_pool);
svn_error_t *
Modified: subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c?rev=1531002&r1=1531001&r2=1531002&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c Thu Oct 10 14:35:24 2013
@@ -2435,15 +2435,17 @@ break_move(svn_wc__db_wcroot_t *wcroot,
svn_error_t *
svn_wc__db_resolve_break_moved_away_internal(svn_wc__db_wcroot_t *wcroot,
const char *local_relpath,
+ int op_depth,
apr_pool_t *scratch_pool)
{
const char *dummy1, *move_dst_op_root_relpath;
const char *dummy2, *move_src_op_root_relpath;
+ /* We want to include the passed op-depth, but the function does a > check */
SVN_ERR(svn_wc__db_op_depth_moved_to(&dummy1, &move_dst_op_root_relpath,
&dummy2,
&move_src_op_root_relpath,
- relpath_depth(local_relpath) - 1,
+ op_depth - 1,
wcroot, local_relpath,
scratch_pool, scratch_pool));
@@ -2518,6 +2520,7 @@ svn_wc__db_resolve_break_moved_away(svn_
SVN_WC__DB_WITH_TXN(
svn_wc__db_resolve_break_moved_away_internal(wcroot, local_relpath,
+ relpath_depth(local_relpath),
scratch_pool),
wcroot);
Modified: subversion/trunk/subversion/tests/cmdline/revert_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/revert_tests.py?rev=1531002&r1=1531001&r2=1531002&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/revert_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/revert_tests.py Thu Oct 10 14:35:24 2013
@@ -1643,17 +1643,6 @@ def revert_obstructing_wc(sbox):
svntest.actions.run_and_verify_svn(None, "Skipped '.*A' -- .*obstruct.*", [],
'revert', '-R', wc_dir)
-@XFail()
-@Issue(4436)
-def revert_move(sbox):
- "revert a move"
-
- sbox.build()
- sbox.simple_move('A/mu', 'mu')
- sbox.simple_rm('A')
-
- svntest.actions.run_and_verify_svn(None, None, [],
- 'revert', '-R', sbox.path('A'))
@@ -1697,7 +1686,6 @@ test_list = [ None,
revert_with_unversioned_targets,
revert_nonexistent,
revert_obstructing_wc,
- revert_move,
]
if __name__ == '__main__':
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=1531002&r1=1531001&r2=1531002&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Thu Oct 10 14:35:24 2013
@@ -8296,6 +8296,157 @@ move_child_to_parent_revert(const svn_te
SVN_ERR(sbox_wc_revert(&b, "A", svn_depth_infinity));
+ /* Verify that the move is now just a copy */
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 0, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+
+ {1, "B", "normal", 1, "A/B"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_abspath_more_than_once(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_child_to_parent_revert", opts,
+ pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/A/A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/A/A/A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "B/A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "B/A/A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "B/A/A/A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "C"));
+ SVN_ERR(sbox_wc_mkdir(&b, "C/A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "C/A/A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "C/A/A/A"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ SVN_ERR(sbox_wc_move(&b, "A/A/A", "AAA_1"));
+
+ SVN_ERR(sbox_wc_delete(&b, "A"));
+ SVN_ERR(sbox_wc_move(&b, "B", "A"));
+
+ SVN_ERR(sbox_wc_move(&b, "A/A/A", "AAA_2"));
+
+ SVN_ERR(sbox_wc_delete(&b, "A/A"));
+ SVN_ERR(sbox_wc_move(&b, "C/A", "A/A"));
+
+ SVN_ERR(sbox_wc_move(&b, "A/A/A", "AAA_3"));
+
+ /* Verify that the move is still recorded correctly */
+ {
+ nodes_row_t nodes[] = {
+
+ {0, "", "normal", 0, ""},
+
+ {1, "AAA_1", "normal", 1, "A/A/A", MOVED_HERE},
+ {1, "AAA_1/A", "normal", 1, "A/A/A/A", MOVED_HERE},
+ {1, "AAA_2", "normal", 1, "B/A/A", MOVED_HERE},
+ {1, "AAA_2/A", "normal", 1, "B/A/A/A", MOVED_HERE},
+ {1, "AAA_3", "normal", 1, "C/A/A", MOVED_HERE},
+ {1, "AAA_3/A", "normal", 1, "C/A/A/A", MOVED_HERE},
+
+ {0, "A", "normal", 1, "A"},
+ {0, "A/A", "normal", 1, "A/A"},
+ {0, "A/A/A", "normal", 1, "A/A/A"},
+ {0, "A/A/A/A", "normal", 1, "A/A/A/A"},
+
+ {1, "A", "normal", 1, "B", MOVED_HERE},
+ {1, "A/A", "normal", 1, "B/A", MOVED_HERE},
+ {1, "A/A/A", "normal", 1, "B/A/A", FALSE, "AAA_1", TRUE},
+ {1, "A/A/A/A", "normal", 1, "B/A/A/A", MOVED_HERE},
+
+ {2, "A/A", "normal", 1, "C/A", MOVED_HERE},
+ {2, "A/A/A", "normal", 1, "C/A/A", FALSE, "AAA_2", TRUE},
+ {2, "A/A/A/A", "normal", 1, "C/A/A/A", MOVED_HERE},
+
+ {3, "A/A/A", "base-deleted", NO_COPY_FROM, "AAA_3"},
+ {3, "A/A/A/A", "base-deleted", NO_COPY_FROM},
+
+ {0, "B", "normal", 1, "B"},
+ {0, "B/A", "normal", 1, "B/A"},
+ {0, "B/A/A", "normal", 1, "B/A/A"},
+ {0, "B/A/A/A", "normal", 1, "B/A/A/A"},
+
+ {1, "B", "base-deleted", NO_COPY_FROM, "A"},
+ {1, "B/A", "base-deleted", NO_COPY_FROM},
+ {1, "B/A/A", "base-deleted", NO_COPY_FROM},
+ {1, "B/A/A/A", "base-deleted", NO_COPY_FROM},
+
+ {0, "C", "normal", 1, "C"},
+ {0, "C/A", "normal", 1, "C/A"},
+ {0, "C/A/A", "normal", 1, "C/A/A"},
+ {0, "C/A/A/A", "normal", 1, "C/A/A/A"},
+
+ {2, "C/A", "base-deleted", NO_COPY_FROM, "A/A"},
+ {2, "C/A/A", "base-deleted", NO_COPY_FROM},
+ {2, "C/A/A/A", "base-deleted", NO_COPY_FROM},
+
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Ok, now we are in the very ugly case where A/A/A is moved away 3 times */
+
+ /* Let's revert A */
+ SVN_ERR(sbox_wc_revert(&b, "A", svn_depth_infinity));
+
+ /* AAA_1 should now be a copy, but AAA_2 and AAA_3 should still be moves,
+ but now from the original location instead of from "A/A/A" */
+ {
+ nodes_row_t nodes[] = {
+
+ {0, "", "normal", 0, ""},
+
+ {1, "AAA_1", "normal", 1, "A/A/A",},
+ {1, "AAA_1/A", "normal", 1, "A/A/A/A"},
+ {1, "AAA_2", "normal", 1, "B/A/A", MOVED_HERE},
+ {1, "AAA_2/A", "normal", 1, "B/A/A/A", MOVED_HERE},
+ {1, "AAA_3", "normal", 1, "C/A/A", MOVED_HERE},
+ {1, "AAA_3/A", "normal", 1, "C/A/A/A", MOVED_HERE},
+
+ {0, "A", "normal", 1, "A"},
+ {0, "A/A", "normal", 1, "A/A"},
+ {0, "A/A/A", "normal", 1, "A/A/A"},
+ {0, "A/A/A/A", "normal", 1, "A/A/A/A"},
+
+ {0, "B", "normal", 1, "B"},
+ {0, "B/A", "normal", 1, "B/A"},
+ {0, "B/A/A", "normal", 1, "B/A/A"},
+ {0, "B/A/A/A", "normal", 1, "B/A/A/A"},
+
+ {1, "B", "base-deleted", NO_COPY_FROM},
+ {1, "B/A", "base-deleted", NO_COPY_FROM},
+ {1, "B/A/A", "base-deleted", NO_COPY_FROM, "AAA_2"},
+ {1, "B/A/A/A", "base-deleted", NO_COPY_FROM},
+
+ {0, "C", "normal", 1, "C"},
+ {0, "C/A", "normal", 1, "C/A"},
+ {0, "C/A/A", "normal", 1, "C/A/A"},
+ {0, "C/A/A/A", "normal", 1, "C/A/A/A"},
+
+ {2, "C/A", "base-deleted", NO_COPY_FROM},
+ {2, "C/A/A", "base-deleted", NO_COPY_FROM, "AAA_3"},
+ {2, "C/A/A/A", "base-deleted", NO_COPY_FROM},
+
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
return SVN_NO_ERROR;
}
@@ -8457,7 +8608,9 @@ struct svn_test_descriptor_t test_funcs[
"move update with replaced parent (issue 4388)"),
SVN_TEST_OPTS_XFAIL(copy_mixed_rev_mods,
"copy mixed-rev with mods"),
- SVN_TEST_OPTS_XFAIL(move_child_to_parent_revert,
+ SVN_TEST_OPTS_PASS(move_child_to_parent_revert,
"move child to parent and revert (issue 4436)"),
+ SVN_TEST_OPTS_XFAIL(move_abspath_more_than_once,
+ "move one abspath more than once"),
SVN_TEST_NULL
};