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 2012/03/15 12:49:51 UTC
svn commit: r1300933 - in /subversion/trunk: ./
subversion/libsvn_wc/wc-metadata.sql subversion/libsvn_wc/wc-queries.sql
subversion/libsvn_wc/wc_db.c subversion/tests/libsvn_wc/db-test.c
subversion/tests/libsvn_wc/op-depth-test.c
Author: philip
Date: Thu Mar 15 11:49:51 2012
New Revision: 1300933
URL: http://svn.apache.org/viewvc?rev=1300933&view=rev
Log:
Reintegrate the multi-layer-move branch. This stores NODES.moved_to
in WORKING nodes and will break any working copy moves recorded by
older 1.8 clients transforming the moves into copies+deletes.
Modified:
subversion/trunk/ (props changed)
subversion/trunk/subversion/libsvn_wc/wc-metadata.sql
subversion/trunk/subversion/libsvn_wc/wc-queries.sql
subversion/trunk/subversion/libsvn_wc/wc_db.c
subversion/trunk/subversion/tests/libsvn_wc/db-test.c
subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c
Propchange: subversion/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Mar 15 11:49:51 2012
@@ -37,6 +37,7 @@
/subversion/branches/kwallet:870785-871314
/subversion/branches/log-g-performance:870941-871032
/subversion/branches/merge-skips-obstructions:874525-874615
+/subversion/branches/multi-layer-moves:1239019-1300930
/subversion/branches/nfc-nfd-aware-client:870276,870376
/subversion/branches/performance:979193,980118,981087,981090,981189,981194,981287,981684,981827,982043,982355,983398,983406,983430,983474,983488,983490,983760,983764,983766,983770,984927,984973,984984,985014,985037,985046,985472,985477,985482,985487-985488,985493,985497,985500,985514,985601,985603,985606,985669,985673,985695,985697,986453,986465,986485,986491-986492,986517,986521,986605,986608,986817,986832,987865,987868-987869,987872,987886-987888,987893,988319,988898,990330,990533,990535-990537,990541,990568,990572,990574-990575,990600,990759,992899,992904,992911,993127,993141,994956,995478,995507,995603,998012,998858,999098,1001413,1001417,1004291,1022668,1022670,1022676,1022715,1022719,1025660,1025672,1027193,1027203,1027206,1027214,1027227,1028077,1028092,1028094,1028104,1028107,1028111,1028354,1029038,1029042-1029043,1029054-1029055,1029062-1029063,1029078,1029080,1029090,1029092-1029093,1029111,1029151,1029158,1029229-1029230,1029232,1029335-1029336,1029339-1029340,10
29342,1029344,1030763,1030827,1031203,1031235,1032285,1032333,1033040,1033057,1033294,1035869,1035882,1039511,1043705,1053735,1056015,1066452,1067683,1067697-1078365
/subversion/branches/py-tests-as-modules:956579-1033052
Modified: subversion/trunk/subversion/libsvn_wc/wc-metadata.sql
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-metadata.sql?rev=1300933&r1=1300932&r2=1300933&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-metadata.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-metadata.sql Thu Mar 15 11:49:51 2012
@@ -389,12 +389,13 @@ CREATE TABLE NODES (
moved_here INTEGER,
/* If the underlying node was moved away (rather than just deleted), this
- specifies the local_relpath of where the BASE node was moved to.
+ specifies the local_relpath of where the node was moved to.
This is set only on the root of a move, and is NULL for all children.
- Note that moved_to never refers to *this* node. It always refers
- to the "underlying" node in the BASE tree. A non-NULL moved_to column
- is only valid in rows where op_depth == 0. */
+ The op-depth of the moved-to node is not recorded. A moved_to path
+ always points at a node within the highest op-depth layer at the
+ destination. This invariant must be maintained by operations which
+ change existing move information. */
moved_to TEXT,
Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1300933&r1=1300932&r2=1300933&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Thu Mar 15 11:49:51 2012
@@ -51,8 +51,7 @@ ORDER BY op_depth DESC
-- STMT_SELECT_BASE_NODE
SELECT repos_id, repos_path, presence, kind, revision, checksum,
translated_size, changed_revision, changed_date, changed_author, depth,
- symlink_target, last_mod_time, properties, file_external IS NOT NULL,
- moved_to
+ symlink_target, last_mod_time, properties, file_external IS NOT NULL
FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0
@@ -60,7 +59,6 @@ WHERE wc_id = ?1 AND local_relpath = ?2
SELECT nodes.repos_id, nodes.repos_path, presence, kind, revision,
checksum, translated_size, changed_revision, changed_date, changed_author,
depth, symlink_target, last_mod_time, properties, file_external IS NOT NULL,
- moved_to,
/* All the columns until now must match those returned by
STMT_SELECT_BASE_NODE. The implementation of svn_wc__db_base_get_info()
assumes that these columns are followed by the lock information) */
@@ -283,13 +281,18 @@ WHERE wc_id = ?1 AND local_relpath = ?2
SELECT dav_cache FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0
+/* ### FIXME. modes_move.moved_to IS NOT NULL works when there is
+ only one move but we need something else when there are several. */
-- STMT_SELECT_DELETION_INFO
-SELECT nodes_base.presence, nodes_work.presence, nodes_base.moved_to,
+SELECT nodes_base.presence, nodes_work.presence, nodes_move.moved_to,
nodes_work.op_depth
FROM nodes AS nodes_work
+LEFT OUTER JOIN nodes nodes_move ON nodes_move.wc_id = nodes_work.wc_id
+ AND nodes_move.local_relpath = nodes_work.local_relpath
+ AND nodes_move.moved_to IS NOT NULL
LEFT OUTER JOIN nodes nodes_base ON nodes_base.wc_id = nodes_work.wc_id
- AND nodes_base.local_relpath = nodes_work.local_relpath
- AND nodes_base.op_depth = 0
+ AND nodes_base.local_relpath = nodes_work.local_relpath
+ AND nodes_base.op_depth = 0
WHERE nodes_work.wc_id = ?1 AND nodes_work.local_relpath = ?2
AND nodes_work.op_depth = (SELECT MAX(op_depth) FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2
@@ -884,28 +887,32 @@ INSERT OR REPLACE INTO nodes (
wc_id, local_relpath, op_depth, parent_relpath, repos_id,
repos_path, revision, presence, depth, moved_here, kind, changed_revision,
changed_date, changed_author, checksum, properties, translated_size,
- last_mod_time, symlink_target )
-SELECT wc_id, ?3 /*local_relpath*/, ?4 /*op_depth*/, ?5 /*parent_relpath*/,
- repos_id, repos_path, revision, ?6 /*presence*/, depth, ?7/*moved_here*/,
- kind, changed_revision, changed_date, changed_author, checksum, properties,
- translated_size, last_mod_time, symlink_target
-FROM nodes
-WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0
+ last_mod_time, symlink_target, moved_to )
+SELECT src.wc_id, ?3 /*local_relpath*/, ?4 /*op_depth*/, ?5 /*parent_relpath*/,
+ src.repos_id, src.repos_path, src.revision, ?6 /*presence*/, src.depth,
+ ?7/*moved_here*/, src.kind, src.changed_revision, src.changed_date,
+ src.changed_author, src.checksum, src.properties, src.translated_size,
+ src.last_mod_time, src.symlink_target, dst.moved_to
+FROM nodes AS src
+LEFT OUTER JOIN nodes_current dst ON dst.wc_id = src.wc_id
+ AND dst.local_relpath = ?3 AND dst.op_depth = ?4
+WHERE src.wc_id = ?1 AND src.local_relpath = ?2 AND src.op_depth = 0
-- STMT_INSERT_WORKING_NODE_COPY_FROM_WORKING
INSERT OR REPLACE INTO nodes (
- wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
- revision, presence, depth, moved_here, kind, changed_revision, changed_date,
- changed_author, checksum, properties, translated_size, last_mod_time,
- symlink_target )
-SELECT wc_id, ?3 /*local_relpath*/, ?4 /*op_depth*/, ?5 /*parent_relpath*/,
- repos_id, repos_path, revision, ?6 /*presence*/, depth, ?7 /*moved_here*/,
- kind, changed_revision, changed_date, changed_author, checksum, properties,
- translated_size, last_mod_time, symlink_target
-FROM nodes
-WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > 0
-ORDER BY op_depth DESC
-LIMIT 1
+ wc_id, local_relpath, op_depth, parent_relpath, repos_id,
+ repos_path, revision, presence, depth, moved_here, kind, changed_revision,
+ changed_date, changed_author, checksum, properties, translated_size,
+ last_mod_time, symlink_target, moved_to )
+SELECT src.wc_id, ?3 /*local_relpath*/, ?4 /*op_depth*/, ?5 /*parent_relpath*/,
+ src.repos_id, src.repos_path, src.revision, ?6 /*presence*/, src.depth,
+ ?7 /*moved_here*/, src.kind, src.changed_revision, src.changed_date,
+ src.changed_author, src.checksum, src.properties, src.translated_size,
+ src.last_mod_time, src.symlink_target, dst.moved_to
+FROM nodes_current AS src
+LEFT OUTER JOIN nodes_current dst ON dst.wc_id = src.wc_id
+ AND dst.local_relpath = ?3 AND dst.op_depth = ?4
+WHERE src.wc_id = ?1 AND src.local_relpath = ?2 AND src.op_depth > 0
-- STMT_INSERT_WORKING_NODE_COPY_FROM_DEPTH
INSERT OR REPLACE INTO nodes (
@@ -1373,34 +1380,48 @@ WHERE wc_id = ?1
AND presence='normal'
AND file_external IS NULL
+/* ### FIXME: op-depth? What about multiple moves? */
-- STMT_SELECT_MOVED_FROM_RELPATH
-SELECT local_relpath FROM nodes
-WHERE wc_id = ?1 AND moved_to = ?2 AND op_depth = 0
+SELECT local_relpath, op_depth FROM nodes
+WHERE wc_id = ?1 AND moved_to = ?2 AND op_depth > 0
-- STMT_UPDATE_MOVED_TO_RELPATH
-UPDATE nodes SET moved_to = ?3
-WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0
+UPDATE nodes SET moved_to = ?4
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3
+/* ### FIXME: op-depth? What about multiple moves? */
-- STMT_CLEAR_MOVED_TO_RELPATH
UPDATE nodes SET moved_to = NULL
-WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0
-
--- STMT_CLEAR_MOVED_TO_RELPATH_RECURSIVE
-UPDATE nodes SET moved_to = NULL
-WHERE wc_id = ?1
- AND (?2 = ''
- OR local_relpath = ?2
- OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
- AND op_depth = 0
+WHERE wc_id = ?1 AND local_relpath = ?2
/* This statement returns pairs of move-roots below the path ?2 in WC_ID ?1.
* Each row returns a moved-here path (always a child of ?2) in the first
* column, and its matching moved-away (deleted) path in the second column. */
-- STMT_SELECT_MOVED_HERE_CHILDREN
SELECT moved_to, local_relpath FROM nodes
-WHERE wc_id = ?1 AND op_depth = 0
+WHERE wc_id = ?1 AND op_depth > 0
AND IS_STRICT_DESCENDANT_OF(moved_to, ?2)
+/* This statement returns pairs of paths that define a move where the
+ destination of the move is within the subtree rooted at path ?2 in
+ WC_ID ?1. */
+-- STMT_SELECT_MOVED_PAIR
+SELECT local_relpath, moved_to, op_depth FROM nodes_current
+WHERE wc_id = ?1
+ AND (IS_STRICT_DESCENDANT_OF(moved_to, ?2)
+ OR (IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
+ AND moved_to IS NOT NULL))
+
+/* This statement returns pairs of move-roots below the path ?2 in WC_ID ?1,
+ * where the source of the move is within the subtree rooted at path ?2, and
+ * the destination of the move is outside the subtree rooted at path ?2. */
+-- STMT_SELECT_MOVED_PAIR2
+SELECT local_relpath, moved_to FROM nodes_current
+WHERE wc_id = ?1
+ AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
+ AND moved_to IS NOT NULL
+ AND NOT IS_STRICT_DESCENDANT_OF(moved_to, ?2)
+
/* ------------------------------------------------------------------------- */
/* Queries for verification. */
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1300933&r1=1300932&r2=1300933&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Thu Mar 15 11:49:51 2012
@@ -368,6 +368,7 @@ scan_addition(svn_wc__db_status_t *statu
svn_revnum_t *original_revision,
const char **moved_from_relpath,
const char **moved_from_op_root_relpath,
+ apr_int64_t *moved_from_op_depth,
svn_wc__db_wcroot_t *wcroot,
const char *local_relpath,
apr_pool_t *result_pool,
@@ -781,7 +782,6 @@ insert_base_node(void *baton,
svn_sqlite__stmt_t *stmt;
svn_filesize_t recorded_size = SVN_INVALID_FILESIZE;
apr_int64_t recorded_mod_time;
- const char *moved_to_relpath = NULL;
svn_boolean_t have_row;
/* The directory at the WCROOT has a NULL parent_relpath. Otherwise,
@@ -813,15 +813,13 @@ insert_base_node(void *baton,
recorded_size = get_recorded_size(stmt, 6);
recorded_mod_time = svn_sqlite__column_int64(stmt, 12);
}
- /* Always preserve moved-to info. */
- moved_to_relpath = svn_sqlite__column_text(stmt, 15, scratch_pool);
}
SVN_ERR(svn_sqlite__reset(stmt));
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_INSERT_NODE));
SVN_ERR(svn_sqlite__bindf(stmt, "isisisr"
"tstr" /* 8 - 11 */
- "isnnnnnsss", /* 12 - 21 */
+ "isnnnnns", /* 12 - 19 */
wcroot->wc_id, /* 1 */
local_relpath, /* 2 */
(apr_int64_t)0, /* op_depth is 0 for base */
@@ -837,9 +835,7 @@ insert_base_node(void *baton,
pibb->changed_date, /* 12 */
pibb->changed_author, /* 13 */
(pibb->kind == svn_kind_symlink) ?
- pibb->target : NULL, /* 19 */
- NULL /* 20 */,
- moved_to_relpath /* 21 */));
+ pibb->target : NULL)); /* 19 */
if (pibb->kind == svn_kind_file)
{
if (!pibb->checksum
@@ -971,38 +967,72 @@ insert_incomplete_children(svn_sqlite__d
{
svn_sqlite__stmt_t *stmt;
int i;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+ apr_hash_t *moved_to_relpaths = apr_hash_make(scratch_pool);
SVN_ERR_ASSERT(repos_path != NULL || op_depth > 0);
SVN_ERR_ASSERT((repos_id != INVALID_REPOS_ID)
== (repos_path != NULL));
+ /* If we're inserting WORKING nodes, we might be replacing existing
+ * nodes which were moved-away. We need to retain the moved-to relpath of
+ * such nodes in order not to lose move information during replace. */
+ if (op_depth > 0)
+ {
+ for (i = children->nelts; i--; )
+ {
+ const char *name = APR_ARRAY_IDX(children, i, const char *);
+ svn_boolean_t have_row;
+
+ svn_pool_clear(iterpool);
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+ STMT_SELECT_WORKING_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id,
+ svn_relpath_join(local_relpath, name,
+ iterpool)));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ if (have_row && !svn_sqlite__column_is_null(stmt, 14))
+ apr_hash_set(moved_to_relpaths, name, APR_HASH_KEY_STRING,
+ svn_sqlite__column_text(stmt, 14, scratch_pool));
+
+ SVN_ERR(svn_sqlite__reset(stmt));
+ }
+ }
+
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_NODE));
for (i = children->nelts; i--; )
{
const char *name = APR_ARRAY_IDX(children, i, const char *);
- SVN_ERR(svn_sqlite__bindf(stmt, "isisnnrsns",
+ svn_pool_clear(iterpool);
+
+ SVN_ERR(svn_sqlite__bindf(stmt, "isisnnrsnsnnnnnnnnnnsn",
wc_id,
svn_relpath_join(local_relpath, name,
- scratch_pool),
+ iterpool),
op_depth,
local_relpath,
revision,
"incomplete", /* 8, presence */
- "unknown")); /* 10, kind */
-
+ "unknown", /* 10, kind */
+ /* 21, moved_to */
+ apr_hash_get(moved_to_relpaths, name,
+ APR_HASH_KEY_STRING)));
if (repos_id != INVALID_REPOS_ID)
{
SVN_ERR(svn_sqlite__bind_int64(stmt, 5, repos_id));
SVN_ERR(svn_sqlite__bind_text(stmt, 6,
svn_relpath_join(repos_path, name,
- scratch_pool)));
+ iterpool)));
}
SVN_ERR(svn_sqlite__insert(NULL, stmt));
}
+ svn_pool_destroy(iterpool);
+
return SVN_NO_ERROR;
}
@@ -2039,7 +2069,7 @@ base_get_info(svn_wc__db_status_t *statu
SVN_ERR_ASSERT(!repos_relpath || *repos_relpath);
if (lock)
{
- *lock = lock_from_columns(stmt, 16, 17, 18, 19, result_pool);
+ *lock = lock_from_columns(stmt, 15, 16, 17, 18, result_pool);
}
if (changed_rev)
{
@@ -3421,7 +3451,7 @@ get_info_for_copy(apr_int64_t *copyfrom_
SVN_ERR(scan_addition(NULL, &op_root_relpath,
NULL, NULL, /* repos_* */
copyfrom_relpath, copyfrom_id, copyfrom_rev,
- NULL, NULL, wcroot, local_relpath,
+ NULL, NULL, NULL, wcroot, local_relpath,
scratch_pool, scratch_pool));
if (*copyfrom_relpath)
{
@@ -3450,7 +3480,7 @@ get_info_for_copy(apr_int64_t *copyfrom_
SVN_ERR(scan_addition(NULL, &op_root_relpath,
NULL, NULL, /* repos_* */
copyfrom_relpath, copyfrom_id, copyfrom_rev,
- NULL, NULL, wcroot, parent_del_relpath,
+ NULL, NULL, NULL, wcroot, parent_del_relpath,
scratch_pool, scratch_pool));
*copyfrom_relpath
= svn_relpath_join(*copyfrom_relpath,
@@ -3626,13 +3656,14 @@ db_op_copy(svn_wc__db_wcroot_t *src_wcro
SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb,
STMT_INSERT_WORKING_NODE_COPY_FROM_BASE));
- SVN_ERR(svn_sqlite__bindf(stmt, "issisti",
+ SVN_ERR(svn_sqlite__bindf(stmt, "issist",
src_wcroot->wc_id, src_relpath,
dst_relpath,
dst_op_depth,
dst_parent_relpath,
- presence_map, dst_presence,
- (apr_int64_t)(is_move ? 1 : 0)));
+ presence_map, dst_presence));
+ if (is_move)
+ SVN_ERR(svn_sqlite__bind_int64(stmt, 7, 1));
SVN_ERR(svn_sqlite__step_done(stmt));
@@ -5373,14 +5404,9 @@ op_revert_txn(void *baton,
SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__step_done(stmt));
+ /* If this node was moved-here, clear moved-to at the move source. */
if (moved_here)
SVN_ERR(clear_moved_to(local_relpath, wcroot, scratch_pool));
-
- /* Clear the moved-to path of the BASE node. */
- SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_CLEAR_MOVED_TO_RELPATH));
- SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
- SVN_ERR(svn_sqlite__step_done(stmt));
}
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
@@ -5512,12 +5538,6 @@ op_revert_recursive_txn(void *baton,
&& moved_here)
SVN_ERR(clear_moved_to(local_relpath, wcroot, scratch_pool));
- /* Clear any moved-to paths of potentially 'moved-away' nodes. */
- SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_CLEAR_MOVED_TO_RELPATH_RECURSIVE));
- SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
- SVN_ERR(svn_sqlite__step_done(stmt));
-
return SVN_NO_ERROR;
}
@@ -6274,6 +6294,7 @@ info_below_working(svn_boolean_t *have_b
static svn_error_t *
delete_update_movedto(svn_wc__db_wcroot_t *wcroot,
const char *child_moved_from_relpath,
+ apr_int64_t op_depth,
const char *new_moved_to_relpath,
apr_pool_t *scratch_pool)
{
@@ -6282,9 +6303,10 @@ delete_update_movedto(svn_wc__db_wcroot_
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_UPDATE_MOVED_TO_RELPATH));
- SVN_ERR(svn_sqlite__bindf(stmt, "iss",
+ SVN_ERR(svn_sqlite__bindf(stmt, "isis",
wcroot->wc_id,
child_moved_from_relpath,
+ op_depth,
new_moved_to_relpath));
SVN_ERR(svn_sqlite__step_done(stmt));
@@ -6297,6 +6319,37 @@ struct op_delete_baton_t {
const char *moved_to_relpath; /* NULL if delete is not part of a move */
};
+/* This structure is used while rewriting move information for nodes.
+ *
+ * The most simple case of rewriting move information happens when
+ * a moved-away subtree is moved again: mv A B; mv B C
+ * The second move requires rewriting moved-to info at or within A.
+ *
+ * Another example is a move of a subtree which had nodes moved into it:
+ * mv A B/F; mv B G
+ * This requires rewriting such that A/F is marked has having moved to G/F.
+ *
+ * Another case is where a node becomes a nested moved node.
+ * A nested move happens when a subtree child is moved before or after
+ * the subtree itself is moved. For example:
+ * mv A/F A/G; mv A B
+ * In this case, the move A/F -> A/G is rewritten to B/F -> B/G.
+ * Note that the following sequence results in the same DB state:
+ * mv A B; mv B/F B/G
+ * We do not care about the order the moves were performed in.
+ * For details, see http://wiki.apache.org/subversion/MultiLayerMoves
+ */
+struct moved_node_t {
+ /* The source of the move. */
+ const char *local_relpath;
+
+ /* The move destination. */
+ const char *moved_to_relpath;
+
+ /* The op-depth of the deleted node at the source of the move. */
+ apr_int64_t op_depth;
+};
+
static svn_error_t *
delete_node(void *baton,
svn_wc__db_wcroot_t *wcroot,
@@ -6311,6 +6364,7 @@ delete_node(void *baton,
apr_int64_t select_depth; /* Depth of what is to be deleted */
svn_boolean_t refetch_depth = FALSE;
svn_kind_t kind;
+ apr_array_header_t *moved_nodes = NULL;
SVN_ERR(read_info(&status,
&kind, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -6345,116 +6399,129 @@ delete_node(void *baton,
if (b->moved_to_relpath)
{
- const char *moved_from_relpath = NULL;
-
- /* ### call scan_addition_txn() directly? */
+ const char *moved_from_op_root_relpath;
+ struct moved_node_t *moved_node
+ = apr_palloc(scratch_pool, sizeof(struct moved_node_t));
+
+ /* The node is being moved-away.
+ * Figure out if the node was moved-here before, or whether this
+ * is the first time the node is moved. */
if (status == svn_wc__db_status_added)
- SVN_ERR(scan_addition(&status, NULL, NULL, NULL,
- NULL, NULL, NULL,
- &moved_from_relpath, NULL,
+ SVN_ERR(scan_addition(&status, NULL, NULL, NULL, NULL, NULL, NULL,
+ &moved_node->local_relpath,
+ &moved_from_op_root_relpath,
+ &moved_node->op_depth,
wcroot, local_relpath,
scratch_pool, scratch_pool));
- if (status == svn_wc__db_status_moved_here)
+ if (status != svn_wc__db_status_moved_here ||
+ strcmp(moved_from_op_root_relpath, moved_node->local_relpath) != 0)
{
- /* The node has already been moved, possibly along with a parent,
- * and is being moved again. Update the existing moved_to path
- * in the BASE node. */
- SVN_ERR(delete_update_movedto(wcroot, moved_from_relpath,
- b->moved_to_relpath, scratch_pool));
- }
+ /* The node is becoming a move-root for the first time,
+ * possibly because of a nested move operation. */
+ moved_node->local_relpath = local_relpath;
+ moved_node->op_depth = b->delete_depth;
+ }
+ moved_node->moved_to_relpath = b->moved_to_relpath;
+
+ /* ### Use array of struct rather than pointers? */
+ moved_nodes = apr_array_make(scratch_pool, 1,
+ sizeof(struct moved_node_t *));
+ APR_ARRAY_PUSH(moved_nodes, const struct moved_node_t *) = moved_node;
/* If a subtree is being moved-away, we need to update moved-to
- * information in BASE for all children that were moved into this
- * subtree. */
+ * information for all children that were moved into, or within,
+ * this subtree. */
if (kind == svn_kind_dir)
{
- apr_pool_t *iterpool;
-
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_SELECT_MOVED_HERE_CHILDREN));
+ STMT_SELECT_MOVED_PAIR));
SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
-
SVN_ERR(svn_sqlite__step(&have_row, stmt));
- iterpool = svn_pool_create(scratch_pool);
while (have_row)
{
- svn_wc__db_status_t child_status;
- const char *child_moved_from_relpath = NULL;
- const char *child_delete_op_root_relpath = NULL;
- const char *moved_here_child_relpath =
- svn_sqlite__column_text(stmt, 0, scratch_pool);
- svn_error_t *err;
-
- svn_pool_clear(iterpool);
-
- /* The moved-here-children query returns info based on the
- * delete-half of the move. Check if that the copied-half of
- * the move matches this information. */
- err = read_info(&child_status, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL,
- wcroot, moved_here_child_relpath,
- iterpool, iterpool);
- if (err)
- return svn_error_compose_create(err, svn_sqlite__reset(stmt));
+ const char *move_relpath
+ = svn_sqlite__column_text(stmt, 0, NULL);
+ const char *move_subtree_relpath
+ = svn_relpath_skip_ancestor(local_relpath, move_relpath);
+ const char *child_moved_to
+ = svn_sqlite__column_text(stmt, 1, NULL);
+ const char *child_moved_to_subtree_relpath
+ = svn_relpath_skip_ancestor(local_relpath, child_moved_to);
+ apr_int64_t child_op_depth = svn_sqlite__column_int64(stmt, 2);
+
+ moved_node = apr_palloc(scratch_pool,
+ sizeof(struct moved_node_t));
+ if (move_subtree_relpath)
+ moved_node->local_relpath
+ = svn_relpath_join(b->moved_to_relpath,
+ move_subtree_relpath, scratch_pool);
+ else
+ moved_node->local_relpath
+ = apr_pstrdup(scratch_pool, move_relpath);
- if (child_status == svn_wc__db_status_added)
- {
- err = scan_addition(&child_status, NULL, NULL, NULL,
- NULL, NULL, NULL,
- &child_moved_from_relpath,
- &child_delete_op_root_relpath,
- wcroot, moved_here_child_relpath,
- iterpool, iterpool);
- if (err)
- return svn_error_compose_create(err,
- svn_sqlite__reset(stmt));
- }
-#ifdef SVN_DEBUG
- /* This catches incorrectly recorded moves.
- * It is possible to hit this during normal operation
- * if a move was interrupted mid-way so only perform
- * this check in debug mode. */
- SVN_ERR_ASSERT(child_moved_from_relpath &&
- !strcmp(child_moved_from_relpath,
- svn_sqlite__column_text(stmt, 1, NULL)));
-#endif
- if (child_status == svn_wc__db_status_moved_here)
- {
- const char *child_subtree_relpath;
- const char *new_moved_to_relpath;
+ if (child_moved_to_subtree_relpath)
+ moved_node->moved_to_relpath
+ = svn_relpath_join(b->moved_to_relpath,
+ child_moved_to_subtree_relpath,
+ scratch_pool);
+ else
+ moved_node->moved_to_relpath
+ = apr_pstrdup(scratch_pool, child_moved_to);
- /* Compute the new moved-to path for this child... */
- child_subtree_relpath =
- svn_relpath_skip_ancestor(local_relpath,
- moved_here_child_relpath);
- SVN_ERR_ASSERT(child_subtree_relpath);
-
- new_moved_to_relpath =
- svn_relpath_join(b->moved_to_relpath,
- child_subtree_relpath, iterpool);
- /* ... and update the BASE moved-to record. */
- err = delete_update_movedto(wcroot, child_moved_from_relpath,
- new_moved_to_relpath,
- scratch_pool);
+ if (child_op_depth > b->delete_depth
+ && svn_relpath_skip_ancestor(local_relpath,
+ moved_node->local_relpath))
+ moved_node->op_depth = b->delete_depth;
+ else
+ moved_node->op_depth = child_op_depth;
- if (err)
- return svn_error_trace(svn_error_compose_create(
- err,
- svn_sqlite__reset(stmt)));
- }
+ APR_ARRAY_PUSH(moved_nodes, const struct moved_node_t *)
+ = moved_node;
SVN_ERR(svn_sqlite__step(&have_row, stmt));
}
- svn_pool_destroy(iterpool);
-
SVN_ERR(svn_sqlite__reset(stmt));
}
}
+ /* Find children that were moved out of the subtree rooted at this node.
+ * We'll need to update their op-depth columns because their deletion
+ * is now implied by the deletion of their parent (i.e. this node). */
+ if (kind == svn_kind_dir && !b->moved_to_relpath)
+ {
+ apr_pool_t *iterpool;
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_SELECT_MOVED_PAIR2));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+ iterpool = svn_pool_create(scratch_pool);
+ while (have_row)
+ {
+ struct moved_node_t *moved_node
+ = apr_palloc(scratch_pool, sizeof(struct moved_node_t));
+
+ moved_node->local_relpath
+ = svn_sqlite__column_text(stmt, 0, scratch_pool);
+ moved_node->moved_to_relpath
+ = svn_sqlite__column_text(stmt, 1, scratch_pool);
+ moved_node->op_depth = b->delete_depth;
+
+ if (!moved_nodes)
+ moved_nodes = apr_array_make(scratch_pool, 1,
+ sizeof(struct moved_node_t *));
+ APR_ARRAY_PUSH(moved_nodes, const struct moved_node_t *) = moved_node;
+
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ }
+ svn_pool_destroy(iterpool);
+ SVN_ERR(svn_sqlite__reset(stmt));
+ }
+
if (op_root)
{
svn_boolean_t below_base;
@@ -6487,7 +6554,7 @@ delete_node(void *baton,
SVN_ERR(scan_addition(&status, NULL, NULL, NULL, NULL, NULL, NULL,
&moved_from_relpath,
- &moved_from_op_root_relpath,
+ &moved_from_op_root_relpath, NULL,
wcroot, local_relpath,
scratch_pool, scratch_pool));
if (status == svn_wc__db_status_moved_here &&
@@ -6547,12 +6614,6 @@ delete_node(void *baton,
if (add_work)
{
/* Delete the node at LOCAL_RELPATH, and possibly mark it as moved. */
- if (b->moved_to_relpath)
- {
- /* Record moved-to relpath in BASE. */
- SVN_ERR(delete_update_movedto(wcroot, local_relpath,
- b->moved_to_relpath, scratch_pool));
- }
/* Delete the node and possible descendants. */
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
@@ -6563,6 +6624,23 @@ delete_node(void *baton,
SVN_ERR(svn_sqlite__step_done(stmt));
}
+ if (moved_nodes)
+ {
+ int i;
+
+ for (i = 0; i < moved_nodes->nelts; ++i)
+ {
+ const struct moved_node_t *moved_node
+ = APR_ARRAY_IDX(moved_nodes, i, void *);
+
+ SVN_ERR(delete_update_movedto(wcroot,
+ moved_node->local_relpath,
+ moved_node->op_depth,
+ moved_node->moved_to_relpath,
+ scratch_pool));
+ }
+ }
+
return SVN_NO_ERROR;
}
@@ -7422,29 +7500,29 @@ read_children_info(void *baton,
if (op_depth == 0)
{
- const char *moved_to_relpath;
-
child_item->info.have_base = TRUE;
/* Get the lock info, available only at op_depth 0. */
child_item->info.lock = lock_from_columns(stmt, 15, 16, 17, 18,
result_pool);
- /* Moved-to is only stored at op_depth 0. */
- moved_to_relpath = svn_sqlite__column_text(stmt, 21, NULL);
- if (moved_to_relpath)
- child_item->info.moved_to_abspath =
- svn_dirent_join(wcroot->abspath, moved_to_relpath, result_pool);
-
/* FILE_EXTERNAL flag only on op_depth 0. */
child_item->info.file_external = svn_sqlite__column_boolean(stmt,
22);
}
else
{
+ const char *moved_to_relpath;
+
child_item->nr_layers++;
child_item->info.have_more_work = (child_item->nr_layers > 1);
+ /* Moved-to can only exist at op_depth > 0. */
+ moved_to_relpath = svn_sqlite__column_text(stmt, 21, NULL);
+ if (moved_to_relpath)
+ child_item->info.moved_to_abspath =
+ svn_dirent_join(wcroot->abspath, moved_to_relpath, result_pool);
+
/* Moved-here can only exist at op_depth > 0. */
child_item->info.moved_here = svn_sqlite__column_boolean(stmt, 20);
}
@@ -7851,7 +7929,8 @@ read_url_txn(void *baton,
if (status == svn_wc__db_status_added)
{
SVN_ERR(scan_addition(NULL, NULL, &repos_relpath, &repos_id, NULL,
- NULL, NULL, NULL, NULL, wcroot, local_relpath,
+ NULL, NULL, NULL, NULL, NULL,
+ wcroot, local_relpath,
scratch_pool, scratch_pool));
}
else if (status == svn_wc__db_status_deleted)
@@ -7884,7 +7963,7 @@ read_url_txn(void *baton,
scratch_pool);
SVN_ERR(scan_addition(NULL, NULL, &repos_relpath, &repos_id,
- NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
wcroot, work_relpath,
scratch_pool, scratch_pool));
@@ -8633,7 +8712,7 @@ svn_wc__db_global_relocate(svn_wc__db_t
if (status == svn_wc__db_status_added)
{
SVN_ERR(scan_addition(NULL, NULL, NULL, &rb.old_repos_id,
- NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
wcroot, local_dir_relpath,
scratch_pool, scratch_pool));
}
@@ -9567,6 +9646,7 @@ get_moved_from_info(svn_wc__db_status_t
const char **moved_from_relpath,
const char **moved_from_op_root_relpath,
const char *moved_to_op_root_relpath,
+ apr_int64_t *op_depth,
svn_wc__db_wcroot_t *wcroot,
const char *local_relpath,
apr_pool_t *result_pool,
@@ -9602,6 +9682,9 @@ get_moved_from_info(svn_wc__db_status_t
if (status)
*status = svn_wc__db_status_moved_here;
+ if (op_depth)
+ *op_depth = svn_sqlite__column_int64(stmt, 1);
+
if (moved_from_relpath || moved_from_op_root_relpath)
{
const char *db_delete_op_root_relpath;
@@ -9663,6 +9746,7 @@ struct scan_addition_baton_t
svn_revnum_t *original_revision;
const char **moved_from_relpath;
const char **moved_from_op_root_relpath;
+ apr_int64_t *moved_from_op_depth;
apr_pool_t *result_pool;
};
@@ -9692,6 +9776,8 @@ scan_addition_txn(void *baton,
*sab->moved_from_relpath = NULL;
if (sab->moved_from_op_root_relpath)
*sab->moved_from_op_root_relpath = NULL;
+ if (sab->moved_from_op_depth)
+ *sab->moved_from_op_depth = 0;
{
svn_sqlite__stmt_t *stmt;
@@ -9822,8 +9908,9 @@ scan_addition_txn(void *baton,
SVN_ERR(get_moved_from_info(sab->status,
sab->moved_from_relpath,
sab->moved_from_op_root_relpath,
- op_root_relpath, wcroot,
- local_relpath,
+ op_root_relpath,
+ sab->moved_from_op_depth,
+ wcroot, local_relpath,
sab->result_pool,
scratch_pool));
else if (sab->status)
@@ -9944,6 +10031,7 @@ scan_addition(svn_wc__db_status_t *statu
svn_revnum_t *original_revision,
const char **moved_from_relpath,
const char **moved_from_op_root_relpath,
+ apr_int64_t *moved_from_op_depth,
svn_wc__db_wcroot_t *wcroot,
const char *local_relpath,
apr_pool_t *result_pool,
@@ -9960,6 +10048,7 @@ scan_addition(svn_wc__db_status_t *statu
sab.original_revision = original_revision;
sab.moved_from_relpath = moved_from_relpath;
sab.moved_from_op_root_relpath = moved_from_op_root_relpath;
+ sab.moved_from_op_depth = moved_from_op_depth;
sab.result_pool = result_pool;
return svn_error_trace(svn_wc__db_with_txn(wcroot, local_relpath,
@@ -10006,8 +10095,8 @@ svn_wc__db_scan_addition(svn_wc__db_stat
SVN_ERR(scan_addition(status, &op_root_relpath, repos_relpath, repos_id_p,
original_repos_relpath, original_repos_id_p,
original_revision, &moved_from_relpath,
- &moved_from_op_root_relpath, wcroot, local_relpath,
- result_pool, scratch_pool));
+ &moved_from_op_root_relpath, NULL,
+ wcroot, local_relpath, result_pool, scratch_pool));
if (op_root_abspath)
*op_root_abspath = svn_dirent_join(wcroot->abspath, op_root_relpath,
Modified: subversion/trunk/subversion/tests/libsvn_wc/db-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_wc/db-test.c?rev=1300933&r1=1300932&r2=1300933&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/db-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/db-test.c Thu Mar 15 11:49:51 2012
@@ -228,8 +228,12 @@ static const char * const TESTING_DATA =
" 1, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 2, " TIME_2s ", '" AUTHOR_2 "',"
" 10, null, null, null);"
"insert into nodes values ("
- " 1, 'moved/file', 0, 'moved', 2, 'moved/file', 2, 'base-deleted',"
- " 0, 'J/J-d', 'file', '()', null, '$sha1$" SHA1_1 "', null, 2, " TIME_2s ", '" AUTHOR_2 "',"
+ " 1, 'moved/file', 0, 'moved', 2, 'moved/file', 2, 'normal',"
+ " 0, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 2, " TIME_2s ", '" AUTHOR_2 "',"
+ " 10, null, null, null);"
+ "insert into nodes values ("
+ " 1, 'moved/file', 2, 'moved', 2, 'moved/file', 2, 'base-deleted',"
+ " 0, 'J/J-d', 'file', '()', null, null, null, null, null, null,"
" 10, null, null, null);"
"insert into nodes values ("
" 1, 'J/J-e', 1, 'J', null, null, null, 'normal',"
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=1300933&r1=1300932&r2=1300933&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Thu Mar 15 11:49:51 2012
@@ -328,7 +328,7 @@ typedef struct nodes_row_t {
/* Macro for filling in the REPO_* fields of a non-base NODES_ROW_T
* that has no copy-from info. */
-#define NO_COPY_FROM SVN_INVALID_REVNUM, NULL
+#define NO_COPY_FROM SVN_INVALID_REVNUM, NULL, FALSE
#define MOVED_HERE FALSE, NULL, TRUE
/* Return a human-readable string representing ROW. */
@@ -1713,8 +1713,8 @@ test_wc_move(const svn_test_opts_t *opts
{ 0, "", "normal", 1, "" },
{ 0, "A", "normal", 1, "A" },
{ 0, "A/B", "normal", 1, "A/B" },
- { 0, "A/B/C", "normal", 1, "A/B/C", FALSE, "A/B/C-move" },
- { 3, "A/B/C", "base-deleted", NO_COPY_FROM },
+ { 0, "A/B/C", "normal", 1, "A/B/C"},
+ { 3, "A/B/C", "base-deleted", NO_COPY_FROM, "A/B/C-move" },
{ 3, "A/B/C-move", "normal", 1, "A/B/C", MOVED_HERE },
{ 0 }
};
@@ -1726,13 +1726,13 @@ test_wc_move(const svn_test_opts_t *opts
nodes_row_t rows[] = {
{ 0, "", "normal", 1, "" },
{ 0, "A", "normal", 1, "A" },
- { 0, "A/B", "normal", 1, "A/B", FALSE, "A/B-move" },
- { 0, "A/B/C", "normal", 1, "A/B/C", FALSE, "A/B-move/C-move" },
- { 2, "A/B", "base-deleted", NO_COPY_FROM },
- { 2, "A/B/C", "base-deleted", NO_COPY_FROM },
+ { 0, "A/B", "normal", 1, "A/B"},
+ { 0, "A/B/C", "normal", 1, "A/B/C"},
+ { 2, "A/B", "base-deleted", NO_COPY_FROM, "A/B-move" },
+ { 2, "A/B/C", "base-deleted", NO_COPY_FROM},
{ 2, "A/B-move", "normal", 1, "A/B", MOVED_HERE },
{ 2, "A/B-move/C", "normal", 1, "A/B/C", MOVED_HERE },
- { 3, "A/B-move/C", "base-deleted", NO_COPY_FROM },
+ { 3, "A/B-move/C", "base-deleted", NO_COPY_FROM, "A/B-move/C-move" },
{ 3, "A/B-move/C-move", "normal", 1, "A/B/C", MOVED_HERE },
{ 0 }
};
@@ -3773,8 +3773,8 @@ nested_moves_child_first(const svn_test_
{0, "", "normal", 1, ""},
{0, "A", "normal", 1, "A"},
{0, "A/B", "normal", 1, "A/B"},
- {0, "A/B/C", "normal", 1, "A/B/C", FALSE, "A/B/C2"},
- {3, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
+ {3, "A/B/C", "base-deleted", NO_COPY_FROM, "A/B/C2"},
{3, "A/B/C2", "normal", 1, "A/B/C", MOVED_HERE},
{0}
};
@@ -3785,13 +3785,13 @@ nested_moves_child_first(const svn_test_
nodes_row_t nodes[] = {
{0, "", "normal", 1, ""},
{0, "A", "normal", 1, "A"},
- {0, "A/B", "normal", 1, "A/B", FALSE, "A/B2"},
- {0, "A/B/C", "normal", 1, "A/B/C", FALSE, "A/B2/C2"},
- {2, "A/B", "base-deleted", NO_COPY_FROM},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
+ {2, "A/B", "base-deleted", NO_COPY_FROM, "A/B2"},
{2, "A/B/C", "base-deleted", NO_COPY_FROM},
{2, "A/B2", "normal", 1, "A/B", MOVED_HERE},
{2, "A/B2/C", "normal", 1, "A/B/C", MOVED_HERE},
- {3, "A/B2/C", "base-deleted", NO_COPY_FROM},
+ {3, "A/B2/C", "base-deleted", NO_COPY_FROM, "A/B2/C2"},
{3, "A/B2/C2", "normal", 1, "A/B/C", MOVED_HERE},
{0}
};
@@ -3801,20 +3801,20 @@ nested_moves_child_first(const svn_test_
{
nodes_row_t nodes[] = {
{0, "", "normal", 1, ""},
- {0, "A", "normal", 1, "A", FALSE, "A2"},
- {0, "A/B", "normal", 1, "A/B", FALSE, "A2/B2"},
- {0, "A/B/C", "normal", 1, "A/B/C", FALSE, "A2/B2/C2"},
- {1, "A", "base-deleted", NO_COPY_FROM},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
{1, "A/B", "base-deleted", NO_COPY_FROM},
{1, "A/B/C", "base-deleted", NO_COPY_FROM},
{1, "A2", "normal", 1, "A", MOVED_HERE},
{1, "A2/B", "normal", 1, "A/B", MOVED_HERE},
{1, "A2/B/C", "normal", 1, "A/B/C", MOVED_HERE},
- {2, "A2/B", "base-deleted", NO_COPY_FROM},
+ {2, "A2/B", "base-deleted", NO_COPY_FROM, "A2/B2"},
{2, "A2/B/C", "base-deleted", NO_COPY_FROM},
{2, "A2/B2", "normal", 1, "A/B", MOVED_HERE},
{2, "A2/B2/C", "normal", 1, "A/B/C", MOVED_HERE},
- {3, "A2/B2/C", "base-deleted", NO_COPY_FROM},
+ {3, "A2/B2/C", "base-deleted", NO_COPY_FROM, "A2/B2/C2"},
{3, "A2/B2/C2","normal", 1, "A/B/C", MOVED_HERE},
{0}
};
@@ -3827,10 +3827,10 @@ nested_moves_child_first(const svn_test_
{
nodes_row_t nodes[] = {
{0, "", "normal", 1, ""},
- {0, "A", "normal", 1, "A", FALSE, "A2"},
+ {0, "A", "normal", 1, "A"},
{0, "A/B", "normal", 1, "A/B"},
{0, "A/B/C", "normal", 1, "A/B/C"},
- {1, "A", "base-deleted", NO_COPY_FROM},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
{1, "A/B", "base-deleted", NO_COPY_FROM},
{1, "A/B/C", "base-deleted", NO_COPY_FROM},
{1, "A2", "normal", 1, "A", MOVED_HERE},
@@ -3871,10 +3871,10 @@ nested_moves_child_last(const svn_test_o
{
nodes_row_t nodes[] = {
{0, "", "normal", 1, ""},
- {0, "A", "normal", 1, "A", FALSE, "A2"},
+ {0, "A", "normal", 1, "A"},
{0, "A/B", "normal", 1, "A/B"},
{0, "A/B/C", "normal", 1, "A/B/C"},
- {1, "A", "base-deleted", NO_COPY_FROM},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
{1, "A/B", "base-deleted", NO_COPY_FROM},
{1, "A/B/C", "base-deleted", NO_COPY_FROM},
{1, "A2", "normal", 1, "A", MOVED_HERE},
@@ -3888,16 +3888,16 @@ nested_moves_child_last(const svn_test_o
{
nodes_row_t nodes[] = {
{0, "", "normal", 1, ""},
- {0, "A", "normal", 1, "A", FALSE, "A2"},
- {0, "A/B", "normal", 1, "A/B", FALSE, "A2/B2"},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
{0, "A/B/C", "normal", 1, "A/B/C"},
- {1, "A", "base-deleted", NO_COPY_FROM},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
{1, "A/B", "base-deleted", NO_COPY_FROM},
{1, "A/B/C", "base-deleted", NO_COPY_FROM},
{1, "A2", "normal", 1, "A", MOVED_HERE},
{1, "A2/B", "normal", 1, "A/B", MOVED_HERE},
{1, "A2/B/C", "normal", 1, "A/B/C", MOVED_HERE},
- {2, "A2/B", "base-deleted", NO_COPY_FROM},
+ {2, "A2/B", "base-deleted", NO_COPY_FROM, "A2/B2"},
{2, "A2/B/C", "base-deleted", NO_COPY_FROM},
{2, "A2/B2", "normal", 1, "A/B", MOVED_HERE},
{2, "A2/B2/C", "normal", 1, "A/B/C", MOVED_HERE},
@@ -3909,20 +3909,20 @@ nested_moves_child_last(const svn_test_o
{
nodes_row_t nodes[] = {
{0, "", "normal", 1, ""},
- {0, "A", "normal", 1, "A", FALSE, "A2"},
- {0, "A/B", "normal", 1, "A/B", FALSE, "A2/B2"},
- {0, "A/B/C", "normal", 1, "A/B/C", FALSE, "A2/B2/C2"},
- {1, "A", "base-deleted", NO_COPY_FROM},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
{1, "A/B", "base-deleted", NO_COPY_FROM},
{1, "A/B/C", "base-deleted", NO_COPY_FROM},
{1, "A2", "normal", 1, "A", MOVED_HERE},
{1, "A2/B", "normal", 1, "A/B", MOVED_HERE},
{1, "A2/B/C", "normal", 1, "A/B/C", MOVED_HERE},
- {2, "A2/B", "base-deleted", NO_COPY_FROM},
+ {2, "A2/B", "base-deleted", NO_COPY_FROM, "A2/B2"},
{2, "A2/B/C", "base-deleted", NO_COPY_FROM},
{2, "A2/B2", "normal", 1, "A/B", MOVED_HERE},
{2, "A2/B2/C", "normal", 1, "A/B/C", MOVED_HERE},
- {3, "A2/B2/C", "base-deleted", NO_COPY_FROM},
+ {3, "A2/B2/C", "base-deleted", NO_COPY_FROM, "A2/B2/C2"},
{3, "A2/B2/C2","normal", 1, "A/B/C", MOVED_HERE},
{0}
};
@@ -3935,10 +3935,10 @@ nested_moves_child_last(const svn_test_o
{
nodes_row_t nodes[] = {
{0, "", "normal", 1, ""},
- {0, "A", "normal", 1, "A", FALSE, "A2"},
+ {0, "A", "normal", 1, "A"},
{0, "A/B", "normal", 1, "A/B"},
{0, "A/B/C", "normal", 1, "A/B/C"},
- {1, "A", "base-deleted", NO_COPY_FROM},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
{1, "A/B", "base-deleted", NO_COPY_FROM},
{1, "A/B/C", "base-deleted", NO_COPY_FROM},
{1, "A2", "normal", 1, "A", MOVED_HERE},
@@ -3976,8 +3976,7 @@ move_in_copy(const svn_test_opts_t *opts
};
SVN_ERR(check_db_rows(&b, "", nodes));
}
- SVN_ERR(wc_move(&b, "A2/B", "A2/B2")); /* ### Moved-here gets recorded, but
- not moved-to. */
+ SVN_ERR(wc_move(&b, "A2/B", "A2/B2"));
{
nodes_row_t nodes[] = {
{0, "", "normal", 1, ""},
@@ -3985,8 +3984,8 @@ move_in_copy(const svn_test_opts_t *opts
{0, "A/B", "normal", 1, "A/B"},
{1, "A2", "normal", 1, "A"},
{1, "A2/B", "normal", 1, "A/B"},
- {2, "A2/B", "base-deleted", NO_COPY_FROM},
- {2, "A2/B2", "normal", 1, "A/B"},
+ {2, "A2/B", "base-deleted", NO_COPY_FROM, "A2/B2"},
+ {2, "A2/B2", "normal", 1, "A/B", MOVED_HERE},
{0}
};
SVN_ERR(check_db_rows(&b, "", nodes));
@@ -4024,9 +4023,7 @@ move_in_replace(const svn_test_opts_t *o
};
SVN_ERR(check_db_rows(&b, "", nodes));
}
- SVN_ERR(wc_move(&b, "A/B", "A/B2")); /* ### Moved-to gets recorded on A/B
- at op-depth=0, that's not the node
- that got moved. */
+ SVN_ERR(wc_move(&b, "A/B", "A/B2"));
{
nodes_row_t nodes[] = {
{0, "", "normal", 1, ""},
@@ -4036,7 +4033,7 @@ move_in_replace(const svn_test_opts_t *o
{0, "X/B", "normal", 1, "X/B"},
{1, "A", "normal", 1, "X"},
{1, "A/B", "normal", 1, "X/B"},
- {2, "A/B", "base-deleted", NO_COPY_FROM},
+ {2, "A/B", "base-deleted", NO_COPY_FROM, "A/B2"},
{2, "A/B2", "normal", 1, "X/B", MOVED_HERE},
{0}
};
@@ -4075,9 +4072,9 @@ copy_a_move(const svn_test_opts_t *opts,
{0, "", "normal", 1, ""},
{0, "A", "normal", 1, "A"},
{0, "A/B", "normal", 1, "A/B"},
- {0, "A/B/C", "normal", 1, "A/B/C", FALSE, "A/C2"},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
{2, "A/C2", "normal", 1, "A/B/C", MOVED_HERE},
- {3, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {3, "A/B/C", "base-deleted", NO_COPY_FROM, "A/C2"},
{0}
};
SVN_ERR(check_db_rows(&b, "", nodes));
@@ -4091,14 +4088,14 @@ copy_a_move(const svn_test_opts_t *opts,
{0, "", "normal", 1, ""},
{0, "A", "normal", 1, "A"},
{0, "A/B", "normal", 1, "A/B"},
- {0, "A/B/C", "normal", 1, "A/B/C", FALSE, "A/C2"},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
{2, "A/C2", "normal", 1, "A/B/C", MOVED_HERE},
- {3, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {3, "A/B/C", "base-deleted", NO_COPY_FROM, "A/C2"},
{1, "A2", "normal", 1, "A"},
{1, "A2/B", "normal", 1, "A/B"},
{1, "A2/B/C", "normal", 1, "A/B/C"},
- {2, "A2/C2", "normal", 1, "A/B/C"},
- {3, "A2/B/C", "base-deleted", NO_COPY_FROM},
+ {2, "A2/C2", "normal", 1, "A/B/C"}, /* MOVED_HERE? */
+ {3, "A2/B/C", "base-deleted", NO_COPY_FROM}, /* "A2/C2"? */
{0}
};
SVN_ERR(check_db_rows(&b, "", nodes));
@@ -4128,12 +4125,12 @@ move_to_swap(const svn_test_opts_t *opts
nodes_row_t nodes[] = {
{0, "", "normal", 1, ""},
{0, "A", "normal", 1, "A"},
- {0, "A/B", "normal", 1, "A/B", FALSE, "X/B"},
+ {0, "A/B", "normal", 1, "A/B"},
{0, "X", "normal", 1, "X"},
- {0, "X/Y", "normal", 1, "X/Y", FALSE, "A/Y"},
- {2, "A/B", "base-deleted", NO_COPY_FROM},
+ {0, "X/Y", "normal", 1, "X/Y"},
+ {2, "A/B", "base-deleted", NO_COPY_FROM, "X/B"},
{2, "A/Y", "normal", 1, "X/Y", MOVED_HERE},
- {2, "X/Y", "base-deleted", NO_COPY_FROM},
+ {2, "X/Y", "base-deleted", NO_COPY_FROM, "A/Y"},
{2, "X/B", "normal", 1, "A/B", MOVED_HERE},
{0}
};
@@ -4141,26 +4138,69 @@ move_to_swap(const svn_test_opts_t *opts
}
SVN_ERR(wc_move(&b, "A", "A2"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "X", "normal", 1, "X"},
+ {0, "X/Y", "normal", 1, "X/Y"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A2", "normal", 1, "A", MOVED_HERE},
+ {1, "A2/B", "normal", 1, "A/B", MOVED_HERE},
+ {2, "A2/B", "base-deleted", NO_COPY_FROM, "X/B"},
+ {2, "A2/Y", "normal", 1, "X/Y", MOVED_HERE},
+ {2, "X/Y", "base-deleted", NO_COPY_FROM, "A2/Y"},
+ {2, "X/B", "normal", 1, "A/B", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
SVN_ERR(wc_move(&b, "X", "A"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "X", "normal", 1, "X"},
+ {0, "X/Y", "normal", 1, "X/Y"},
+ {1, "A", "normal", 1, "X", FALSE, "A2", TRUE},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/Y", "normal", 1, "X/Y", MOVED_HERE},
+ {1, "A2", "normal", 1, "A", MOVED_HERE},
+ {1, "A2/B", "normal", 1, "A/B", MOVED_HERE},
+ {1, "X", "base-deleted", NO_COPY_FROM, "A"},
+ {1, "X/Y", "base-deleted", NO_COPY_FROM},
+ {2, "A/B", "normal", 1, "A/B", MOVED_HERE},
+ {2, "A/Y", "base-deleted", NO_COPY_FROM, "A2/Y"},
+ {2, "A2/B", "base-deleted", NO_COPY_FROM, "A/B"},
+ {2, "A2/Y", "normal", 1, "X/Y", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
SVN_ERR(wc_move(&b, "A2", "X"));
- /* Is this correct or should A/Y and X/B at op-depth=1 be marked
- moved-here? */
{
nodes_row_t nodes[] = {
{0, "", "normal", 1, ""},
- {0, "A", "normal", 1, "A", FALSE, "X"},
- {0, "A/B", "normal", 1, "A/B", FALSE, "A/B"},
- {0, "X", "normal", 1, "X", FALSE, "A"},
- {0, "X/Y", "normal", 1, "X/Y", FALSE, "X/Y"},
- {1, "A", "normal", 1, "X", MOVED_HERE},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "X", "normal", 1, "X"},
+ {0, "X/Y", "normal", 1, "X/Y"},
+ {1, "A", "normal", 1, "X", FALSE, "X", TRUE},
{1, "A/Y", "normal", 1, "X/Y", MOVED_HERE},
{1, "A/B", "base-deleted", NO_COPY_FROM},
- {1, "X", "normal", 1, "A", MOVED_HERE},
+ {1, "X", "normal", 1, "A", FALSE, "A", TRUE},
{1, "X/B", "normal", 1, "A/B", MOVED_HERE},
{1, "X/Y", "base-deleted", NO_COPY_FROM},
- {2, "A/Y", "base-deleted", NO_COPY_FROM},
- {2, "X/B", "base-deleted", NO_COPY_FROM},
+ {2, "A/Y", "base-deleted", NO_COPY_FROM, "X/Y"},
+ {2, "X/B", "base-deleted", NO_COPY_FROM, "A/B"},
{2, "A/B", "normal", 1, "A/B", MOVED_HERE},
{2, "X/Y", "normal", 1, "X/Y", MOVED_HERE},
{0}
@@ -4178,14 +4218,14 @@ move_to_swap(const svn_test_opts_t *opts
{
nodes_row_t nodes[] = {
{0, "", "normal", 1, ""},
- {0, "A", "normal", 1, "A", FALSE, "X"},
+ {0, "A", "normal", 1, "A"},
{0, "A/B", "normal", 1, "A/B"},
- {0, "X", "normal", 1, "X", FALSE, "A"},
+ {0, "X", "normal", 1, "X"},
{0, "X/Y", "normal", 1, "X/Y"},
- {1, "A", "normal", 1, "X", MOVED_HERE},
+ {1, "A", "normal", 1, "X", FALSE, "X", TRUE},
{1, "A/Y", "normal", 1, "X/Y", MOVED_HERE},
{1, "A/B", "base-deleted", NO_COPY_FROM},
- {1, "X", "normal", 1, "A", MOVED_HERE},
+ {1, "X", "normal", 1, "A", FALSE, "A", TRUE},
{1, "X/B", "normal", 1, "A/B", MOVED_HERE},
{1, "X/Y", "base-deleted", NO_COPY_FROM},
{0}
@@ -4199,18 +4239,18 @@ move_to_swap(const svn_test_opts_t *opts
{
nodes_row_t nodes[] = {
{0, "", "normal", 1, ""},
- {0, "A", "normal", 1, "A", FALSE, "X"},
- {0, "A/B", "normal", 1, "A/B", FALSE, "A/B"},
- {0, "X", "normal", 1, "X", FALSE, "A"},
- {0, "X/Y", "normal", 1, "X/Y", FALSE, "X/Y"},
- {1, "A", "normal", 1, "X", MOVED_HERE},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "X", "normal", 1, "X"},
+ {0, "X/Y", "normal", 1, "X/Y"},
+ {1, "A", "normal", 1, "X", FALSE, "X", TRUE},
{1, "A/Y", "normal", 1, "X/Y", MOVED_HERE},
{1, "A/B", "base-deleted", NO_COPY_FROM},
- {1, "X", "normal", 1, "A", MOVED_HERE},
+ {1, "X", "normal", 1, "A", FALSE, "A", TRUE},
{1, "X/B", "normal", 1, "A/B", MOVED_HERE},
{1, "X/Y", "base-deleted", NO_COPY_FROM},
- {2, "A/Y", "base-deleted", NO_COPY_FROM},
- {2, "X/B", "base-deleted", NO_COPY_FROM},
+ {2, "A/Y", "base-deleted", NO_COPY_FROM, "X/Y"},
+ {2, "X/B", "base-deleted", NO_COPY_FROM, "A/B"},
{2, "A/B", "normal", 1, "A/B", MOVED_HERE},
{2, "X/Y", "normal", 1, "X/Y", MOVED_HERE},
{0}
@@ -4227,10 +4267,10 @@ revert_nested_move(const svn_test_opts_t
svn_test__sandbox_t b;
nodes_row_t nodes_A_moved[] = {
{0, "", "normal", 1, ""},
- {0, "A", "normal", 1, "A", FALSE, "A2"},
+ {0, "A", "normal", 1, "A"},
{0, "A/B", "normal", 1, "A/B"},
{0, "A/B/C", "normal", 1, "A/B/C"},
- {1, "A", "base-deleted", NO_COPY_FROM},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
{1, "A/B", "base-deleted", NO_COPY_FROM},
{1, "A/B/C", "base-deleted", NO_COPY_FROM},
{1, "A2", "normal", 1, "A", MOVED_HERE},
@@ -4240,16 +4280,16 @@ revert_nested_move(const svn_test_opts_t
};
nodes_row_t nodes_AB_moved[] = {
{0, "", "normal", 1, ""},
- {0, "A", "normal", 1, "A", FALSE, "A2"},
- {0, "A/B", "normal", 1, "A/B", FALSE, "A2/B2"},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
{0, "A/B/C", "normal", 1, "A/B/C"},
- {1, "A", "base-deleted", NO_COPY_FROM},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
{1, "A/B", "base-deleted", NO_COPY_FROM},
{1, "A/B/C", "base-deleted", NO_COPY_FROM},
{1, "A2", "normal", 1, "A", MOVED_HERE},
{1, "A2/B", "normal", 1, "A/B", MOVED_HERE},
{1, "A2/B/C", "normal", 1, "A/B/C", MOVED_HERE},
- {2, "A2/B", "base-deleted", NO_COPY_FROM},
+ {2, "A2/B", "base-deleted", NO_COPY_FROM, "A2/B2"},
{2, "A2/B/C", "base-deleted", NO_COPY_FROM},
{2, "A2/B2", "normal", 1, "A/B", MOVED_HERE},
{2, "A2/B2/C", "normal", 1, "A/B/C", MOVED_HERE},
@@ -4257,20 +4297,20 @@ revert_nested_move(const svn_test_opts_t
};
nodes_row_t nodes_ABC_moved[] = {
{0, "", "normal", 1, ""},
- {0, "A", "normal", 1, "A", FALSE, "A2"},
- {0, "A/B", "normal", 1, "A/B", FALSE, "A2/B2"},
- {0, "A/B/C", "normal", 1, "A/B/C", FALSE, "A2/B2/C2"},
- {1, "A", "base-deleted", NO_COPY_FROM},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
{1, "A/B", "base-deleted", NO_COPY_FROM},
{1, "A/B/C", "base-deleted", NO_COPY_FROM},
{1, "A2", "normal", 1, "A", MOVED_HERE},
{1, "A2/B", "normal", 1, "A/B", MOVED_HERE},
{1, "A2/B/C", "normal", 1, "A/B/C", MOVED_HERE},
- {2, "A2/B", "base-deleted", NO_COPY_FROM},
+ {2, "A2/B", "base-deleted", NO_COPY_FROM, "A2/B2"},
{2, "A2/B/C", "base-deleted", NO_COPY_FROM},
{2, "A2/B2", "normal", 1, "A/B", MOVED_HERE},
{2, "A2/B2/C", "normal", 1, "A/B/C", MOVED_HERE},
- {3, "A2/B2/C", "base-deleted", NO_COPY_FROM},
+ {3, "A2/B2/C", "base-deleted", NO_COPY_FROM, "A2/B2/C2"},
{3, "A2/B2/C2", "normal", 1, "A/B/C", MOVED_HERE},
{0}
};
@@ -4308,6 +4348,13 @@ revert_nested_move(const svn_test_opts_t
SVN_ERR(wc_revert(&b, "A2/B2", svn_depth_infinity));
SVN_ERR(check_db_rows(&b, "", nodes_A_moved));
+ /* Check moves in reverse order */
+ SVN_ERR(wc_revert(&b, "", svn_depth_infinity));
+ SVN_ERR(wc_move(&b, "A/B/C", "A/B/C2"));
+ SVN_ERR(wc_move(&b, "A/B", "A/B2"));
+ SVN_ERR(wc_move(&b, "A", "A2"));
+ SVN_ERR(check_db_rows(&b, "", nodes_ABC_moved));
+
return SVN_NO_ERROR;
}
@@ -4333,34 +4380,30 @@ move_on_move(const svn_test_opts_t *opts
nodes_row_t nodes[] = {
{0, "", "normal", 1, ""},
{0, "A", "normal", 1, "A"},
- {0, "A/B", "normal", 1, "A/B", FALSE, "B2"},
+ {0, "A/B", "normal", 1, "A/B"},
{0, "X", "normal", 1, "X"},
{0, "X/B", "normal", 1, "X/B"},
{1, "B2", "normal", 1, "A/B", MOVED_HERE},
{1, "A", "normal", 1, "X"},
- {1, "A/B", "normal", 1, "X/B"},
+ {1, "A/B", "normal", 1, "X/B", FALSE, "B2"},
{0}
};
SVN_ERR(check_db_rows(&b, "", nodes));
}
- /* A/B to B2 is already recorded in A/B but the copy has given us
- another A/B that we can move. A second move overwites the first
- move stored in A/B even though it's a different node being moved,
- and that breaks the recording of the move to B2. */
SVN_ERR(wc_move(&b, "A/B", "B3"));
{
nodes_row_t nodes[] = {
{0, "", "normal", 1, ""},
{0, "A", "normal", 1, "A"},
- {0, "A/B", "normal", 1, "A/B", FALSE, "B2"}, /* XFAIL */
+ {0, "A/B", "normal", 1, "A/B"},
{0, "X", "normal", 1, "X"},
{0, "X/B", "normal", 1, "X/B"},
{1, "B2", "normal", 1, "A/B", MOVED_HERE},
{1, "B3", "normal", 1, "X/B", MOVED_HERE},
{1, "A", "normal", 1, "X"},
- {1, "A/B", "normal", 1, "X/B"}, /* moved_to=B3? */
- {2, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B", "normal", 1, "X/B", FALSE, "B2"},
+ {2, "A/B", "base-deleted", NO_COPY_FROM, "B3"},
{0}
};
SVN_ERR(check_db_rows(&b, "", nodes));
@@ -4390,37 +4433,33 @@ move_on_move2(const svn_test_opts_t *opt
{
nodes_row_t nodes[] = {
{0, "", "normal", 1, ""},
- {0, "A", "normal", 1, "A", FALSE, "A2"},
+ {0, "A", "normal", 1, "A"},
{0, "A/B", "normal", 1, "A/B"},
{0, "X", "normal", 1, "X"},
{0, "X/B", "normal", 1, "X/B"},
{1, "A2", "normal", 1, "A", MOVED_HERE},
{1, "A2/B", "normal", 1, "A/B", MOVED_HERE},
- {1, "A", "normal", 1, "X"},
+ {1, "A", "normal", 1, "X", FALSE, "A2"},
{1, "A/B", "normal", 1, "X/B"},
{0}
};
SVN_ERR(check_db_rows(&b, "", nodes));
}
- /* A/B is already moved to A2/B but there is no explicit moved_to,
- we derive it from A. The copy has given us another A/B that we
- can move doing so stores explicit moved_to in A/B that breaks the
- recording of the first move to A2/B. */
SVN_ERR(wc_move(&b, "A/B", "B3"));
{
nodes_row_t nodes[] = {
{0, "", "normal", 1, ""},
- {0, "A", "normal", 1, "A", FALSE, "A2"},
- {0, "A/B", "normal", 1, "A/B"}, /* XFAIL */
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
{0, "X", "normal", 1, "X"},
{0, "X/B", "normal", 1, "X/B"},
{1, "A2", "normal", 1, "A", MOVED_HERE},
{1, "A2/B", "normal", 1, "A/B", MOVED_HERE},
{1, "B3", "normal", 1, "X/B", MOVED_HERE},
- {1, "A", "normal", 1, "X"},
- {1, "A/B", "normal", 1, "X/B"}, /* moved_to=B3? */
- {2, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A", "normal", 1, "X", FALSE, "A2"},
+ {1, "A/B", "normal", 1, "X/B"},
+ {2, "A/B", "base-deleted", NO_COPY_FROM, "B3"},
{0}
};
SVN_ERR(check_db_rows(&b, "", nodes));
@@ -4450,9 +4489,9 @@ move_added(const svn_test_opts_t *opts,
{
nodes_row_t nodes[] = {
{0, "", "normal", 1, ""},
- {0, "A", "normal", 1, "A", FALSE, "A2"},
+ {0, "A", "normal", 1, "A"},
{0, "A/B", "normal", 1, "A/B"},
- {1, "A", "base-deleted", NO_COPY_FROM},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
{1, "A/B", "base-deleted", NO_COPY_FROM},
{1, "A2", "normal", 1, "A", MOVED_HERE},
{1, "A2/B", "normal", 1, "A/B", MOVED_HERE},
@@ -4540,9 +4579,9 @@ struct svn_test_descriptor_t test_funcs[
"nested_moves_child_first"),
SVN_TEST_OPTS_PASS(nested_moves_child_last,
"nested_moves_child_last"),
- SVN_TEST_OPTS_XFAIL(move_in_copy,
+ SVN_TEST_OPTS_PASS(move_in_copy,
"move_in_copy"),
- SVN_TEST_OPTS_XFAIL(move_in_replace,
+ SVN_TEST_OPTS_PASS(move_in_replace,
"move_in_replace"),
SVN_TEST_OPTS_PASS(copy_a_move,
"copy_a_move"),
@@ -4550,9 +4589,9 @@ struct svn_test_descriptor_t test_funcs[
"move_to_swap"),
SVN_TEST_OPTS_PASS(revert_nested_move,
"revert_nested_move"),
- SVN_TEST_OPTS_XFAIL(move_on_move,
+ SVN_TEST_OPTS_PASS(move_on_move,
"move_on_move"),
- SVN_TEST_OPTS_XFAIL(move_on_move2,
+ SVN_TEST_OPTS_PASS(move_on_move2,
"move_on_move2"),
SVN_TEST_OPTS_XFAIL(move_added,
"move_added"),