summaryrefslogtreecommitdiff
path: root/subversion/tests/libsvn_wc/op-depth-test.c
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/tests/libsvn_wc/op-depth-test.c')
-rw-r--r--subversion/tests/libsvn_wc/op-depth-test.c6654
1 files changed, 6119 insertions, 535 deletions
diff --git a/subversion/tests/libsvn_wc/op-depth-test.c b/subversion/tests/libsvn_wc/op-depth-test.c
index c385c39..39afcf4 100644
--- a/subversion/tests/libsvn_wc/op-depth-test.c
+++ b/subversion/tests/libsvn_wc/op-depth-test.c
@@ -35,6 +35,7 @@
#include "svn_wc.h"
#include "svn_client.h"
#include "svn_hash.h"
+#include "svn_sorts.h"
#include "utils.h"
@@ -43,6 +44,8 @@
#include "private/svn_dep_compat.h"
#include "../../libsvn_wc/wc.h"
#include "../../libsvn_wc/wc_db.h"
+#include "../../libsvn_wc/workqueue.h"
+#include "../../libsvn_wc/conflicts.h"
#define SVN_WC__I_AM_WC_DB
#include "../../libsvn_wc/wc_db_private.h"
@@ -52,6 +55,14 @@
#pragma warning(disable: 4221) /* nonstandard extension used */
#endif
+/* This macro is not available in 1.8.x, but let's just use it here */
+#ifndef SVN_VA_NULL
+struct svn_null_pointer_constant_stdarg_sentinel_t;
+
+/** Null pointer constant used as a sentinel in variable argument lists. */
+#define SVN_VA_NULL ((struct svn_null_pointer_constant_stdarg_sentinel_t*)0)
+#endif
+
/* Compare strings, like strcmp but either or both may be NULL which
* compares equal to NULL and not equal to any non-NULL string. */
static int
@@ -77,260 +88,14 @@ open_wc_db(svn_sqlite__db_t **sdb,
apr_pool_t *scratch_pool)
{
SVN_ERR(svn_wc__db_util_open_db(sdb, wc_root_abspath, "wc.db",
- svn_sqlite__mode_readwrite, my_statements,
+ svn_sqlite__mode_readwrite,
+ FALSE /* exclusive */, my_statements,
result_pool, scratch_pool));
return SVN_NO_ERROR;
}
/* ---------------------------------------------------------------------- */
-/* Functions for easy manipulation of a WC. Paths given to these functions
- * can be relative to the WC root as stored in the WC baton. */
-
-/* Return the abspath of PATH which is absolute or relative to the WC in B. */
-#define wc_path(b, path) (svn_dirent_join((b)->wc_abspath, (path), (b)->pool))
-
-/* Create a file on disk at PATH, with TEXT as its content. */
-static void
-file_write(svn_test__sandbox_t *b, const char *path, const char *text)
-{
- FILE *f = fopen(wc_path(b, path), "w");
- fputs(text, f);
- fclose(f);
-}
-
-/* Schedule for addition the single node that exists on disk at PATH,
- * non-recursively. */
-static svn_error_t *
-wc_add(svn_test__sandbox_t *b, const char *path)
-{
- const char *parent_abspath;
- path = wc_path(b, path);
- parent_abspath = svn_dirent_dirname(path, b->pool);
- SVN_ERR(svn_wc__acquire_write_lock(NULL, b->wc_ctx, parent_abspath, FALSE,
- b->pool, b->pool));
- SVN_ERR(svn_wc_add_from_disk(b->wc_ctx, path, NULL, NULL, b->pool));
- SVN_ERR(svn_wc__release_write_lock(b->wc_ctx, parent_abspath, b->pool));
- return SVN_NO_ERROR;
-}
-
-/* Create a single directory on disk. */
-static svn_error_t *
-disk_mkdir(svn_test__sandbox_t *b, const char *path)
-{
- path = wc_path(b, path);
- SVN_ERR(svn_io_dir_make(path, APR_FPROT_OS_DEFAULT, b->pool));
- return SVN_NO_ERROR;
-}
-
-/* Create a single directory on disk and schedule it for addition. */
-static svn_error_t *
-wc_mkdir(svn_test__sandbox_t *b, const char *path)
-{
- SVN_ERR(disk_mkdir(b, path));
- SVN_ERR(wc_add(b, path));
- return SVN_NO_ERROR;
-}
-
-#if 0 /* not used */
-/* Copy the file or directory tree FROM_PATH to TO_PATH which must not exist
- * beforehand. */
-static svn_error_t *
-disk_copy(svn_test__sandbox_t *b, const char *from_path, const char *to_path)
-{
- const char *to_dir, *to_name;
- from_path = wc_path(b, from_path);
- to_path = wc_path(b, to_path);
- svn_dirent_split(&to_dir, &to_name, to_path, b->pool);
- return svn_io_copy_dir_recursively(from_path, to_dir, to_name,
- FALSE, NULL, NULL, b->pool);
-}
-#endif
-
-/* Copy the WC file or directory tree FROM_PATH to TO_PATH which must not
- * exist beforehand. */
-static svn_error_t *
-wc_copy(svn_test__sandbox_t *b, const char *from_path, const char *to_path)
-{
- from_path = wc_path(b, from_path);
- to_path = wc_path(b, to_path);
- return svn_wc_copy3(b->wc_ctx, from_path, to_path, FALSE,
- NULL, NULL, NULL, NULL, b->pool);
-}
-
-/* Revert a WC file or directory tree at PATH */
-static svn_error_t *
-wc_revert(svn_test__sandbox_t *b, const char *path, svn_depth_t depth)
-{
- const char *abspath = wc_path(b, path);
- const char *dir_abspath = svn_dirent_dirname(abspath, b->pool);
- const char *lock_root_abspath;
-
- SVN_ERR(svn_wc__acquire_write_lock(&lock_root_abspath, b->wc_ctx,
- dir_abspath, FALSE /* lock_anchor */,
- b->pool, b->pool));
- SVN_ERR(svn_wc_revert4(b->wc_ctx, abspath, depth, FALSE, NULL,
- NULL, NULL, /* cancel baton + func */
- NULL, NULL, /* notify baton + func */
- b->pool));
- SVN_ERR(svn_wc__release_write_lock(b->wc_ctx, lock_root_abspath, b->pool));
- return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-wc_delete(svn_test__sandbox_t *b, const char *path)
-{
- const char *abspath = wc_path(b, path);
- const char *dir_abspath = svn_dirent_dirname(abspath, b->pool);
- const char *lock_root_abspath;
-
- SVN_ERR(svn_wc__acquire_write_lock(&lock_root_abspath, b->wc_ctx,
- dir_abspath, FALSE,
- b->pool, b->pool));
- SVN_ERR(svn_wc_delete4(b->wc_ctx, abspath, FALSE, TRUE,
- NULL, NULL, /* cancel baton + func */
- NULL, NULL, /* notify baton + func */
- b->pool));
- SVN_ERR(svn_wc__release_write_lock(b->wc_ctx, lock_root_abspath, b->pool));
- return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-wc_exclude(svn_test__sandbox_t *b, const char *path)
-{
- const char *abspath = wc_path(b, path);
- const char *lock_root_abspath;
-
- SVN_ERR(svn_wc__acquire_write_lock(&lock_root_abspath, b->wc_ctx,
- abspath, TRUE,
- b->pool, b->pool));
- SVN_ERR(svn_wc_exclude(b->wc_ctx, abspath,
- NULL, NULL, /* cancel baton + func */
- NULL, NULL, /* notify baton + func */
- b->pool));
- SVN_ERR(svn_wc__release_write_lock(b->wc_ctx, lock_root_abspath, b->pool));
- return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-wc_commit(svn_test__sandbox_t *b, const char *path)
-{
- svn_client_ctx_t *ctx;
- apr_array_header_t *targets = apr_array_make(b->pool, 1,
- sizeof(const char *));
-
- APR_ARRAY_PUSH(targets, const char *) = wc_path(b, path);
- SVN_ERR(svn_client_create_context(&ctx, b->pool));
- return svn_client_commit5(targets, svn_depth_infinity,
- FALSE, FALSE, TRUE, /* keep locks/cl's/use_ops*/
- NULL, NULL, NULL, NULL, ctx, b->pool);
-}
-
-static svn_error_t *
-wc_update(svn_test__sandbox_t *b, const char *path, svn_revnum_t revnum)
-{
- svn_client_ctx_t *ctx;
- apr_array_header_t *result_revs;
- apr_array_header_t *paths = apr_array_make(b->pool, 1,
- sizeof(const char *));
- svn_opt_revision_t revision;
- revision.kind = svn_opt_revision_number;
- revision.value.number = revnum;
-
- APR_ARRAY_PUSH(paths, const char *) = wc_path(b, path);
- SVN_ERR(svn_client_create_context(&ctx, b->pool));
- return svn_client_update4(&result_revs, paths, &revision, svn_depth_infinity,
- TRUE, FALSE, FALSE, FALSE, FALSE,
- ctx, b->pool);
-}
-
-static svn_error_t *
-wc_resolved(svn_test__sandbox_t *b, const char *path)
-{
- svn_client_ctx_t *ctx;
-
- SVN_ERR(svn_client_create_context(&ctx, b->pool));
- return svn_client_resolved(wc_path(b, path), TRUE, ctx, b->pool);
-}
-
-static svn_error_t *
-wc_move(svn_test__sandbox_t *b, const char *src, const char *dst)
-{
- svn_client_ctx_t *ctx;
- apr_array_header_t *paths = apr_array_make(b->pool, 1,
- sizeof(const char *));
-
- SVN_ERR(svn_client_create_context(&ctx, b->pool));
- APR_ARRAY_PUSH(paths, const char *) = wc_path(b, src);
- return svn_client_move6(paths, wc_path(b, dst),
- FALSE, FALSE, NULL, NULL, NULL, ctx, b->pool);
-}
-
-static svn_error_t *
-wc_propset(svn_test__sandbox_t *b,
- const char *name,
- const char *value,
- const char *path)
-{
- svn_client_ctx_t *ctx;
- apr_array_header_t *paths = apr_array_make(b->pool, 1,
- sizeof(const char *));
-
- SVN_ERR(svn_client_create_context(&ctx, b->pool));
- APR_ARRAY_PUSH(paths, const char *) = wc_path(b, path);
- return svn_client_propset_local(name, svn_string_create(value, b->pool),
- paths, svn_depth_empty, TRUE, NULL, ctx,
- b->pool);
-}
-
-/* Create the Greek tree on disk in the WC, and commit it. */
-static svn_error_t *
-add_and_commit_greek_tree(svn_test__sandbox_t *b)
-{
- const char *greek_tree_dirs[8] =
- {
- "A",
- "A/B",
- "A/B/E",
- "A/B/F",
- "A/C",
- "A/D",
- "A/D/G",
- "A/D/H"
- };
- const char *greek_tree_files[12][2] =
- {
- { "iota", "This is the file 'iota'.\n" },
- { "A/mu", "This is the file 'mu'.\n" },
- { "A/B/lambda", "This is the file 'lambda'.\n" },
- { "A/B/E/alpha", "This is the file 'alpha'.\n" },
- { "A/B/E/beta", "This is the file 'beta'.\n" },
- { "A/D/gamma", "This is the file 'gamma'.\n" },
- { "A/D/G/pi", "This is the file 'pi'.\n" },
- { "A/D/G/rho", "This is the file 'rho'.\n" },
- { "A/D/G/tau", "This is the file 'tau'.\n" },
- { "A/D/H/chi", "This is the file 'chi'.\n" },
- { "A/D/H/psi", "This is the file 'psi'.\n" },
- { "A/D/H/omega", "This is the file 'omega'.\n" }
- };
- int i;
-
- for (i = 0; i < 8; i++)
- SVN_ERR(wc_mkdir(b, greek_tree_dirs[i]));
-
- for (i = 0; i < 12; i++)
- {
- file_write(b, greek_tree_files[i][0], greek_tree_files[i][1]);
- SVN_ERR(wc_add(b, greek_tree_files[i][0]));
- }
-
- SVN_ERR(wc_commit(b, ""));
-
- return SVN_NO_ERROR;
-}
-
-
-/* ---------------------------------------------------------------------- */
/* Functions for comparing expected and found WC DB data. */
/* Some of the fields from a NODES table row. */
@@ -341,36 +106,87 @@ typedef struct nodes_row_t {
svn_revnum_t repo_revnum;
const char *repo_relpath;
svn_boolean_t file_external;
+ const char *moved_to;
+ svn_boolean_t moved_here;
+ const char *props; /* comma-separated list of prop names */
} 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
+#define NOT_MOVED FALSE, NULL, FALSE
+
+/* Return a comma-separated list of the prop names in PROPS, in lexically
+ * ascending order, or NULL if PROPS is empty or NULL. (Here, we don't
+ * care about the difference between 'has no props' and 'can't have props',
+ * and we choose to represent both of those as NULL.) */
+static const char *
+props_hash_to_text(apr_hash_t *props, apr_pool_t *pool)
+{
+ apr_array_header_t *props_sorted;
+ svn_stringbuf_t *str;
+ int i;
+
+ if (! props)
+ return NULL;
+
+ str = svn_stringbuf_create_empty(pool);
+ props_sorted = svn_sort__hash(props, svn_sort_compare_items_lexically, pool);
+ for (i = 0; i < props_sorted->nelts; i++)
+ {
+ const svn_sort__item_t *item
+ = &APR_ARRAY_IDX(props_sorted, i, svn_sort__item_t);
+
+ if (str->len)
+ svn_stringbuf_appendbyte(str, ',');
+ svn_stringbuf_appendcstr(str, item->key);
+ }
+ return str->len ? str->data : NULL;
+}
/* Return a human-readable string representing ROW. */
static const char *
print_row(const nodes_row_t *row,
apr_pool_t *result_pool)
{
- const char *file_external_str;
+ const char *file_external_str, *moved_here_str, *moved_to_str, *props;
if (row == NULL)
return "(null)";
+ if (row->moved_to)
+ moved_to_str = apr_psprintf(result_pool, ", moved-to %s", row->moved_to);
+ else
+ moved_to_str = "";
+
+ if (row->moved_here)
+ moved_here_str = ", moved-here";
+ else
+ moved_here_str = "";
+
if (row->file_external)
file_external_str = ", file-external";
else
file_external_str = "";
-
+
+ if (row->props)
+ props = apr_psprintf(result_pool, ", p=(%s)", row->props);
+ else
+ props = "";
+
if (row->repo_revnum == SVN_INVALID_REVNUM)
- return apr_psprintf(result_pool, "%d, %s, %s%s",
+ return apr_psprintf(result_pool, "%d, \"%s\", \"%s\"%s%s%s%s",
row->op_depth, row->local_relpath, row->presence,
- file_external_str);
+ moved_here_str, moved_to_str,
+ file_external_str, props);
else
- return apr_psprintf(result_pool, "%d, %s, %s, from ^/%s@%d%s",
+ return apr_psprintf(result_pool, "%d, \"%s\", \"%s\", %s ^/%s@%d%s%s%s%s",
row->op_depth, row->local_relpath, row->presence,
+ row->op_depth == 0 ? "base" : "copyfrom",
row->repo_relpath, (int)row->repo_revnum,
- file_external_str);
+ moved_here_str, moved_to_str,
+ file_external_str, props);
}
/* A baton to pass through svn_hash_diff() to compare_nodes_rows(). */
@@ -412,7 +228,14 @@ compare_nodes_rows(const void *key, apr_ssize_t klen,
else if (expected->repo_revnum != found->repo_revnum
|| (strcmp_null(expected->repo_relpath, found->repo_relpath) != 0)
|| (strcmp_null(expected->presence, found->presence) != 0)
- || (expected->file_external != found->file_external))
+ || (expected->file_external != found->file_external)
+ || (expected->moved_here != found->moved_here)
+ || (expected->moved_to && !found->moved_to)
+ || (!expected->moved_to && found->moved_to)
+ || (expected->moved_to
+ && strcmp(expected->moved_to, found->moved_to))
+ || (expected->props != NULL
+ && strcmp_null(expected->props, found->props) != 0))
{
b->errors = svn_error_createf(
SVN_ERR_TEST_FAILED, b->errors,
@@ -441,10 +264,13 @@ check_db_rows(svn_test__sandbox_t *b,
int i;
svn_sqlite__stmt_t *stmt;
static const char *const statements[] = {
- "SELECT op_depth, presence, local_relpath, revision, repos_path, "
- " file_external "
- "FROM nodes "
- "WHERE local_relpath = ?1 OR local_relpath LIKE ?2",
+ "SELECT op_depth, nodes.presence, nodes.local_relpath, revision,"
+ " repos_path, file_external, def_local_relpath, moved_to, moved_here,"
+ " properties"
+ " FROM nodes "
+ " LEFT OUTER JOIN externals"
+ " ON nodes.local_relpath = externals.local_relpath"
+ " WHERE nodes.local_relpath = ?1 OR nodes.local_relpath LIKE ?2",
NULL };
#define STMT_SELECT_NODES_INFO 0
@@ -470,6 +296,7 @@ check_db_rows(svn_test__sandbox_t *b,
{
const char *key;
nodes_row_t *row = apr_palloc(b->pool, sizeof(*row));
+ apr_hash_t *props_hash;
row->op_depth = svn_sqlite__column_int(stmt, 0);
row->presence = svn_sqlite__column_text(stmt, 1, b->pool);
@@ -477,6 +304,15 @@ check_db_rows(svn_test__sandbox_t *b,
row->repo_revnum = svn_sqlite__column_revnum(stmt, 3);
row->repo_relpath = svn_sqlite__column_text(stmt, 4, b->pool);
row->file_external = !svn_sqlite__column_is_null(stmt, 5);
+ if (row->file_external && svn_sqlite__column_is_null(stmt, 6))
+ comparison_baton.errors
+ = svn_error_createf(SVN_ERR_TEST_FAILED, comparison_baton.errors,
+ "incomplete {%s}", print_row(row, b->pool));
+ row->moved_to = svn_sqlite__column_text(stmt, 7, b->pool);
+ row->moved_here = svn_sqlite__column_boolean(stmt, 8);
+ SVN_ERR(svn_sqlite__column_properties(&props_hash, stmt, 9,
+ b->pool, b->pool));
+ row->props = props_hash_to_text(props_hash, b->pool);
key = apr_psprintf(b->pool, "%d %s", row->op_depth, row->local_relpath);
apr_hash_set(found_hash, key, APR_HASH_KEY_STRING, row);
@@ -534,22 +370,22 @@ struct copy_subtest_t
static svn_error_t *
wc_wc_copies(svn_test__sandbox_t *b)
{
- SVN_ERR(add_and_commit_greek_tree(b));
+ SVN_ERR(sbox_add_and_commit_greek_tree(b));
/* Create the various kinds of source node which will be copied */
- file_write(b, source_added_file, "New file");
- SVN_ERR(wc_add(b, source_added_file));
- SVN_ERR(wc_mkdir(b, source_added_dir));
- SVN_ERR(wc_mkdir(b, source_added_dir2));
+ sbox_file_write(b, source_added_file, "New file");
+ SVN_ERR(sbox_wc_add(b, source_added_file));
+ SVN_ERR(sbox_wc_mkdir(b, source_added_dir));
+ SVN_ERR(sbox_wc_mkdir(b, source_added_dir2));
- SVN_ERR(wc_copy(b, source_base_file, source_copied_file));
- SVN_ERR(wc_copy(b, source_base_dir, source_copied_dir));
+ SVN_ERR(sbox_wc_copy(b, source_base_file, source_copied_file));
+ SVN_ERR(sbox_wc_copy(b, source_base_dir, source_copied_dir));
/* Delete some nodes so that we can test copying onto these paths */
- SVN_ERR(wc_delete(b, "A/D/gamma"));
- SVN_ERR(wc_delete(b, "A/D/G"));
+ SVN_ERR(sbox_wc_delete(b, "A/D/gamma"));
+ SVN_ERR(sbox_wc_delete(b, "A/D/G"));
/* Test copying various things */
@@ -647,11 +483,7 @@ wc_wc_copies(svn_test__sandbox_t *b)
/* Perform each subtest in turn. */
for (subtest = subtests; subtest->from_path; subtest++)
{
- SVN_ERR(svn_wc_copy3(b->wc_ctx,
- wc_path(b, subtest->from_path),
- wc_path(b, subtest->to_path),
- FALSE /* metadata_only */,
- NULL, NULL, NULL, NULL, b->pool));
+ SVN_ERR(sbox_wc_copy(b, subtest->from_path, subtest->to_path));
SVN_ERR(check_db_rows(b, subtest->to_path, subtest->expected));
}
}
@@ -664,14 +496,14 @@ wc_wc_copies(svn_test__sandbox_t *b)
static svn_error_t *
repo_wc_copies(svn_test__sandbox_t *b)
{
- SVN_ERR(add_and_commit_greek_tree(b));
+ SVN_ERR(sbox_add_and_commit_greek_tree(b));
/* Delete some nodes so that we can test copying onto these paths */
- SVN_ERR(wc_delete(b, "A/B/lambda"));
- SVN_ERR(wc_delete(b, "A/D/gamma"));
- SVN_ERR(wc_delete(b, "A/D/G"));
- SVN_ERR(wc_delete(b, "A/D/H"));
+ SVN_ERR(sbox_wc_delete(b, "A/B/lambda"));
+ SVN_ERR(sbox_wc_delete(b, "A/D/gamma"));
+ SVN_ERR(sbox_wc_delete(b, "A/D/G"));
+ SVN_ERR(sbox_wc_delete(b, "A/D/H"));
/* Test copying various things */
@@ -761,7 +593,7 @@ repo_wc_copies(svn_test__sandbox_t *b)
source.peg_revision = &rev;
APR_ARRAY_PUSH(sources, svn_client_copy_source_t *) = &source;
SVN_ERR(svn_client_copy6(sources,
- wc_path(b, subtest->to_path),
+ sbox_wc_path(b, subtest->to_path),
FALSE, FALSE, FALSE,
NULL, NULL, NULL, ctx, b->pool));
}
@@ -801,7 +633,7 @@ test_reverts(const svn_test_opts_t *opts, apr_pool_t *pool)
/* Implement revert tests below, now that we have a wc with lots of
copy-changes */
- SVN_ERR(wc_revert(&b, "A/B/D-added", svn_depth_infinity));
+ SVN_ERR(sbox_wc_revert(&b, "A/B/D-added", svn_depth_infinity));
SVN_ERR(check_db_rows(&b, "A/B/D-added", no_node_rows_expected));
return SVN_NO_ERROR;
@@ -813,10 +645,10 @@ test_deletes(const svn_test_opts_t *opts, apr_pool_t *pool)
svn_test__sandbox_t b;
SVN_ERR(svn_test__sandbox_create(&b, "deletes", opts, pool));
- SVN_ERR(add_and_commit_greek_tree(&b));
+ SVN_ERR(sbox_add_and_commit_greek_tree(&b));
- file_write(&b, "A/B/E/new-file", "New file");
- SVN_ERR(wc_add(&b, "A/B/E/new-file"));
+ sbox_file_write(&b, "A/B/E/new-file", "New file");
+ SVN_ERR(sbox_wc_add(&b, "A/B/E/new-file"));
{
nodes_row_t rows[] = {
{ 4, "A/B/E/new-file", "normal", NO_COPY_FROM },
@@ -825,7 +657,7 @@ test_deletes(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(check_db_rows(&b, "A/B/E/new-file", rows));
}
- SVN_ERR(wc_delete(&b, "A/B/E/alpha"));
+ SVN_ERR(sbox_wc_delete(&b, "A/B/E/alpha"));
{
nodes_row_t rows[] = {
{ 0, "A/B/E/alpha", "normal", 1, "A/B/E/alpha" },
@@ -835,7 +667,7 @@ test_deletes(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(check_db_rows(&b, "A/B/E/alpha", rows));
}
- SVN_ERR(wc_delete(&b, "A/B/F"));
+ SVN_ERR(sbox_wc_delete(&b, "A/B/F"));
{
nodes_row_t rows[] = {
{ 0, "A/B/F", "normal", 1, "A/B/F" },
@@ -845,7 +677,7 @@ test_deletes(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(check_db_rows(&b, "A/B/F", rows));
}
- SVN_ERR(wc_delete(&b, "A/B"));
+ SVN_ERR(sbox_wc_delete(&b, "A/B"));
{
nodes_row_t rows[] = {
{ 0, "A/B", "normal", 1, "A/B", },
@@ -874,11 +706,11 @@ test_adds(const svn_test_opts_t *opts, apr_pool_t *pool)
svn_test__sandbox_t b;
SVN_ERR(svn_test__sandbox_create(&b, "adds", opts, pool));
- SVN_ERR(add_and_commit_greek_tree(&b));
+ SVN_ERR(sbox_add_and_commit_greek_tree(&b));
/* add file */
- file_write(&b, "new-file", "New file");
- SVN_ERR(wc_add(&b, "new-file"));
+ sbox_file_write(&b, "new-file", "New file");
+ SVN_ERR(sbox_wc_add(&b, "new-file"));
{
nodes_row_t rows[] = {
{ 1, "new-file", "normal", NO_COPY_FROM },
@@ -887,8 +719,8 @@ test_adds(const svn_test_opts_t *opts, apr_pool_t *pool)
}
/* add dir */
- SVN_ERR(wc_mkdir(&b, "new-dir"));
- SVN_ERR(wc_mkdir(&b, "new-dir/D2"));
+ SVN_ERR(sbox_wc_mkdir(&b, "new-dir"));
+ SVN_ERR(sbox_wc_mkdir(&b, "new-dir/D2"));
{
nodes_row_t rows[] = {
{ 1, "new-dir", "normal", NO_COPY_FROM },
@@ -898,9 +730,9 @@ test_adds(const svn_test_opts_t *opts, apr_pool_t *pool)
}
/* replace file */
- SVN_ERR(wc_delete(&b, "iota"));
- file_write(&b, "iota", "New iota file");
- SVN_ERR(wc_add(&b, "iota"));
+ SVN_ERR(sbox_wc_delete(&b, "iota"));
+ sbox_file_write(&b, "iota", "New iota file");
+ SVN_ERR(sbox_wc_add(&b, "iota"));
{
nodes_row_t rows[] = {
{ 0, "iota", "normal", 1, "iota" },
@@ -910,9 +742,9 @@ test_adds(const svn_test_opts_t *opts, apr_pool_t *pool)
}
/* replace dir */
- SVN_ERR(wc_delete(&b, "A/B/E"));
- SVN_ERR(wc_mkdir(&b, "A/B/E"));
- SVN_ERR(wc_mkdir(&b, "A/B/E/D2"));
+ SVN_ERR(sbox_wc_delete(&b, "A/B/E"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/E"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/E/D2"));
{
nodes_row_t rows[] = {
{ 0, "A/B/E", "normal", 1, "A/B/E" },
@@ -935,12 +767,12 @@ test_adds_change_kind(const svn_test_opts_t *opts, apr_pool_t *pool)
svn_test__sandbox_t b;
SVN_ERR(svn_test__sandbox_create(&b, "adds", opts, pool));
- SVN_ERR(add_and_commit_greek_tree(&b));
+ SVN_ERR(sbox_add_and_commit_greek_tree(&b));
/* replace dir with file */
- SVN_ERR(wc_delete(&b, "A/B/E"));
- file_write(&b, "A/B/E", "New E file");
- SVN_ERR(wc_add(&b, "A/B/E"));
+ SVN_ERR(sbox_wc_delete(&b, "A/B/E"));
+ sbox_file_write(&b, "A/B/E", "New E file");
+ SVN_ERR(sbox_wc_add(&b, "A/B/E"));
{
nodes_row_t rows[] = {
{ 0, "A/B/E", "normal", 1, "A/B/E" },
@@ -954,9 +786,9 @@ test_adds_change_kind(const svn_test_opts_t *opts, apr_pool_t *pool)
}
/* replace file with dir */
- SVN_ERR(wc_delete(&b, "iota"));
- SVN_ERR(wc_mkdir(&b, "iota"));
- SVN_ERR(wc_mkdir(&b, "iota/D2"));
+ SVN_ERR(sbox_wc_delete(&b, "iota"));
+ SVN_ERR(sbox_wc_mkdir(&b, "iota"));
+ SVN_ERR(sbox_wc_mkdir(&b, "iota/D2"));
{
nodes_row_t rows[] = {
{ 0, "iota", "normal", 1, "iota" },
@@ -976,10 +808,10 @@ test_delete_of_copies(const svn_test_opts_t *opts, apr_pool_t *pool)
svn_test__sandbox_t b;
SVN_ERR(svn_test__sandbox_create(&b, "deletes_of_copies", opts, pool));
- SVN_ERR(add_and_commit_greek_tree(&b));
- SVN_ERR(wc_copy(&b, "A/B", "A/B-copied"));
+ SVN_ERR(sbox_add_and_commit_greek_tree(&b));
+ SVN_ERR(sbox_wc_copy(&b, "A/B", "A/B-copied"));
- SVN_ERR(wc_delete(&b, "A/B-copied/E"));
+ SVN_ERR(sbox_wc_delete(&b, "A/B-copied/E"));
{
nodes_row_t rows[] = {
{ 2, "A/B-copied/E", "normal", 1, "A/B/E" },
@@ -993,7 +825,7 @@ test_delete_of_copies(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(check_db_rows(&b, "A/B-copied/E", rows));
}
- SVN_ERR(wc_copy(&b, "A/D/G", "A/B-copied/E"));
+ SVN_ERR(sbox_wc_copy(&b, "A/D/G", "A/B-copied/E"));
{
nodes_row_t rows[] = {
{ 2, "A/B-copied/E", "normal", 1, "A/B/E" },
@@ -1010,7 +842,7 @@ test_delete_of_copies(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(check_db_rows(&b, "A/B-copied/E", rows));
}
- SVN_ERR(wc_delete(&b, "A/B-copied/E/rho"));
+ SVN_ERR(sbox_wc_delete(&b, "A/B-copied/E/rho"));
{
nodes_row_t rows[] = {
{ 2, "A/B-copied/E", "normal", 1, "A/B/E" },
@@ -1028,7 +860,7 @@ test_delete_of_copies(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(check_db_rows(&b, "A/B-copied/E", rows));
}
- SVN_ERR(wc_delete(&b, "A/B-copied/E"));
+ SVN_ERR(sbox_wc_delete(&b, "A/B-copied/E"));
{
nodes_row_t rows[] = {
{ 2, "A/B-copied/E", "normal", 1, "A/B/E" },
@@ -1042,9 +874,9 @@ test_delete_of_copies(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(check_db_rows(&b, "A/B-copied/E", rows));
}
- SVN_ERR(wc_copy(&b, "A/B", "A/B-copied/E"));
+ SVN_ERR(sbox_wc_copy(&b, "A/B", "A/B-copied/E"));
- SVN_ERR(wc_delete(&b, "A/B-copied/E/F"));
+ SVN_ERR(sbox_wc_delete(&b, "A/B-copied/E/F"));
{
nodes_row_t rows[] = {
{ 3, "A/B-copied/E/F", "normal", 1, "A/B/F" },
@@ -1054,7 +886,7 @@ test_delete_of_copies(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(check_db_rows(&b, "A/B-copied/E/F", rows));
}
- SVN_ERR(wc_delete(&b, "A/B-copied"));
+ SVN_ERR(sbox_wc_delete(&b, "A/B-copied"));
{
nodes_row_t rows[] = { { 0 } };
SVN_ERR(check_db_rows(&b, "A/B-copied", rows));
@@ -1070,11 +902,11 @@ test_delete_with_base(const svn_test_opts_t *opts, apr_pool_t *pool)
svn_test__sandbox_t b;
SVN_ERR(svn_test__sandbox_create(&b, "deletes_with_base", opts, pool));
- SVN_ERR(add_and_commit_greek_tree(&b));
- SVN_ERR(wc_delete(&b, "A/B/E/beta"));
- SVN_ERR(wc_commit(&b, ""));
+ SVN_ERR(sbox_add_and_commit_greek_tree(&b));
+ SVN_ERR(sbox_wc_delete(&b, "A/B/E/beta"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
- SVN_ERR(wc_delete(&b, "A/B/E"));
+ SVN_ERR(sbox_wc_delete(&b, "A/B/E"));
{
nodes_row_t rows[] = {
{ 0, "A/B/E", "normal", 1, "A/B/E"},
@@ -1087,9 +919,9 @@ test_delete_with_base(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(check_db_rows(&b, "A/B/E", rows));
}
- SVN_ERR(wc_copy(&b, "A/B/F", "A/B/E"));
- SVN_ERR(wc_copy(&b, "A/mu", "A/B/E/alpha"));
- SVN_ERR(wc_copy(&b, "A/mu", "A/B/E/beta"));
+ SVN_ERR(sbox_wc_copy(&b, "A/B/F", "A/B/E"));
+ SVN_ERR(sbox_wc_copy(&b, "A/mu", "A/B/E/alpha"));
+ SVN_ERR(sbox_wc_copy(&b, "A/mu", "A/B/E/beta"));
{
nodes_row_t rows[] = {
{ 0, "A/B/E", "normal", 1, "A/B/E"},
@@ -1105,7 +937,7 @@ test_delete_with_base(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(check_db_rows(&b, "A/B/E", rows));
}
- SVN_ERR(wc_delete(&b, "A/B/E"));
+ SVN_ERR(sbox_wc_delete(&b, "A/B/E"));
{
nodes_row_t rows[] = {
{ 0, "A/B/E", "normal", 1, "A/B/E"},
@@ -1137,16 +969,16 @@ test_delete_with_update(const svn_test_opts_t *opts, apr_pool_t *pool)
svn_test__sandbox_t b;
SVN_ERR(svn_test__sandbox_create(&b, "delete_with_update", opts, pool));
- SVN_ERR(wc_mkdir(&b, "A"));
- SVN_ERR(wc_commit(&b, ""));
- SVN_ERR(wc_mkdir(&b, "A/B"));
- SVN_ERR(wc_mkdir(&b, "A/B/C"));
- SVN_ERR(wc_commit(&b, ""));
- SVN_ERR(wc_update(&b, "", 1));
-
- SVN_ERR(wc_delete(&b, "A"));
- SVN_ERR(wc_mkdir(&b, "A"));
- SVN_ERR(wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_delete(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
{
nodes_row_t rows[] = {
{ 0, "A", "normal", 1, "A"},
@@ -1156,7 +988,7 @@ test_delete_with_update(const svn_test_opts_t *opts, apr_pool_t *pool)
};
SVN_ERR(check_db_rows(&b, "A", rows));
}
- SVN_ERR(wc_update(&b, "", 2));
+ SVN_ERR(sbox_wc_update(&b, "", 2));
{
nodes_row_t rows[] = {
{ 0, "A", "normal", 2, "A"},
@@ -1170,8 +1002,8 @@ test_delete_with_update(const svn_test_opts_t *opts, apr_pool_t *pool)
};
SVN_ERR(check_db_rows(&b, "A", rows));
}
- SVN_ERR(wc_resolved(&b, ""));
- SVN_ERR(wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_resolved(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
{
nodes_row_t rows[] = {
{ 0, "A", "normal", 1, "A"},
@@ -1213,9 +1045,9 @@ insert_dirs(svn_test__sandbox_t *b,
if (nodes->local_relpath[0])
{
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, 2));
- SVN_ERR(svn_sqlite__bindf(stmt, "sissrs",
+ SVN_ERR(svn_sqlite__bindf(stmt, "sdssrs",
nodes->local_relpath,
- (apr_int64_t)nodes->op_depth,
+ nodes->op_depth,
nodes->presence,
nodes->repo_relpath,
nodes->repo_revnum,
@@ -1225,9 +1057,9 @@ insert_dirs(svn_test__sandbox_t *b,
else
{
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, 1));
- SVN_ERR(svn_sqlite__bindf(stmt, "sissr",
+ SVN_ERR(svn_sqlite__bindf(stmt, "sdssr",
nodes->local_relpath,
- (apr_int64_t)nodes->op_depth,
+ nodes->op_depth,
nodes->presence,
nodes->repo_relpath,
nodes->repo_revnum));
@@ -1258,7 +1090,7 @@ base_dir_insert_remove(svn_test__sandbox_t *b,
nodes_row_t *added)
{
nodes_row_t *after;
- const char *dir_abspath = wc_path(b, local_relpath);
+ const char *dir_abspath = sbox_wc_path(b, local_relpath);
int i;
apr_int64_t num_before = count_rows(before), num_added = count_rows(added);
@@ -1270,10 +1102,10 @@ base_dir_insert_remove(svn_test__sandbox_t *b,
"not-even-a-uuid", revision,
apr_hash_make(b->pool), revision,
0, NULL, NULL, svn_depth_infinity,
- NULL, NULL, FALSE, NULL, NULL,
+ NULL, NULL, FALSE, NULL, NULL, NULL,
b->pool));
- after = apr_palloc(b->pool, sizeof(*after) * (num_before + num_added + 1));
+ after = apr_palloc(b->pool, sizeof(*after) * (apr_size_t)(num_before + num_added + 1));
for (i = 0; i < num_before; ++i)
after[i] = before[i];
for (i = 0; i < num_added; ++i)
@@ -1282,7 +1114,14 @@ base_dir_insert_remove(svn_test__sandbox_t *b,
SVN_ERR(check_db_rows(b, "", after));
- SVN_ERR(svn_wc__db_base_remove(b->wc_ctx->db, dir_abspath, b->pool));
+ SVN_ERR(svn_wc__db_base_remove(b->wc_ctx->db, dir_abspath,
+ FALSE /* keep_as_Working */,
+ FALSE /* queue_deletes */,
+ FALSE /* remove_locks */,
+ SVN_INVALID_REVNUM,
+ NULL, NULL, b->pool));
+ SVN_ERR(svn_wc__wq_run(b->wc_ctx->db, dir_abspath,
+ NULL, NULL, b->pool));
SVN_ERR(check_db_rows(b, "", before));
@@ -1598,7 +1437,7 @@ temp_op_make_copy(svn_test__sandbox_t *b,
SVN_ERR(insert_dirs(b, before));
- SVN_ERR(svn_wc__db_temp_op_make_copy(b->wc_ctx->db, dir_abspath, b->pool));
+ SVN_ERR(svn_wc__db_op_make_copy(b->wc_ctx->db, dir_abspath, NULL, NULL, b->pool));
SVN_ERR(check_db_rows(b, "", after));
@@ -1698,39 +1537,39 @@ test_wc_move(const svn_test_opts_t *opts, apr_pool_t *pool)
svn_test__sandbox_t b;
SVN_ERR(svn_test__sandbox_create(&b, "wc_move", opts, 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_commit(&b, ""));
- SVN_ERR(wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
- SVN_ERR(wc_move(&b, "A/B/C", "A/B/C-move"));
+ SVN_ERR(sbox_wc_move(&b, "A/B/C", "A/B/C-move"));
{
nodes_row_t rows[] = {
{ 0, "", "normal", 1, "" },
{ 0, "A", "normal", 1, "A" },
{ 0, "A/B", "normal", 1, "A/B" },
- { 0, "A/B/C", "normal", 1, "A/B/C" },
- { 3, "A/B/C", "base-deleted", NO_COPY_FROM },
- { 3, "A/B/C-move", "normal", 1, "A/B/C" },
+ { 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 }
};
SVN_ERR(check_db_rows(&b, "", rows));
}
- SVN_ERR(wc_move(&b, "A/B", "A/B-move"));
+ SVN_ERR(sbox_wc_move(&b, "A/B", "A/B-move"));
{
nodes_row_t rows[] = {
{ 0, "", "normal", 1, "" },
{ 0, "A", "normal", 1, "A" },
- { 0, "A/B", "normal", 1, "A/B" },
- { 0, "A/B/C", "normal", 1, "A/B/C" },
- { 2, "A/B", "base-deleted", NO_COPY_FROM },
- { 2, "A/B/C", "base-deleted", NO_COPY_FROM },
- { 2, "A/B-move", "normal", 1, "A/B" },
- { 2, "A/B-move/C", "normal", 1, "A/B/C" },
- { 3, "A/B-move/C", "base-deleted", NO_COPY_FROM },
- { 3, "A/B-move/C-move", "normal", 1, "A/B/C" },
+ { 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, "A/B-move/C-move" },
+ { 3, "A/B-move/C-move", "normal", 1, "A/B/C", MOVED_HERE },
{ 0 }
};
SVN_ERR(check_db_rows(&b, "", rows));
@@ -1745,14 +1584,14 @@ test_mixed_rev_copy(const svn_test_opts_t *opts, apr_pool_t *pool)
svn_test__sandbox_t b;
SVN_ERR(svn_test__sandbox_create(&b, "mixed_rev_copy", opts, pool));
- SVN_ERR(wc_mkdir(&b, "A"));
- SVN_ERR(wc_commit(&b, ""));
- SVN_ERR(wc_mkdir(&b, "A/B"));
- SVN_ERR(wc_commit(&b, ""));
- SVN_ERR(wc_mkdir(&b, "A/B/C"));
- SVN_ERR(wc_commit(&b, ""));
-
- SVN_ERR(wc_copy(&b, "A", "X"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ SVN_ERR(sbox_wc_copy(&b, "A", "X"));
{
nodes_row_t rows[] = {
{ 1, "X", "normal", 1, "A" },
@@ -1765,7 +1604,7 @@ test_mixed_rev_copy(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(check_db_rows(&b, "X", rows));
}
- SVN_ERR(wc_copy(&b, "A/B", "X/Y"));
+ SVN_ERR(sbox_wc_copy(&b, "A/B", "X/Y"));
{
nodes_row_t rows[] = {
{ 1, "X", "normal", 1, "A" },
@@ -1781,7 +1620,7 @@ test_mixed_rev_copy(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(check_db_rows(&b, "X", rows));
}
- SVN_ERR(wc_delete(&b, "X/B/C"));
+ SVN_ERR(sbox_wc_delete(&b, "X/B/C"));
{
nodes_row_t rows[] = {
{ 1, "X", "normal", 1, "A" },
@@ -1796,8 +1635,8 @@ test_mixed_rev_copy(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(check_db_rows(&b, "X", rows));
}
- SVN_ERR(wc_delete(&b, "X"));
- SVN_ERR(wc_update(&b, "A/B/C", 0));
+ SVN_ERR(sbox_wc_delete(&b, "X"));
+ SVN_ERR(sbox_wc_update(&b, "A/B/C", 0));
{
nodes_row_t rows[] = {
{ 0, "", "normal", 0, "" },
@@ -1809,7 +1648,7 @@ test_mixed_rev_copy(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(check_db_rows(&b, "", rows));
}
- SVN_ERR(wc_copy(&b, "A", "X"));
+ SVN_ERR(sbox_wc_copy(&b, "A", "X"));
{
nodes_row_t rows[] = {
{ 1, "X", "normal", 1, "A" },
@@ -1830,23 +1669,23 @@ test_delete_of_replace(const svn_test_opts_t *opts, apr_pool_t *pool)
svn_test__sandbox_t b;
SVN_ERR(svn_test__sandbox_create(&b, "delete_of_replace", opts, 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"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C/F"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C/F/K"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C/G"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C/G/K"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_copy(&b, "A", "X"));
+ SVN_ERR(sbox_wc_move(&b, "X/B/C/F", "X/B/C/H"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+
+ SVN_ERR(sbox_wc_delete(&b, "A/B"));
+ SVN_ERR(sbox_wc_copy(&b, "X/B", "A/B"));
{
nodes_row_t rows[] = {
{ 0, "A", "normal", 2, "A" },
@@ -1869,7 +1708,7 @@ test_delete_of_replace(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(check_db_rows(&b, "A", rows));
}
- SVN_ERR(wc_delete(&b, "A/B"));
+ SVN_ERR(sbox_wc_delete(&b, "A/B"));
{
nodes_row_t rows[] = {
{ 0, "A", "normal", 2, "A" },
@@ -1899,25 +1738,25 @@ test_del_replace_not_present(const svn_test_opts_t *opts, apr_pool_t *pool)
svn_test__sandbox_t b;
SVN_ERR(svn_test__sandbox_create(&b, "del_replace_not_present", opts, pool));
- SVN_ERR(wc_mkdir(&b, "A"));
- SVN_ERR(wc_mkdir(&b, "A/B"));
- SVN_ERR(wc_mkdir(&b, "A/B/X"));
- SVN_ERR(wc_mkdir(&b, "A/B/Y"));
- SVN_ERR(wc_mkdir(&b, "A/B/Z"));
- SVN_ERR(wc_commit(&b, ""));
-
- SVN_ERR(wc_copy(&b, "A", "X"));
- SVN_ERR(wc_mkdir(&b, "X/B/W"));
- SVN_ERR(wc_commit(&b, ""));
-
- SVN_ERR(wc_update(&b, "", 2));
- SVN_ERR(wc_update(&b, "A/B/X", 0));
- SVN_ERR(wc_update(&b, "A/B/Y", 0));
- SVN_ERR(wc_update(&b, "X/B/W", 0));
- SVN_ERR(wc_update(&b, "X/B/Y", 0));
- SVN_ERR(wc_update(&b, "X/B/Z", 0));
-
- SVN_ERR(wc_delete(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/X"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/Y"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/Z"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ SVN_ERR(sbox_wc_copy(&b, "A", "X"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X/B/W"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ SVN_ERR(sbox_wc_update(&b, "A/B/X", 0));
+ SVN_ERR(sbox_wc_update(&b, "A/B/Y", 0));
+ SVN_ERR(sbox_wc_update(&b, "X/B/W", 0));
+ SVN_ERR(sbox_wc_update(&b, "X/B/Y", 0));
+ SVN_ERR(sbox_wc_update(&b, "X/B/Z", 0));
+
+ SVN_ERR(sbox_wc_delete(&b, "A"));
{
nodes_row_t rows[] = {
{ 0, "A", "normal", 2, "A" },
@@ -1933,7 +1772,7 @@ test_del_replace_not_present(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(check_db_rows(&b, "A", rows));
}
- SVN_ERR(wc_copy(&b, "X", "A"));
+ SVN_ERR(sbox_wc_copy(&b, "X", "A"));
{
nodes_row_t rows[] = {
{ 0, "A", "normal", 2, "A" },
@@ -1952,7 +1791,7 @@ test_del_replace_not_present(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(check_db_rows(&b, "A", rows));
}
- SVN_ERR(wc_delete(&b, "A"));
+ SVN_ERR(sbox_wc_delete(&b, "A"));
{
nodes_row_t rows[] = {
{ 0, "A", "normal", 2, "A" },
@@ -2091,7 +1930,7 @@ revert(svn_test__sandbox_t *b,
actual_row_t *before_actual,
actual_row_t *after_actual)
{
- const char *local_abspath = wc_path(b, local_relpath);
+ const char *local_abspath = sbox_wc_path(b, local_relpath);
svn_error_t *err;
if (!before_actual)
@@ -2202,12 +2041,10 @@ test_op_revert(const svn_test_opts_t *opts, apr_pool_t *pool)
before, before, before_actual4, after_actual4));
err = revert(&b, "A/B", svn_depth_empty,
before, before, common_actual5, common_actual5);
- SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_WC_INVALID_OPERATION_DEPTH);
- svn_error_clear(err);
+ SVN_TEST_ASSERT_ERROR(err, SVN_ERR_WC_INVALID_OPERATION_DEPTH);
err = revert(&b, "A/B/C", svn_depth_empty,
before, before, common_actual6, common_actual6);
- SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_WC_INVALID_OPERATION_DEPTH);
- svn_error_clear(err);
+ SVN_TEST_ASSERT_ERROR(err, SVN_ERR_WC_INVALID_OPERATION_DEPTH);
}
{
@@ -2260,30 +2097,24 @@ test_op_revert(const svn_test_opts_t *opts, apr_pool_t *pool)
err = revert(&b, "A/B", svn_depth_empty,
common, common, NULL, NULL);
- SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_WC_INVALID_OPERATION_DEPTH);
- svn_error_clear(err);
+ SVN_TEST_ASSERT_ERROR(err, SVN_ERR_WC_INVALID_OPERATION_DEPTH);
err = revert(&b, "A/B", svn_depth_empty,
common, common, common_actual, common_actual);
- SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_WC_INVALID_OPERATION_DEPTH);
- svn_error_clear(err);
+ SVN_TEST_ASSERT_ERROR(err, SVN_ERR_WC_INVALID_OPERATION_DEPTH);
err = revert(&b, "P", svn_depth_empty,
common, common, NULL, NULL);
- SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_WC_INVALID_OPERATION_DEPTH);
- svn_error_clear(err);
+ SVN_TEST_ASSERT_ERROR(err, SVN_ERR_WC_INVALID_OPERATION_DEPTH);
err = revert(&b, "P", svn_depth_empty,
common, common, common_actual, common_actual);
- SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_WC_INVALID_OPERATION_DEPTH);
- svn_error_clear(err);
+ SVN_TEST_ASSERT_ERROR(err, SVN_ERR_WC_INVALID_OPERATION_DEPTH);
err = revert(&b, "X", svn_depth_empty,
common, common, NULL, NULL);
- SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_WC_INVALID_OPERATION_DEPTH);
- svn_error_clear(err);
+ SVN_TEST_ASSERT_ERROR(err, SVN_ERR_WC_INVALID_OPERATION_DEPTH);
err = revert(&b, "X", svn_depth_empty,
common, common, common_actual, common_actual);
- SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_WC_INVALID_OPERATION_DEPTH);
- svn_error_clear(err);
+ SVN_TEST_ASSERT_ERROR(err, SVN_ERR_WC_INVALID_OPERATION_DEPTH);
}
{
@@ -2484,8 +2315,7 @@ test_op_revert(const svn_test_opts_t *opts, apr_pool_t *pool)
};
err = revert(&b, "A", svn_depth_empty,
common, common, NULL, NULL);
- SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_WC_INVALID_OPERATION_DEPTH);
- svn_error_clear(err);
+ SVN_TEST_ASSERT_ERROR(err, SVN_ERR_WC_INVALID_OPERATION_DEPTH);
}
{
@@ -2751,27 +2581,27 @@ test_children_of_replaced_dir(const svn_test_opts_t *opts, apr_pool_t *pool)
A_abspath = svn_dirent_join(b.wc_abspath, "A", pool);
/* Set up the base state as revision 1. */
- SVN_ERR(wc_mkdir(&b, "A"));
- SVN_ERR(wc_mkdir(&b, "A/F"));
- SVN_ERR(wc_mkdir(&b, "A/G"));
- SVN_ERR(wc_mkdir(&b, "A/H"));
- SVN_ERR(wc_mkdir(&b, "A/L"));
- SVN_ERR(wc_mkdir(&b, "X"));
- SVN_ERR(wc_mkdir(&b, "X/G"));
- SVN_ERR(wc_mkdir(&b, "X/H"));
- SVN_ERR(wc_mkdir(&b, "X/I"));
- SVN_ERR(wc_mkdir(&b, "X/K"));
- SVN_ERR(wc_commit(&b, ""));
- SVN_ERR(wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/F"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/G"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/H"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/L"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X/G"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X/H"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X/I"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X/K"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
/* Replace A with a copy of X. */
- SVN_ERR(wc_delete(&b, "A"));
- SVN_ERR(wc_copy(&b, "X", "A"));
+ SVN_ERR(sbox_wc_delete(&b, "A"));
+ SVN_ERR(sbox_wc_copy(&b, "X", "A"));
/* Make other local mods. */
- SVN_ERR(wc_delete(&b, "A/G"));
- SVN_ERR(wc_mkdir(&b, "A/J"));
- SVN_ERR(wc_mkdir(&b, "A/L"));
+ SVN_ERR(sbox_wc_delete(&b, "A/G"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/J"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/L"));
/* Test several variants of "list the children of 'A'". */
@@ -2819,15 +2649,17 @@ do_delete(svn_test__sandbox_t *b,
actual_row_t *actual_before,
actual_row_t *actual_after)
{
- const char *local_abspath = wc_path(b, local_relpath);
+ const char *local_abspath = sbox_wc_path(b, local_relpath);
SVN_ERR(insert_dirs(b, before));
SVN_ERR(insert_actual(b, actual_before));
SVN_ERR(check_db_rows(b, "", before));
SVN_ERR(check_db_actual(b, actual_before));
- SVN_ERR(svn_wc__db_op_delete(b->wc_ctx->db, local_abspath,
- NULL, NULL /* notification */,
+ SVN_ERR(svn_wc__db_op_delete(b->wc_ctx->db, local_abspath, NULL,
+ TRUE /* delete_dir_externals */,
+ NULL /* conflict */, NULL /* work_item */,
NULL, NULL /* cancellation */,
+ NULL, NULL /* notification */,
b->pool));
SVN_ERR(check_db_rows(b, "", after));
SVN_ERR(check_db_actual(b, actual_after));
@@ -3069,13 +2901,13 @@ test_child_replace_with_same_origin(const svn_test_opts_t *opts,
SVN_ERR(svn_test__sandbox_create(&b, "child_replace_with_same", opts, pool));
/* Set up the base state as revision 1. */
- SVN_ERR(wc_mkdir(&b, "A"));
- SVN_ERR(wc_mkdir(&b, "A/B"));
- SVN_ERR(wc_mkdir(&b, "A/B/C"));
- SVN_ERR(wc_commit(&b, ""));
- SVN_ERR(wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
- SVN_ERR(wc_copy(&b, "A", "X"));
+ SVN_ERR(sbox_wc_copy(&b, "A", "X"));
{
nodes_row_t rows[] = {
@@ -3087,7 +2919,7 @@ test_child_replace_with_same_origin(const svn_test_opts_t *opts,
SVN_ERR(check_db_rows(&b, "X", rows));
}
- SVN_ERR(wc_delete(&b, "X/B"));
+ SVN_ERR(sbox_wc_delete(&b, "X/B"));
{
nodes_row_t rows[] = {
{1, "X", "normal", 1, "A"},
@@ -3102,7 +2934,7 @@ test_child_replace_with_same_origin(const svn_test_opts_t *opts,
SVN_ERR(check_db_rows(&b, "X", rows));
}
- SVN_ERR(wc_copy(&b, "A/B", "X/B"));
+ SVN_ERR(sbox_wc_copy(&b, "A/B", "X/B"));
{
/* The revisions match what was here, so for an optimal commit
this should have exactly the same behavior as reverting X/B.
@@ -3138,38 +2970,38 @@ test_shadowed_update(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(svn_test__sandbox_create(&b, "shadowed_update", opts, pool));
/* Set up the base state as revision 1. */
- file_write(&b, "iota", "This is iota");
- SVN_ERR(wc_add(&b, "iota"));
- SVN_ERR(wc_commit(&b, ""));
+ sbox_file_write(&b, "iota", "This is iota");
+ SVN_ERR(sbox_wc_add(&b, "iota"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
/* And create two trees in r2 */
- SVN_ERR(wc_mkdir(&b, "A"));
- SVN_ERR(wc_mkdir(&b, "A/B"));
- SVN_ERR(wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
- SVN_ERR(wc_mkdir(&b, "K"));
- SVN_ERR(wc_mkdir(&b, "K/L"));
- SVN_ERR(wc_mkdir(&b, "K/L/M"));
- SVN_ERR(wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "K"));
+ SVN_ERR(sbox_wc_mkdir(&b, "K/L"));
+ SVN_ERR(sbox_wc_mkdir(&b, "K/L/M"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
/* And change something in r3 */
- file_write(&b, "iota", "This is a new iota");
- SVN_ERR(wc_commit(&b, ""));
+ sbox_file_write(&b, "iota", "This is a new iota");
+ SVN_ERR(sbox_wc_commit(&b, ""));
/* And delete C & M */
- SVN_ERR(wc_delete(&b, "A/B/C"));
- SVN_ERR(wc_delete(&b, "K/L/M"));
- SVN_ERR(wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_delete(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_delete(&b, "K/L/M"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
/* And now create the shadowed situation */
- SVN_ERR(wc_update(&b, "", 2));
- SVN_ERR(wc_copy(&b, "A", "A_tmp"));
- SVN_ERR(wc_update(&b, "", 1));
- SVN_ERR(wc_move(&b, "A_tmp", "A"));
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ SVN_ERR(sbox_wc_copy(&b, "A", "A_tmp"));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_move(&b, "A_tmp", "A"));
- SVN_ERR(wc_mkdir(&b, "K"));
- SVN_ERR(wc_mkdir(&b, "K/L"));
- SVN_ERR(wc_mkdir(&b, "K/L/M"));
+ SVN_ERR(sbox_wc_mkdir(&b, "K"));
+ SVN_ERR(sbox_wc_mkdir(&b, "K/L"));
+ SVN_ERR(sbox_wc_mkdir(&b, "K/L/M"));
/* Verify situation before update */
{
@@ -3190,7 +3022,7 @@ test_shadowed_update(const svn_test_opts_t *opts, apr_pool_t *pool)
}
/* And now bring in A and K below the local information */
- SVN_ERR(wc_update(&b, "", 3));
+ SVN_ERR(sbox_wc_update(&b, "", 3));
{
nodes_row_t rows[] = {
@@ -3223,9 +3055,9 @@ test_shadowed_update(const svn_test_opts_t *opts, apr_pool_t *pool)
}
/* Update again to remove C and M */
- SVN_ERR(wc_resolved(&b, "A"));
- SVN_ERR(wc_resolved(&b, "K"));
- SVN_ERR(wc_update(&b, "", 4));
+ SVN_ERR(sbox_wc_resolved(&b, "A"));
+ SVN_ERR(sbox_wc_resolved(&b, "K"));
+ SVN_ERR(sbox_wc_update(&b, "", 4));
{
nodes_row_t rows[] = {
@@ -3255,11 +3087,11 @@ test_shadowed_update(const svn_test_opts_t *opts, apr_pool_t *pool)
}
/* Update again to bring C and M back */
- SVN_ERR(wc_resolved(&b, "A"));
- SVN_ERR(wc_resolved(&b, "K"));
- SVN_ERR(wc_update(&b, "", 3));
+ SVN_ERR(sbox_wc_resolved(&b, "A"));
+ SVN_ERR(sbox_wc_resolved(&b, "K"));
+ SVN_ERR(sbox_wc_update(&b, "", 3));
- SVN_ERR(wc_delete(&b, "K/L/M"));
+ SVN_ERR(sbox_wc_delete(&b, "K/L/M"));
{
nodes_row_t rows[] = {
{0, "", "normal", 3, ""},
@@ -3289,13 +3121,13 @@ test_shadowed_update(const svn_test_opts_t *opts, apr_pool_t *pool)
}
/* Resolve conflict on K and go back to r1 */
- SVN_ERR(wc_revert(&b, "K", svn_depth_infinity));
- SVN_ERR(wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_revert(&b, "K", svn_depth_infinity));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
- SVN_ERR(wc_mkdir(&b, "K"));
- SVN_ERR(wc_mkdir(&b, "K/L"));
+ SVN_ERR(sbox_wc_mkdir(&b, "K"));
+ SVN_ERR(sbox_wc_mkdir(&b, "K/L"));
- SVN_ERR(wc_update(&b, "", 3));
+ SVN_ERR(sbox_wc_update(&b, "", 3));
{
nodes_row_t rows[] = {
@@ -3316,10 +3148,10 @@ test_shadowed_update(const svn_test_opts_t *opts, apr_pool_t *pool)
}
/* 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));
+ SVN_ERR(sbox_wc_resolved(&b, "K"));
+ SVN_ERR(sbox_wc_update(&b, "K/L/M", 4));
+ SVN_ERR(sbox_wc_resolved(&b, "A"));
+ SVN_ERR(sbox_wc_update(&b, "A/B/C", 4));
{
nodes_row_t rows[] = {
@@ -3361,24 +3193,24 @@ test_copy_of_deleted(const svn_test_opts_t *opts, apr_pool_t *pool)
svn_test__sandbox_t b;
SVN_ERR(svn_test__sandbox_create(&b, "copy_of_deleted", opts, pool));
- SVN_ERR(add_and_commit_greek_tree(&b));
+ SVN_ERR(sbox_add_and_commit_greek_tree(&b));
- /* Recreate the test scenario from copy_tests.py copy_wc_url_with_absent */
+ /* Recreate the test scenario from copy_tests.py copy_wc_url_with_server_excluded */
/* Delete A/B */
- SVN_ERR(wc_delete(&b, "A/B"));
+ SVN_ERR(sbox_wc_delete(&b, "A/B"));
/* A/no not-present but in HEAD */
- SVN_ERR(wc_copy(&b, "A/mu", "A/no"));
- SVN_ERR(wc_commit(&b, "A/no"));
- SVN_ERR(wc_update(&b, "A/no", 1));
+ SVN_ERR(sbox_wc_copy(&b, "A/mu", "A/no"));
+ SVN_ERR(sbox_wc_commit(&b, "A/no"));
+ SVN_ERR(sbox_wc_update(&b, "A/no", 1));
/* A/mu not-present and not in HEAD */
- SVN_ERR(wc_delete(&b, "A/mu"));
- SVN_ERR(wc_commit(&b, "A/mu"));
+ SVN_ERR(sbox_wc_delete(&b, "A/mu"));
+ SVN_ERR(sbox_wc_commit(&b, "A/mu"));
/* A/D excluded */
- SVN_ERR(wc_exclude(&b, "A/D"));
+ SVN_ERR(sbox_wc_exclude(&b, "A/D"));
/* This should have created this structure */
{
@@ -3408,7 +3240,7 @@ test_copy_of_deleted(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(check_db_rows(&b, "A", rows));
}
- SVN_ERR(wc_copy(&b, "A", "A_copied"));
+ SVN_ERR(sbox_wc_copy(&b, "A", "A_copied"));
/* I would expect this behavior, as this copies all layers where possible
instead of just constructing a top level layer with not-present nodes
@@ -3451,12 +3283,12 @@ test_case_rename(const svn_test_opts_t *opts, apr_pool_t *pool)
apr_hash_t *dirents;
SVN_ERR(svn_test__sandbox_create(&b, "case_rename", opts, pool));
- SVN_ERR(add_and_commit_greek_tree(&b));
+ SVN_ERR(sbox_add_and_commit_greek_tree(&b));
- SVN_ERR(wc_move(&b, "A", "a"));
- SVN_ERR(wc_move(&b, "iota", "iotA"));
+ SVN_ERR(sbox_wc_move(&b, "A", "a"));
+ SVN_ERR(sbox_wc_move(&b, "iota", "iotA"));
- SVN_ERR(svn_io_get_dirents3(&dirents, wc_path(&b, ""), TRUE, pool, pool));
+ SVN_ERR(svn_io_get_dirents3(&dirents, sbox_wc_path(&b, ""), TRUE, pool, pool));
/* A shouldn't be there, but a should */
SVN_TEST_ASSERT(apr_hash_get(dirents, "a", APR_HASH_KEY_STRING));
@@ -3474,14 +3306,14 @@ commit_file_external(const svn_test_opts_t *opts, apr_pool_t *pool)
svn_test__sandbox_t b;
SVN_ERR(svn_test__sandbox_create(&b, "commit_file_external", opts, pool));
- file_write(&b, "f", "this is f\n");
- SVN_ERR(wc_add(&b, "f"));
- SVN_ERR(wc_propset(&b, "svn:externals", "^/f g", ""));
- SVN_ERR(wc_commit(&b, ""));
- SVN_ERR(wc_update(&b, "", 1));
- file_write(&b, "g", "this is f\nmodified via g\n");
- SVN_ERR(wc_commit(&b, ""));
- SVN_ERR(wc_update(&b, "", 2));
+ sbox_file_write(&b, "f", "this is f\n");
+ SVN_ERR(sbox_wc_add(&b, "f"));
+ SVN_ERR(sbox_wc_propset(&b, "svn:externals", "^/f g", ""));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ sbox_file_write(&b, "g", "this is f\nmodified via g\n");
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 2));
{
nodes_row_t rows[] = {
@@ -3496,6 +3328,196 @@ commit_file_external(const svn_test_opts_t *opts, apr_pool_t *pool)
return SVN_NO_ERROR;
}
+static svn_error_t *
+revert_file_externals(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "revert_file_externals", opts, pool));
+ sbox_file_write(&b, "f", "this is f\n");
+ SVN_ERR(sbox_wc_add(&b, "f"));
+ SVN_ERR(sbox_wc_propset(&b, "svn:externals", "^/f g", ""));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_propset(&b, "svn:externals", "^/f h", ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_propset(&b, "svn:externals", "^/f g", "A"));
+ {
+ nodes_row_t rows[] = {
+ { 0, "", "normal", 1, "" },
+ { 0, "f", "normal", 1, "f" },
+ { 0, "g", "normal", 1, "f", TRUE },
+ { 1, "A", "normal", NO_COPY_FROM },
+ { 0 }
+ };
+ SVN_ERR(check_db_rows(&b, "", rows));
+ }
+
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ {
+ nodes_row_t rows[] = {
+ { 0, "", "normal", 1, "" },
+ { 0, "f", "normal", 1, "f" },
+ { 1, "A", "normal", NO_COPY_FROM },
+ { 0, "h", "normal", 1, "f", TRUE },
+ { 0, "A/g", "normal", 1, "f", TRUE },
+ { 0 }
+ };
+ SVN_ERR(check_db_rows(&b, "", rows));
+ }
+
+ SVN_ERR(sbox_wc_revert(&b, "", svn_depth_infinity));
+ {
+ nodes_row_t rows[] = {
+ { 0, "", "normal", 1, "" },
+ { 0, "f", "normal", 1, "f" },
+ { 0, "h", "normal", 1, "f", TRUE },
+ { 0, "A/g", "normal", 1, "f", TRUE },
+ { 0 }
+ };
+ SVN_ERR(check_db_rows(&b, "", rows));
+ }
+
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ {
+ nodes_row_t rows[] = {
+ { 0, "", "normal", 1, "" },
+ { 0, "f", "normal", 1, "f" },
+ { 0, "g", "normal", 1, "f", TRUE },
+ { 0 }
+ };
+ SVN_ERR(check_db_rows(&b, "", rows));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_file_externals(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "copy_file_externals", opts, pool));
+ sbox_file_write(&b, "f", "this is f\n");
+ SVN_ERR(sbox_wc_add(&b, "f"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_propset(&b, "svn:externals", "^/f g", "A"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_propset(&b, "svn:externals", "^/f g", "A/B"));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ {
+ nodes_row_t rows[] = {
+ { 0, "", "normal", 1, "" },
+ { 0, "f", "normal", 1, "f" },
+ { 0, "A", "normal", 1, "A" },
+ { 2, "A/B", "normal", NO_COPY_FROM },
+ { 0, "A/g", "normal", 1, "f", TRUE },
+ { 0, "A/B/g", "normal", 1, "f", TRUE },
+ { 0 }
+ };
+ SVN_ERR(check_db_rows(&b, "", rows));
+ }
+
+ SVN_ERR(sbox_wc_copy(&b, "A", "X"));
+ {
+ nodes_row_t rows[] = {
+ { 0, "", "normal", 1, "" },
+ { 0, "f", "normal", 1, "f" },
+ { 0, "A", "normal", 1, "A" },
+ { 2, "A/B", "normal", NO_COPY_FROM },
+ { 0, "A/g", "normal", 1, "f", TRUE },
+ { 0, "A/B/g", "normal", 1, "f", TRUE },
+ { 1, "X", "normal", 1, "A" },
+ { 2, "X/B", "normal", NO_COPY_FROM },
+ { 0 }
+ };
+ SVN_ERR(check_db_rows(&b, "", rows));
+ }
+
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ {
+ nodes_row_t rows[] = {
+ { 0, "", "normal", 1, "" },
+ { 0, "f", "normal", 1, "f" },
+ { 0, "A", "normal", 1, "A" },
+ { 2, "A/B", "normal", NO_COPY_FROM },
+ { 0, "A/g", "normal", 1, "f", TRUE },
+ { 0, "A/B/g", "normal", 1, "f", TRUE },
+ { 1, "X", "normal", 1, "A" },
+ { 2, "X/B", "normal", NO_COPY_FROM },
+ { 0, "X/g", "normal", 1, "f", TRUE },
+ { 0, "X/B/g", "normal", 1, "f", TRUE },
+ { 0 }
+ };
+ SVN_ERR(check_db_rows(&b, "", rows));
+ }
+
+ SVN_ERR(sbox_wc_delete(&b, "X"));
+ {
+ nodes_row_t rows[] = {
+ { 0, "", "normal", 1, "" },
+ { 0, "f", "normal", 1, "f" },
+ { 0, "A", "normal", 1, "A" },
+ { 2, "A/B", "normal", NO_COPY_FROM },
+ { 0, "A/g", "normal", 1, "f", TRUE },
+ { 0, "A/B/g", "normal", 1, "f", TRUE },
+ { 0 }
+ };
+ SVN_ERR(check_db_rows(&b, "", rows));
+ }
+
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ {
+ nodes_row_t rows[] = {
+ { 0, "", "normal", 1, "" },
+ { 0, "f", "normal", 1, "f" },
+ { 0, "A", "normal", 1, "A" },
+ { 2, "A/B", "normal", NO_COPY_FROM },
+ { 0, "A/g", "normal", 1, "f", TRUE },
+ { 0, "A/B/g", "normal", 1, "f", TRUE },
+ { 0 }
+ };
+ SVN_ERR(check_db_rows(&b, "", rows));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_wc_wc_server_excluded(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+ nodes_row_t before[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/E", "server-excluded", 1, "A/B/E"},
+ {0}
+ };
+ nodes_row_t after[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/E", "server-excluded", 1, "A/B/E"},
+ {1, "X", "normal", 1, "A"},
+ {1, "X/B", "normal", 1, "A/B"},
+ {1, "X/B/E", "incomplete", 1, "A/B/E"},
+ {0}
+ };
+ svn_error_t *err;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "copy_wc_wc_server_excluded", opts, pool));
+ SVN_ERR(insert_dirs(&b, before));
+ SVN_ERR(check_db_rows(&b, "", before));
+ SVN_ERR(sbox_disk_mkdir(&b, "A"));
+ err = sbox_wc_copy(&b, "A", "X");
+ SVN_TEST_ASSERT_ERROR(err, SVN_ERR_WC_PATH_UNEXPECTED_STATUS);
+ SVN_ERR(check_db_rows(&b, "", after));
+
+ return SVN_NO_ERROR;
+}
+
/* Issue 4040 */
static svn_error_t *
incomplete_switch(const svn_test_opts_t *opts, apr_pool_t *pool)
@@ -3504,17 +3526,17 @@ incomplete_switch(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(svn_test__sandbox_create(&b, "incomplete_switch", opts, 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/D"));
- SVN_ERR(wc_commit(&b, ""));
- SVN_ERR(wc_copy(&b, "A", "X"));
- SVN_ERR(wc_commit(&b, ""));
- SVN_ERR(wc_copy(&b, "A", "X/A"));
- SVN_ERR(wc_commit(&b, ""));
- SVN_ERR(wc_delete(&b, "X/A"));
- SVN_ERR(wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C/D"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_copy(&b, "A", "X"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_copy(&b, "A", "X/A"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_delete(&b, "X/A"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
{
/* Interrupted switch from A@1 to X@3 */
@@ -3529,7 +3551,7 @@ incomplete_switch(const svn_test_opts_t *opts, apr_pool_t *pool)
{0}
};
- nodes_row_t after_update[] = {
+ nodes_row_t after_update[] = {
{0, "", "normal", 4, "X"},
{0, "B", "normal", 4, "A/B"},
{0, "B/C", "normal", 4, "A/B/C"},
@@ -3539,13 +3561,5466 @@ incomplete_switch(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(insert_dirs(&b, before));
SVN_ERR(check_db_rows(&b, "", before));
- SVN_ERR(wc_update(&b, "", 4));
+ SVN_ERR(sbox_wc_update(&b, "", 4));
SVN_ERR(check_db_rows(&b, "", after_update));
}
return SVN_NO_ERROR;
}
+static svn_error_t *
+nested_moves_child_first(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "nested_moves_child_first", opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+ SVN_ERR(sbox_wc_move(&b, "A/B/C", "A/B/C2"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {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}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+ SVN_ERR(sbox_wc_move(&b, "A/B", "A/B2"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {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, "A/B2/C2"},
+ {3, "A/B2/C2", "normal", 1, "A/B/C", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+ SVN_ERR(sbox_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, "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, "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, "A2/B2/C2"},
+ {3, "A2/B2/C2","normal", 1, "A/B/C", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Revert should leave the A to A2 move */
+ SVN_ERR(sbox_wc_revert(&b, "A2/B2", svn_depth_infinity));
+ SVN_ERR(sbox_wc_revert(&b, "A2/B", svn_depth_infinity));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {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},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+nested_moves_child_last(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "nested_moves_child_last", opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+ SVN_ERR(sbox_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, "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},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+ SVN_ERR(sbox_wc_move(&b, "A2/B", "A2/B2"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {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, "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},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+ SVN_ERR(sbox_wc_move(&b, "A2/B2/C", "A2/B2/C2"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {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, "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, "A2/B2/C2"},
+ {3, "A2/B2/C2","normal", 1, "A/B/C", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Revert should leave the A to A2 move */
+ SVN_ERR(sbox_wc_revert(&b, "A2/B2", svn_depth_infinity));
+ SVN_ERR(sbox_wc_revert(&b, "A2/B", svn_depth_infinity));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {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},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_in_copy(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_in_copy", opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_copy(&b, "A", "A2"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {1, "A2", "normal", 1, "A"},
+ {1, "A2/B", "normal", 1, "A/B"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+ SVN_ERR(sbox_wc_move(&b, "A2/B", "A2/B2"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {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, "A2/B2"},
+ {2, "A2/B2", "normal", 1, "A/B", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_in_replace(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_in_replace", opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X/B"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_delete(&b, "A"));
+ SVN_ERR(sbox_wc_copy(&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/B", "normal", 1, "X/B"},
+ {1, "A", "normal", 1, "X"},
+ {1, "A/B", "normal", 1, "X/B"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+ SVN_ERR(sbox_wc_move(&b, "A/B", "A/B2"));
+ {
+ 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/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, "A/B2"},
+ {2, "A/B2", "normal", 1, "X/B", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_a_move(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "copy_a_move", opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+ SVN_ERR(sbox_wc_move(&b, "A/B/C", "A/C2"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {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, "A/C2"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+ /* Copying a move doesn't copy any moved-to/here artifacts, which
+ means that moving inside a copy is not the same as copying
+ something that contains a move? Is this behaviour correct? */
+ SVN_ERR(sbox_wc_copy(&b, "A", "A2"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {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, "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"}, /* MOVED_HERE? */
+ {3, "A2/B/C", "base-deleted", NO_COPY_FROM}, /* "A2/C2"? */
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_to_swap(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_to_swap", opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X/Y"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_move(&b, "A/B", "X/B"));
+ SVN_ERR(sbox_wc_move(&b, "X/Y", "A/Y"));
+
+ {
+ 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"},
+ {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, "A/Y"},
+ {2, "X/B", "normal", 1, "A/B", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_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(sbox_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(sbox_wc_move(&b, "A2", "X"));
+
+ {
+ 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, "X", TRUE},
+ {1, "A/Y", "normal", 1, "X/Y", MOVED_HERE},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {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, "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}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Revert and try in different order */
+ SVN_ERR(sbox_wc_revert(&b, "", svn_depth_infinity));
+
+ SVN_ERR(sbox_wc_move(&b, "A", "A2"));
+ SVN_ERR(sbox_wc_move(&b, "X", "A"));
+ SVN_ERR(sbox_wc_move(&b, "A2", "X"));
+
+ {
+ 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, "X", TRUE},
+ {1, "A/Y", "normal", 1, "X/Y", MOVED_HERE},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {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}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_move(&b, "A/Y", "X/Y"));
+ SVN_ERR(sbox_wc_move(&b, "X/B", "A/B"));
+
+ {
+ 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, "X", TRUE},
+ {1, "A/Y", "normal", 1, "X/Y", MOVED_HERE},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {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, "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}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* And move this last bit back and check if the db state is restored */
+ SVN_ERR(sbox_wc_move(&b, "A/B", "X/B"));
+ 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"},
+ {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", FALSE, "A", TRUE},
+ {1, "X/B", "normal", 1, "A/B", MOVED_HERE},
+ {1, "X/Y", "base-deleted", NO_COPY_FROM},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* And try to undo the rest */
+ SVN_ERR(sbox_wc_move(&b, "A", "A2"));
+ SVN_ERR(sbox_wc_move(&b, "X", "A"));
+ SVN_ERR(sbox_wc_move(&b, "A2", "X"));
+
+ {
+ 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"},
+
+ {0}
+ };
+
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+revert_nested_move(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+ nodes_row_t nodes_A_moved[] = {
+ {0, "", "normal", 1, ""},
+ {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},
+ {0}
+ };
+ nodes_row_t nodes_AB_moved[] = {
+ {0, "", "normal", 1, ""},
+ {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, "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},
+ {0}
+ };
+ nodes_row_t nodes_ABC_moved[] = {
+ {0, "", "normal", 1, ""},
+ {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, "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, "A2/B2/C2"},
+ {3, "A2/B2/C2", "normal", 1, "A/B/C", MOVED_HERE},
+ {0}
+ };
+ nodes_row_t nodes_AB_moved_C_copied[] = {
+ {0, "", "normal", 1, ""},
+ {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, "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/C2", "normal", 1, "A/B/C"},
+ {0}
+ };
+ nodes_row_t nodes_AC_moved_B_copied[] = {
+ {0, "", "normal", 1, ""},
+ {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/B2", "normal", 1, "A/B"},
+ {2, "A2/B2/C", "normal", 1, "A/B/C"},
+ {3, "A2/B2/C", "base-deleted", NO_COPY_FROM, "A2/B2/C2"},
+ {3, "A2/B2/C2", "normal", 1, "A/B/C", MOVED_HERE},
+ {0}
+ };
+
+ SVN_ERR(svn_test__sandbox_create(&b, "revert_nested_move", opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_move(&b, "A", "A2"));
+ SVN_ERR(check_db_rows(&b, "", nodes_A_moved));
+
+ SVN_ERR(sbox_wc_move(&b, "A2/B", "A2/B2"));
+ SVN_ERR(check_db_rows(&b, "", nodes_AB_moved));
+
+ SVN_ERR(sbox_wc_move(&b, "A2/B2/C", "A2/B2/C2"));
+ SVN_ERR(check_db_rows(&b, "", nodes_ABC_moved));
+
+ SVN_ERR(sbox_wc_revert(&b, "A2/B", svn_depth_infinity));
+ SVN_ERR(sbox_wc_revert(&b, "A2/B2", svn_depth_infinity));
+ SVN_ERR(check_db_rows(&b, "", nodes_A_moved));
+
+ SVN_ERR(sbox_wc_move(&b, "A2/B", "A2/B2"));
+ SVN_ERR(sbox_wc_move(&b, "A2/B2/C", "A2/B2/C2"));
+ SVN_ERR(check_db_rows(&b, "", nodes_ABC_moved));
+
+ SVN_ERR(sbox_wc_revert(&b, "A2/B2/C", svn_depth_empty));
+ SVN_ERR(check_db_rows(&b, "", nodes_AB_moved_C_copied));
+ SVN_ERR(sbox_wc_revert(&b, "A2/B2/C2", svn_depth_infinity));
+ SVN_ERR(check_db_rows(&b, "", nodes_AB_moved));
+
+ SVN_ERR(sbox_wc_move(&b, "A2/B2/C", "A2/B2/C2"));
+ SVN_ERR(check_db_rows(&b, "", nodes_ABC_moved));
+
+ SVN_ERR(sbox_wc_revert(&b, "A2/B2/C", svn_depth_infinity));
+ SVN_ERR(check_db_rows(&b, "", nodes_AB_moved_C_copied));
+ SVN_ERR(sbox_wc_revert(&b, "A2/B2/C2", svn_depth_infinity));
+ SVN_ERR(check_db_rows(&b, "", nodes_AB_moved));
+
+ SVN_ERR(sbox_wc_revert(&b, "A2/B", svn_depth_infinity));
+ SVN_ERR(sbox_wc_revert(&b, "A2/B2", svn_depth_infinity));
+ SVN_ERR(check_db_rows(&b, "", nodes_A_moved));
+
+ /* Check moves in reverse order */
+ SVN_ERR(sbox_wc_revert(&b, "", svn_depth_infinity));
+ SVN_ERR(sbox_wc_move(&b, "A/B/C", "A/B/C2"));
+ SVN_ERR(sbox_wc_move(&b, "A/B", "A/B2"));
+ SVN_ERR(sbox_wc_move(&b, "A", "A2"));
+ SVN_ERR(check_db_rows(&b, "", nodes_ABC_moved));
+
+ SVN_ERR(sbox_wc_revert(&b, "A2/B", svn_depth_infinity));
+ SVN_ERR(check_db_rows(&b, "", nodes_AC_moved_B_copied));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_on_move(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_on_move", opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X/B"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_move(&b, "A/B", "B2"));
+ SVN_ERR(sbox_wc_delete(&b, "A"));
+ SVN_ERR(sbox_wc_copy(&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/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", FALSE, "B2"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_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"},
+ {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", FALSE, "B2"},
+ {2, "A/B", "base-deleted", NO_COPY_FROM, "B3"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_on_move2(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_on_move2", opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X/B"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_move(&b, "A", "A2"));
+ SVN_ERR(sbox_wc_delete(&b, "A"));
+ SVN_ERR(sbox_wc_copy(&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/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", FALSE, "A2"},
+ {1, "A/B", "normal", 1, "X/B"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_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"},
+ {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", 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));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_added(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_added", opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_move(&b, "A", "A2"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A2/B/C2"));
+
+ /* Both A2/B/C and A2/B/C2 are simple adds inside the move. It
+ doesn't seem right for A2/B/C to be marked moved_here. */
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {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},
+ {3, "A2/B/C", "normal", NO_COPY_FROM},
+ {3, "A2/B/C2", "normal", NO_COPY_FROM},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* Test the result of 'update' when the incoming changes are inside a
+ * directory that is locally moved. */
+static svn_error_t *
+move_update(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_update", opts, pool));
+
+ /* r1: Create files 'f', 'h' */
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ sbox_file_write(&b, "A/B/f", "r1 content\n");
+ sbox_file_write(&b, "A/B/h", "r1 content\n");
+ SVN_ERR(sbox_wc_add(&b, "A/B/f"));
+ SVN_ERR(sbox_wc_add(&b, "A/B/h"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ /* r2: Modify 'f' */
+ sbox_file_write(&b, "A/B/f", "r1 content\nr2 content\n");
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ /* r3: Delete 'h', add 'g' */
+ sbox_file_write(&b, "A/B/g", "r3 content\n");
+ SVN_ERR(sbox_wc_add(&b, "A/B/g"));
+ SVN_ERR(sbox_wc_delete(&b, "A/B/h"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ /* r4: Add a new subtree 'X' */
+ SVN_ERR(sbox_wc_mkdir(&b, "X"));
+ sbox_file_write(&b, "X/f", "r4 content\n");
+ sbox_file_write(&b, "X/g", "r4 content\n");
+ sbox_file_write(&b, "X/h", "r4 content\n");
+ SVN_ERR(sbox_wc_add(&b, "X/f"));
+ SVN_ERR(sbox_wc_add(&b, "X/g"));
+ SVN_ERR(sbox_wc_add(&b, "X/h"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ /* r5: Add a subtree 'A/B/C' */
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ /* A is single-revision so A2 is a single-revision copy */
+ SVN_ERR(sbox_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, "A/B/f", "normal", 1, "A/B/f"},
+ {0, "A/B/h", "normal", 1, "A/B/h"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/f", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/h", "base-deleted", NO_COPY_FROM},
+ {1, "A2", "normal", 1, "A", MOVED_HERE},
+ {1, "A2/B", "normal", 1, "A/B", MOVED_HERE},
+ {1, "A2/B/f", "normal", 1, "A/B/f", MOVED_HERE},
+ {1, "A2/B/h", "normal", 1, "A/B/h", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Update causes a tree-conflict on A due to incoming text-change. */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 2, ""},
+ {0, "A", "normal", 2, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "A/B/f", "normal", 2, "A/B/f"},
+ {0, "A/B/h", "normal", 2, "A/B/h"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/f", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/h", "base-deleted", NO_COPY_FROM},
+ {1, "A2", "normal", 1, "A", MOVED_HERE},
+ {1, "A2/B", "normal", 1, "A/B", MOVED_HERE},
+ {1, "A2/B/f", "normal", 1, "A/B/f", MOVED_HERE},
+ {1, "A2/B/h", "normal", 1, "A/B/h", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Resolve should update the move. */
+ SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 2, ""},
+ {0, "A", "normal", 2, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "A/B/f", "normal", 2, "A/B/f"},
+ {0, "A/B/h", "normal", 2, "A/B/h"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/f", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/h", "base-deleted", NO_COPY_FROM},
+ {1, "A2", "normal", 2, "A", MOVED_HERE},
+ {1, "A2/B", "normal", 2, "A/B", MOVED_HERE},
+ {1, "A2/B/f", "normal", 2, "A/B/f", MOVED_HERE},
+ {1, "A2/B/h", "normal", 2, "A/B/h", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Update causes a tree-conflict on due to incoming add. */
+ SVN_ERR(sbox_wc_update(&b, "", 3));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 3, ""},
+ {0, "A", "normal", 3, "A"},
+ {0, "A/B", "normal", 3, "A/B"},
+ {0, "A/B/f", "normal", 3, "A/B/f"},
+ {0, "A/B/g", "normal", 3, "A/B/g"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/f", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/g", "base-deleted", NO_COPY_FROM},
+ {1, "A2", "normal", 2, "A", MOVED_HERE},
+ {1, "A2/B", "normal", 2, "A/B", MOVED_HERE},
+ {1, "A2/B/f", "normal", 2, "A/B/f", MOVED_HERE},
+ {1, "A2/B/h", "normal", 2, "A/B/h", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 3, ""},
+ {0, "A", "normal", 3, "A"},
+ {0, "A/B", "normal", 3, "A/B"},
+ {0, "A/B/f", "normal", 3, "A/B/f"},
+ {0, "A/B/g", "normal", 3, "A/B/g"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/f", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/g", "base-deleted", NO_COPY_FROM},
+ {1, "A2", "normal", 3, "A", MOVED_HERE},
+ {1, "A2/B", "normal", 3, "A/B", MOVED_HERE},
+ {1, "A2/B/f", "normal", 3, "A/B/f", MOVED_HERE},
+ {1, "A2/B/g", "normal", 3, "A/B/g", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_delete(&b, "A2/B"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 3, ""},
+ {0, "A", "normal", 3, "A"},
+ {0, "A/B", "normal", 3, "A/B"},
+ {0, "A/B/f", "normal", 3, "A/B/f"},
+ {0, "A/B/g", "normal", 3, "A/B/g"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/f", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/g", "base-deleted", NO_COPY_FROM},
+ {1, "A2", "normal", 3, "A", MOVED_HERE},
+ {1, "A2/B", "normal", 3, "A/B", MOVED_HERE},
+ {1, "A2/B/f", "normal", 3, "A/B/f", MOVED_HERE},
+ {1, "A2/B/g", "normal", 3, "A/B/g", MOVED_HERE},
+ {2, "A2/B", "base-deleted", NO_COPY_FROM},
+ {2, "A2/B/f", "base-deleted", NO_COPY_FROM},
+ {2, "A2/B/g", "base-deleted", NO_COPY_FROM},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 2, ""},
+ {0, "A", "normal", 2, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "A/B/f", "normal", 2, "A/B/f"},
+ {0, "A/B/h", "normal", 2, "A/B/h"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/f", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/h", "base-deleted", NO_COPY_FROM},
+ {1, "A2", "normal", 2, "A", MOVED_HERE},
+ {1, "A2/B", "normal", 2, "A/B", MOVED_HERE},
+ {1, "A2/B/f", "normal", 2, "A/B/f", MOVED_HERE},
+ {1, "A2/B/h", "normal", 2, "A/B/h", MOVED_HERE},
+ {2, "A2/B", "base-deleted", NO_COPY_FROM},
+ {2, "A2/B/f", "base-deleted", NO_COPY_FROM},
+ {2, "A2/B/h", "base-deleted", NO_COPY_FROM},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_update(&b, "X", 4));
+ SVN_ERR(sbox_wc_copy(&b, "X", "A2/B"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 2, ""},
+ {0, "A", "normal", 2, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "A/B/f", "normal", 2, "A/B/f"},
+ {0, "A/B/h", "normal", 2, "A/B/h"},
+ {0, "X", "normal", 4, "X"},
+ {0, "X/f", "normal", 4, "X/f"},
+ {0, "X/g", "normal", 4, "X/g"},
+ {0, "X/h", "normal", 4, "X/h"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/f", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/h", "base-deleted", NO_COPY_FROM},
+ {1, "A2", "normal", 2, "A", MOVED_HERE},
+ {1, "A2/B", "normal", 2, "A/B", MOVED_HERE},
+ {1, "A2/B/f", "normal", 2, "A/B/f", MOVED_HERE},
+ {1, "A2/B/h", "normal", 2, "A/B/h", MOVED_HERE},
+ {2, "A2/B", "normal", 4, "X"},
+ {2, "A2/B/f", "normal", 4, "X/f"},
+ {2, "A2/B/g", "normal", 4, "X/g"},
+ {2, "A2/B/h", "normal", 4, "X/h"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_update(&b, "", 4));
+ SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 4, ""},
+ {0, "A", "normal", 4, "A"},
+ {0, "A/B", "normal", 4, "A/B"},
+ {0, "A/B/f", "normal", 4, "A/B/f"},
+ {0, "A/B/g", "normal", 4, "A/B/g"},
+ {0, "X", "normal", 4, "X"},
+ {0, "X/f", "normal", 4, "X/f"},
+ {0, "X/g", "normal", 4, "X/g"},
+ {0, "X/h", "normal", 4, "X/h"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/f", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/g", "base-deleted", NO_COPY_FROM},
+ {1, "A2", "normal", 4, "A", MOVED_HERE},
+ {1, "A2/B", "normal", 4, "A/B", MOVED_HERE},
+ {1, "A2/B/f", "normal", 4, "A/B/f", MOVED_HERE},
+ {1, "A2/B/g", "normal", 4, "A/B/g", MOVED_HERE},
+ {2, "A2/B", "normal", 4, "X"},
+ {2, "A2/B/f", "normal", 4, "X/f"},
+ {2, "A2/B/g", "normal", 4, "X/g"},
+ {2, "A2/B/h", "normal", 4, "X/h"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_update(&b, "", 5));
+ SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 5, ""},
+ {0, "A", "normal", 5, "A"},
+ {0, "A/B", "normal", 5, "A/B"},
+ {0, "A/B/f", "normal", 5, "A/B/f"},
+ {0, "A/B/g", "normal", 5, "A/B/g"},
+ {0, "A/B/C", "normal", 5, "A/B/C"},
+ {0, "X", "normal", 5, "X"},
+ {0, "X/f", "normal", 5, "X/f"},
+ {0, "X/g", "normal", 5, "X/g"},
+ {0, "X/h", "normal", 5, "X/h"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/f", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/g", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {1, "A2", "normal", 5, "A", MOVED_HERE},
+ {1, "A2/B", "normal", 5, "A/B", MOVED_HERE},
+ {1, "A2/B/f", "normal", 5, "A/B/f", MOVED_HERE},
+ {1, "A2/B/g", "normal", 5, "A/B/g", MOVED_HERE},
+ {1, "A2/B/C", "normal", 5, "A/B/C", MOVED_HERE},
+ {2, "A2/B", "normal", 4, "X"},
+ {2, "A2/B/f", "normal", 4, "X/f"},
+ {2, "A2/B/g", "normal", 4, "X/g"},
+ {2, "A2/B/h", "normal", 4, "X/h"},
+ {2, "A2/B/C", "base-deleted", NO_COPY_FROM},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+check_moved_to(apr_array_header_t *moved_tos,
+ int i,
+ int op_depth,
+ const char *local_relpath)
+{
+ struct svn_wc__db_moved_to_t *moved_to;
+
+ if (i >= moved_tos->nelts)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "moved-to %d not found", i);
+
+ moved_to = APR_ARRAY_IDX(moved_tos, i, struct svn_wc__db_moved_to_t *);
+
+ if (moved_to->op_depth != op_depth
+ || strcmp(moved_to->local_relpath, local_relpath))
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "expected: {%d '%s'} found[%d]: {%d '%s'}",
+ op_depth, local_relpath, i,
+ moved_to->op_depth, moved_to->local_relpath);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_scan_delete(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+ const char *moved_to_abspath, *moved_to_op_root_abspath;
+ apr_array_header_t *moved_tos;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "scan_delete", opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A2"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A2/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "C2"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_move(&b, "A2", "X"));
+ SVN_ERR(sbox_wc_move(&b, "X/B", "Z"));
+ SVN_ERR(sbox_wc_move(&b, "A/B", "X/B"));
+ SVN_ERR(sbox_wc_move(&b, "X/B/C", "Y"));
+ SVN_ERR(sbox_wc_move(&b, "C2", "X/B/C"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
+ {0, "A2", "normal", 1, "A2"},
+ {0, "A2/B", "normal", 1, "A2/B"},
+ {0, "C2", "normal", 1, "C2"},
+ {1, "A2", "base-deleted", NO_COPY_FROM, "X"},
+ {1, "A2/B", "base-deleted", NO_COPY_FROM},
+ {1, "Z", "normal", 1, "A2/B", MOVED_HERE},
+ {1, "X", "normal", 1, "A2", MOVED_HERE},
+ {1, "X/B", "normal", 1, "A2/B", MOVED_HERE},
+ {2, "A/B", "base-deleted", NO_COPY_FROM, "X/B"},
+ {2, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {2, "X/B", "normal", 1, "A/B", FALSE, "Z", TRUE},
+ {2, "X/B/C", "normal", 1, "A/B/C", MOVED_HERE},
+ {1, "Y", "normal", 1, "A/B/C", MOVED_HERE},
+ {1, "C2", "base-deleted", NO_COPY_FROM, "X/B/C"},
+ {3, "X/B/C", "normal", 1, "C2", FALSE, "Y", TRUE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(svn_wc__db_scan_deletion(NULL, &moved_to_abspath,
+ NULL, &moved_to_op_root_abspath,
+ b.wc_ctx->db, sbox_wc_path(&b, "C2"),
+ pool, pool));
+ SVN_TEST_STRING_ASSERT(moved_to_abspath, sbox_wc_path(&b, "X/B/C"));
+ SVN_TEST_STRING_ASSERT(moved_to_op_root_abspath, sbox_wc_path(&b, "X/B/C"));
+
+ SVN_ERR(svn_wc__db_scan_deletion(NULL, &moved_to_abspath,
+ NULL, &moved_to_op_root_abspath,
+ b.wc_ctx->db, sbox_wc_path(&b, "A/B"),
+ pool, pool));
+ SVN_TEST_STRING_ASSERT(moved_to_abspath, sbox_wc_path(&b, "X/B"));
+ SVN_TEST_STRING_ASSERT(moved_to_op_root_abspath, sbox_wc_path(&b, "X/B"));
+
+ SVN_ERR(svn_wc__db_follow_moved_to(&moved_tos, b.wc_ctx->db,
+ sbox_wc_path(&b, "A/B/C"), pool, pool));
+ SVN_ERR(check_moved_to(moved_tos, 0, 2, "X/B/C"));
+ SVN_ERR(check_moved_to(moved_tos, 1, 3, "Y"));
+ SVN_TEST_ASSERT(moved_tos->nelts == 2);
+
+ SVN_ERR(svn_wc__db_scan_deletion(NULL, &moved_to_abspath,
+ NULL, &moved_to_op_root_abspath,
+ b.wc_ctx->db, sbox_wc_path(&b, "A/B/C"),
+ pool, pool));
+ SVN_TEST_STRING_ASSERT(moved_to_abspath, sbox_wc_path(&b, "X/B/C"));
+ SVN_TEST_STRING_ASSERT(moved_to_op_root_abspath, sbox_wc_path(&b, "X/B"));
+
+ SVN_ERR(svn_wc__db_scan_deletion(NULL, &moved_to_abspath,
+ NULL, &moved_to_op_root_abspath,
+ b.wc_ctx->db, sbox_wc_path(&b, "A2"),
+ pool, pool));
+ SVN_TEST_STRING_ASSERT(moved_to_abspath, sbox_wc_path(&b, "X"));
+ SVN_TEST_STRING_ASSERT(moved_to_op_root_abspath, sbox_wc_path(&b, "X"));
+
+ SVN_ERR(svn_wc__db_scan_deletion(NULL, &moved_to_abspath,
+ NULL, &moved_to_op_root_abspath,
+ b.wc_ctx->db, sbox_wc_path(&b, "A2/B"),
+ pool, pool));
+ SVN_TEST_STRING_ASSERT(moved_to_abspath, sbox_wc_path(&b, "X/B"));
+ SVN_TEST_STRING_ASSERT(moved_to_op_root_abspath, sbox_wc_path(&b, "X"));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_follow_moved_to(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+ apr_array_header_t *moved_tos;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "follow_moved_to", opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A1"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A1/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A1/B/C"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A1/B/C/D"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A1/B/C/D/E"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A2"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A2/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A2/B/C"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A2/B/C/D"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A2/B/C/D/E"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A3"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A3/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A3/B/C"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A3/B/C/D"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A3/B/C/D/E"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A1", "normal", 1, "A1"},
+ {0, "A1/B", "normal", 1, "A1/B"},
+ {0, "A1/B/C", "normal", 1, "A1/B/C"},
+ {0, "A1/B/C/D", "normal", 1, "A1/B/C/D"},
+ {0, "A1/B/C/D/E", "normal", 1, "A1/B/C/D/E"},
+ {0, "A2", "normal", 1, "A2"},
+ {0, "A2/B", "normal", 1, "A2/B"},
+ {0, "A2/B/C", "normal", 1, "A2/B/C"},
+ {0, "A2/B/C/D", "normal", 1, "A2/B/C/D"},
+ {0, "A2/B/C/D/E", "normal", 1, "A2/B/C/D/E"},
+ {0, "A3", "normal", 1, "A3"},
+ {0, "A3/B", "normal", 1, "A3/B"},
+ {0, "A3/B/C", "normal", 1, "A3/B/C"},
+ {0, "A3/B/C/D", "normal", 1, "A3/B/C/D"},
+ {0, "A3/B/C/D/E", "normal", 1, "A3/B/C/D/E"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_move(&b, "A1", "X"));
+ SVN_ERR(sbox_wc_move(&b, "A2", "A1"));
+ SVN_ERR(sbox_wc_move(&b, "A3", "A2"));
+ SVN_ERR(sbox_wc_move(&b, "X", "A3"));
+ SVN_ERR(sbox_wc_move(&b, "A1/B", "X"));
+ SVN_ERR(sbox_wc_move(&b, "A2/B", "A1/B"));
+ SVN_ERR(sbox_wc_move(&b, "A3/B", "A2/B"));
+ SVN_ERR(sbox_wc_move(&b, "X", "A3/B"));
+ SVN_ERR(sbox_wc_move(&b, "A1/B/C/D", "X"));
+ SVN_ERR(sbox_wc_move(&b, "A2/B/C/D", "A1/B/C/D"));
+ SVN_ERR(sbox_wc_move(&b, "A3/B/C/D", "A2/B/C/D"));
+ SVN_ERR(sbox_wc_move(&b, "X", "A3/B/C/D"));
+ SVN_ERR(sbox_wc_move(&b, "A1/B/C/D/E", "X"));
+ SVN_ERR(sbox_wc_move(&b, "A2/B/C/D/E", "A1/B/C/D/E"));
+ SVN_ERR(sbox_wc_move(&b, "A3/B/C/D/E", "A2/B/C/D/E"));
+ SVN_ERR(sbox_wc_move(&b, "X", "A3/B/C/D/E"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A1", "normal", 1, "A1"},
+ {0, "A1/B", "normal", 1, "A1/B"},
+ {0, "A1/B/C", "normal", 1, "A1/B/C"},
+ {0, "A1/B/C/D", "normal", 1, "A1/B/C/D"},
+ {0, "A1/B/C/D/E", "normal", 1, "A1/B/C/D/E"},
+ {0, "A2", "normal", 1, "A2"},
+ {0, "A2/B", "normal", 1, "A2/B"},
+ {0, "A2/B/C", "normal", 1, "A2/B/C"},
+ {0, "A2/B/C/D", "normal", 1, "A2/B/C/D"},
+ {0, "A2/B/C/D/E", "normal", 1, "A2/B/C/D/E"},
+ {0, "A3", "normal", 1, "A3"},
+ {0, "A3/B", "normal", 1, "A3/B"},
+ {0, "A3/B/C", "normal", 1, "A3/B/C"},
+ {0, "A3/B/C/D", "normal", 1, "A3/B/C/D"},
+ {0, "A3/B/C/D/E", "normal", 1, "A3/B/C/D/E"},
+
+ {1, "A1", "normal", 1, "A2", FALSE, "A3", TRUE},
+ {1, "A1/B", "normal", 1, "A2/B", MOVED_HERE},
+ {1, "A1/B/C", "normal", 1, "A2/B/C", MOVED_HERE},
+ {1, "A1/B/C/D", "normal", 1, "A2/B/C/D", MOVED_HERE},
+ {1, "A1/B/C/D/E", "normal", 1, "A2/B/C/D/E", MOVED_HERE},
+
+ {1, "A2", "normal", 1, "A3", FALSE, "A1", TRUE},
+ {1, "A2/B", "normal", 1, "A3/B", MOVED_HERE},
+ {1, "A2/B/C", "normal", 1, "A3/B/C", MOVED_HERE},
+ {1, "A2/B/C/D", "normal", 1, "A3/B/C/D", MOVED_HERE},
+ {1, "A2/B/C/D/E", "normal", 1, "A3/B/C/D/E", MOVED_HERE},
+
+ {1, "A3", "normal", 1, "A1", FALSE, "A2", TRUE},
+ {1, "A3/B", "normal", 1, "A1/B", MOVED_HERE},
+ {1, "A3/B/C", "normal", 1, "A1/B/C", MOVED_HERE},
+ {1, "A3/B/C/D", "normal", 1, "A1/B/C/D", MOVED_HERE},
+ {1, "A3/B/C/D/E", "normal", 1, "A1/B/C/D/E", MOVED_HERE},
+
+ {2, "A1/B", "normal", 1, "A3/B", FALSE, "A3/B", TRUE},
+ {2, "A1/B/C", "normal", 1, "A3/B/C", MOVED_HERE},
+ {2, "A1/B/C/D", "normal", 1, "A3/B/C/D", MOVED_HERE},
+ {2, "A1/B/C/D/E", "normal", 1, "A3/B/C/D/E", MOVED_HERE},
+
+ {2, "A2/B", "normal", 1, "A1/B", FALSE, "A1/B", TRUE},
+ {2, "A2/B/C", "normal", 1, "A1/B/C", MOVED_HERE},
+ {2, "A2/B/C/D", "normal", 1, "A1/B/C/D", MOVED_HERE},
+ {2, "A2/B/C/D/E", "normal", 1, "A1/B/C/D/E", MOVED_HERE},
+
+ {2, "A3/B", "normal", 1, "A2/B", FALSE, "A2/B", TRUE},
+ {2, "A3/B/C", "normal", 1, "A2/B/C", MOVED_HERE},
+ {2, "A3/B/C/D", "normal", 1, "A2/B/C/D", MOVED_HERE},
+ {2, "A3/B/C/D/E", "normal", 1, "A2/B/C/D/E", MOVED_HERE},
+
+ {4, "A1/B/C/D", "normal", 1, "A1/B/C/D", FALSE, "A3/B/C/D", TRUE},
+ {4, "A1/B/C/D/E", "normal", 1, "A1/B/C/D/E", MOVED_HERE},
+
+ {4, "A2/B/C/D", "normal", 1, "A2/B/C/D", FALSE, "A1/B/C/D", TRUE},
+ {4, "A2/B/C/D/E", "normal", 1, "A2/B/C/D/E", MOVED_HERE},
+
+ {4, "A3/B/C/D", "normal", 1, "A3/B/C/D", FALSE, "A2/B/C/D", TRUE},
+ {4, "A3/B/C/D/E", "normal", 1, "A3/B/C/D/E", MOVED_HERE},
+
+ {5, "A1/B/C/D/E", "normal", 1, "A2/B/C/D/E", FALSE, "A3/B/C/D/E", TRUE},
+ {5, "A2/B/C/D/E", "normal", 1, "A3/B/C/D/E", FALSE, "A1/B/C/D/E", TRUE},
+ {5, "A3/B/C/D/E", "normal", 1, "A1/B/C/D/E", FALSE, "A2/B/C/D/E", TRUE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* A1->A3, A3/B->A2/B, A2/B/C/D->A1/B/C/D, A1/B/C/D/E->A3/B/C/D/E */
+ SVN_ERR(svn_wc__db_follow_moved_to(&moved_tos, b.wc_ctx->db,
+ sbox_wc_path(&b, "A1"), pool, pool));
+ SVN_ERR(check_moved_to(moved_tos, 0, 1, "A3"));
+ SVN_TEST_ASSERT(moved_tos->nelts == 1);
+
+ SVN_ERR(svn_wc__db_follow_moved_to(&moved_tos, b.wc_ctx->db,
+ sbox_wc_path(&b, "A1/B"), pool, pool));
+ SVN_ERR(check_moved_to(moved_tos, 0, 1, "A3/B"));
+ SVN_ERR(check_moved_to(moved_tos, 1, 2, "A2/B"));
+ SVN_TEST_ASSERT(moved_tos->nelts == 2);
+
+ SVN_ERR(svn_wc__db_follow_moved_to(&moved_tos, b.wc_ctx->db,
+ sbox_wc_path(&b, "A1/B/C"), pool, pool));
+ SVN_ERR(check_moved_to(moved_tos, 0, 1, "A3/B/C"));
+ SVN_ERR(check_moved_to(moved_tos, 1, 2, "A2/B/C"));
+ SVN_TEST_ASSERT(moved_tos->nelts == 2);
+
+ SVN_ERR(svn_wc__db_follow_moved_to(&moved_tos, b.wc_ctx->db,
+ sbox_wc_path(&b, "A1/B/C/D"), pool, pool));
+ SVN_ERR(check_moved_to(moved_tos, 0, 1, "A3/B/C/D"));
+ SVN_ERR(check_moved_to(moved_tos, 1, 2, "A2/B/C/D"));
+ SVN_ERR(check_moved_to(moved_tos, 2, 4, "A1/B/C/D"));
+ SVN_TEST_ASSERT(moved_tos->nelts == 3);
+
+ SVN_ERR(svn_wc__db_follow_moved_to(&moved_tos, b.wc_ctx->db,
+ sbox_wc_path(&b, "A1/B/C/D/E"), pool, pool));
+ SVN_ERR(check_moved_to(moved_tos, 0, 1, "A3/B/C/D/E"));
+ SVN_ERR(check_moved_to(moved_tos, 1, 2, "A2/B/C/D/E"));
+ SVN_ERR(check_moved_to(moved_tos, 2, 4, "A1/B/C/D/E"));
+ SVN_ERR(check_moved_to(moved_tos, 3, 5, "A3/B/C/D/E"));
+ SVN_TEST_ASSERT(moved_tos->nelts == 4);
+
+ SVN_ERR(sbox_wc_delete(&b, "A3/B/C/D/E"));
+ SVN_ERR(svn_wc__db_follow_moved_to(&moved_tos, b.wc_ctx->db,
+ sbox_wc_path(&b, "A1/B/C/D/E"), pool, pool));
+ SVN_ERR(check_moved_to(moved_tos, 0, 1, "A3/B/C/D/E"));
+ SVN_ERR(check_moved_to(moved_tos, 1, 2, "A2/B/C/D/E"));
+ SVN_ERR(check_moved_to(moved_tos, 2, 4, "A1/B/C/D/E"));
+ SVN_TEST_ASSERT(moved_tos->nelts == 3);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+mixed_rev_move(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+ apr_array_header_t *moved_tos;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "mixed_rev_move", opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 0, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "A/B/C", "normal", 3, "A/B/C"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* We don't allow mixed-rev move in 1.8 and the command line client
+ will return an error, but for compatibility with 1.7 move has an
+ allow_mixed_revisions=TRUE flag which is being used here so the
+ move transforms automatically into copy+delete. This test was
+ written before that transforming was implemented so still expects
+ some move information. */
+ SVN_ERR(sbox_wc_move(&b, "A", "X"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 0, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "A/B/C", "normal", 3, "A/B/C"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "X"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {1, "X", "normal", 1, "A", MOVED_HERE},
+ {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"},
+ {3, "X/B/C", "normal", 3, "A/B/C"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* ### These values PASS but I'm not sure they are correct. */
+ SVN_ERR(svn_wc__db_follow_moved_to(&moved_tos, b.wc_ctx->db,
+ sbox_wc_path(&b, "A/B/C"), pool, pool));
+ SVN_ERR(check_moved_to(moved_tos, 0, 1, "X/B/C"));
+ SVN_TEST_ASSERT(moved_tos->nelts == 1);
+
+ SVN_ERR(svn_wc__db_follow_moved_to(&moved_tos, b.wc_ctx->db,
+ sbox_wc_path(&b, "A/B"), pool, pool));
+ SVN_ERR(check_moved_to(moved_tos, 0, 1, "X/B"));
+ SVN_TEST_ASSERT(moved_tos->nelts == 1);
+
+ SVN_ERR(svn_wc__db_follow_moved_to(&moved_tos, b.wc_ctx->db,
+ sbox_wc_path(&b, "A"), pool, pool));
+ SVN_ERR(check_moved_to(moved_tos, 0, 1, "X"));
+ SVN_TEST_ASSERT(moved_tos->nelts == 1);
+
+
+ /* This move doesn't record moved-to */
+ SVN_ERR(sbox_wc_move(&b, "X/B", "X/Y"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 0, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "A/B/C", "normal", 3, "A/B/C"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "X"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {1, "X", "normal", 1, "A", MOVED_HERE},
+ {1, "X/B", "not-present", 2, "A/B"},
+ {2, "X/Y", "normal", 2, "A/B"},
+ {2, "X/Y/C", "not-present", NO_COPY_FROM},
+ {3, "X/Y/C", "normal", 3, "A/B/C"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(svn_wc__db_follow_moved_to(&moved_tos, b.wc_ctx->db,
+ sbox_wc_path(&b, "A/B/C"), pool, pool));
+ SVN_TEST_ASSERT(moved_tos->nelts == 0);
+
+ SVN_ERR(svn_wc__db_follow_moved_to(&moved_tos, b.wc_ctx->db,
+ sbox_wc_path(&b, "A/B"), pool, pool));
+ SVN_TEST_ASSERT(moved_tos->nelts == 0);
+
+ SVN_ERR(svn_wc__db_follow_moved_to(&moved_tos, b.wc_ctx->db,
+ sbox_wc_path(&b, "A"), pool, pool));
+ SVN_ERR(check_moved_to(moved_tos, 0, 1, "X"));
+ SVN_TEST_ASSERT(moved_tos->nelts == 1);
+
+ return SVN_NO_ERROR;
+}
+
+/* Test the result of 'update' when the incoming changes are inside a
+ * directory that is locally moved. */
+static svn_error_t *
+update_prop_mod_into_moved(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "update_prop_mod_into_moved", opts, pool));
+
+ /* r1: Create files 'f', 'h' */
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ sbox_file_write(&b, "A/B/f", "r1 content\n");
+ sbox_file_write(&b, "A/B/h", "r1 content\n");
+ SVN_ERR(sbox_wc_add(&b, "A/B/f"));
+ SVN_ERR(sbox_wc_add(&b, "A/B/h"));
+ SVN_ERR(sbox_wc_propset(&b, "pd", "f1", "A/B/f"));
+ SVN_ERR(sbox_wc_propset(&b, "pn", "f1", "A/B/f"));
+ SVN_ERR(sbox_wc_propset(&b, "pm", "f1", "A/B/f"));
+ SVN_ERR(sbox_wc_propset(&b, "p", "h1", "A/B/h"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ /* r2: Modify 'f'. Delete prop 'pd', modify prop 'pm', add prop 'pa',
+ * leave prop 'pn' unchanged. */
+ sbox_file_write(&b, "A/B/f", "r1 content\nr2 content\n");
+ SVN_ERR(sbox_wc_propset(&b, "pd", NULL, "A/B/f"));
+ SVN_ERR(sbox_wc_propset(&b, "pm", "f2", "A/B/f"));
+ SVN_ERR(sbox_wc_propset(&b, "pa", "f2", "A/B/f"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ /* r3: Delete 'h', add 'g' */
+ sbox_file_write(&b, "A/B/g", "r3 content\n");
+ SVN_ERR(sbox_wc_add(&b, "A/B/g"));
+ SVN_ERR(sbox_wc_propset(&b, "p", "g3", "A/B/g"));
+ SVN_ERR(sbox_wc_delete(&b, "A/B/h"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/f", "normal", 1, "A/B/f", NOT_MOVED, "pd,pm,pn"},
+ {0, "A/B/h", "normal", 1, "A/B/h", NOT_MOVED, "p"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* A is single-revision so A2 is a single-revision copy */
+ SVN_ERR(sbox_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, "A/B/f", "normal", 1, "A/B/f", NOT_MOVED, "pd,pm,pn"},
+ {0, "A/B/h", "normal", 1, "A/B/h", NOT_MOVED, "p"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/f", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/h", "base-deleted", NO_COPY_FROM},
+ {1, "A2", "normal", 1, "A", MOVED_HERE},
+ {1, "A2/B", "normal", 1, "A/B", MOVED_HERE},
+ {1, "A2/B/f", "normal", 1, "A/B/f", MOVED_HERE, "pd,pm,pn"},
+ {1, "A2/B/h", "normal", 1, "A/B/h", MOVED_HERE, "p"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Update causes a tree-conflict on A due to incoming text-change. */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 2, ""},
+ {0, "A", "normal", 2, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "A/B/f", "normal", 2, "A/B/f", NOT_MOVED, "pa,pm,pn"},
+ {0, "A/B/h", "normal", 2, "A/B/h", NOT_MOVED, "p"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/f", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/h", "base-deleted", NO_COPY_FROM},
+ {1, "A2", "normal", 1, "A", MOVED_HERE},
+ {1, "A2/B", "normal", 1, "A/B", MOVED_HERE},
+ {1, "A2/B/f", "normal", 1, "A/B/f", MOVED_HERE, "pd,pm,pn"},
+ {1, "A2/B/h", "normal", 1, "A/B/h", MOVED_HERE, "p"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Resolve should update the move. */
+ SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 2, ""},
+ {0, "A", "normal", 2, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "A/B/f", "normal", 2, "A/B/f", NOT_MOVED, "pa,pm,pn"},
+ {0, "A/B/h", "normal", 2, "A/B/h", NOT_MOVED, "p"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/f", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/h", "base-deleted", NO_COPY_FROM},
+ {1, "A2", "normal", 2, "A", MOVED_HERE},
+ {1, "A2/B", "normal", 2, "A/B", MOVED_HERE},
+ {1, "A2/B/f", "normal", 2, "A/B/f", MOVED_HERE, "pa,pm,pn"},
+ {1, "A2/B/h", "normal", 2, "A/B/h", MOVED_HERE, "p"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+nested_move_update(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "nested_move_update", opts, pool));
+
+ /* r1: Create file 'f' */
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ sbox_file_write(&b, "A/B/C/f", "r1 content\n");
+ SVN_ERR(sbox_wc_add(&b, "A/B/C/f"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ /* r2: Modify 'f' */
+ sbox_file_write(&b, "A/B/C/f", "r1 content\nr2 content\n");
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ /* r3: Create 'X' */
+ SVN_ERR(sbox_wc_mkdir(&b, "X"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_move(&b, "A", "A2"));
+ SVN_ERR(sbox_wc_move(&b, "A2/B/C", "A2/B/C2"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
+ {0, "A/B/C/f", "normal", 1, "A/B/C/f"},
+ {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, "A/B/C/f", "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},
+ {1, "A2/B/C/f", "normal", 1, "A/B/C/f", MOVED_HERE},
+ {3, "A2/B/C", "base-deleted", NO_COPY_FROM, "A2/B/C2"},
+ {3, "A2/B/C/f", "base-deleted", NO_COPY_FROM},
+ {3, "A2/B/C2", "normal", 1, "A/B/C", MOVED_HERE},
+ {3, "A2/B/C2/f", "normal", 1, "A/B/C/f", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+
+ /* Following the A->A2 move should raise a tree-conflict on A2/B/C,
+ resolving that may require an explicit resolve. */
+ SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(sbox_wc_resolve(&b, "A2/B/C", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 2, ""},
+ {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"},
+ {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, "A/B/C/f", "base-deleted", NO_COPY_FROM},
+ {1, "A2", "normal", 2, "A", MOVED_HERE},
+ {1, "A2/B", "normal", 2, "A/B", MOVED_HERE},
+ {1, "A2/B/C", "normal", 2, "A/B/C", MOVED_HERE},
+ {1, "A2/B/C/f", "normal", 2, "A/B/C/f", MOVED_HERE},
+ {3, "A2/B/C", "base-deleted", NO_COPY_FROM, "A2/B/C2"},
+ {3, "A2/B/C/f", "base-deleted", NO_COPY_FROM},
+ {3, "A2/B/C2", "normal", 2, "A/B/C", MOVED_HERE},
+ {3, "A2/B/C2/f", "normal", 2, "A/B/C/f", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Update A to r3 brings no changes but updates the revisions. */
+ SVN_ERR(sbox_wc_update(&b, "A", 3));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 2, ""},
+ {0, "A", "normal", 3, "A"},
+ {0, "A/B", "normal", 3, "A/B"},
+ {0, "A/B/C", "normal", 3, "A/B/C"},
+ {0, "A/B/C/f", "normal", 3, "A/B/C/f"},
+ {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, "A/B/C/f", "base-deleted", NO_COPY_FROM},
+ {1, "A2", "normal", 3, "A", MOVED_HERE},
+ {1, "A2/B", "normal", 3, "A/B", MOVED_HERE},
+ {1, "A2/B/C", "normal", 3, "A/B/C", MOVED_HERE},
+ {1, "A2/B/C/f", "normal", 3, "A/B/C/f", MOVED_HERE},
+ {3, "A2/B/C", "base-deleted", NO_COPY_FROM, "A2/B/C2"},
+ {3, "A2/B/C/f", "base-deleted", NO_COPY_FROM},
+ {3, "A2/B/C2", "normal", 3, "A/B/C", MOVED_HERE},
+ {3, "A2/B/C2/f", "normal", 3, "A/B/C/f", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+nested_move_commit(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "nested_move_commit", opts, pool));
+
+ /* r1: Create file 'f' */
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ sbox_file_write(&b, "A/B/C/f", "r1 content\n");
+ SVN_ERR(sbox_wc_add(&b, "A/B/C/f"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_move(&b, "A/B/C", "C2"));
+
+ {
+ const char *moved_to;
+ const char *expected_to;
+ SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL, NULL, &moved_to,
+ b.wc_ctx->db, sbox_wc_path(&b, "A/B/C"),
+ pool, pool));
+
+ expected_to = sbox_wc_path(&b, "C2");
+
+ if (strcmp(moved_to, expected_to) != 0)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "Expected moved to %s, but was %s",
+ expected_to, moved_to);
+ }
+ {
+ const char *moved_from;
+ const char *expected_from;
+ SVN_ERR(svn_wc__db_scan_moved(&moved_from, NULL, NULL, NULL,
+ b.wc_ctx->db, sbox_wc_path(&b, "C2"),
+ pool, pool));
+
+ expected_from = sbox_wc_path(&b, "A/B/C");
+
+ if (strcmp(moved_from, expected_from) != 0)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "Expected moved from %s, but was %s",
+ expected_from, moved_from);
+ }
+
+ SVN_ERR(sbox_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, "A/B/C", "normal", 1, "A/B/C"},
+ {0, "A/B/C/f", "normal", 1, "A/B/C/f"},
+ {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, "A/B/C/f", "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},
+ {1, "A2/B/C/f", "normal", 1, "A/B/C/f", MOVED_HERE},
+ {3, "A2/B/C", "base-deleted", NO_COPY_FROM, "C2"},
+ {3, "A2/B/C/f", "base-deleted", NO_COPY_FROM},
+ {1, "C2", "normal", 1, "A/B/C", MOVED_HERE},
+ {1, "C2/f", "normal", 1, "A/B/C/f", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ {
+ const char *moved_to;
+ const char *expected_to;
+ SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL, NULL, &moved_to,
+ b.wc_ctx->db, sbox_wc_path(&b, "A/B/C"),
+ pool, pool));
+
+ /* A/B/C is part of the A->A2 move. */
+ expected_to = sbox_wc_path(&b, "A2");
+ if (strcmp(moved_to, expected_to) != 0)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "Expected moved to %s, but was %s",
+ expected_to, moved_to);
+
+ SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL, NULL, &moved_to,
+ b.wc_ctx->db, sbox_wc_path(&b, "A2/B/C"),
+ pool, pool));
+
+ /* A2/B/C is the A2/B/C->C2 move. */
+ expected_to = sbox_wc_path(&b, "C2");
+ if (strcmp(moved_to, expected_to) != 0)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "Expected moved to %s, but was %s",
+ expected_to, moved_to);
+ }
+ {
+ const char *moved_from;
+ const char *expected_from;
+ SVN_ERR(svn_wc__db_scan_moved(&moved_from, NULL, NULL, NULL,
+ b.wc_ctx->db, sbox_wc_path(&b, "C2"),
+ pool, pool));
+
+ /* C2 is the A2/B/C->C2 move. */
+ expected_from = sbox_wc_path(&b, "A2/B/C");
+ if (strcmp(moved_from, expected_from) != 0)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "Expected moved from %s, but was %s",
+ expected_from, moved_from);
+ }
+
+ {
+ apr_array_header_t *targets = apr_array_make(pool, 2, sizeof(const char *));
+
+ APR_ARRAY_PUSH(targets, const char *) = sbox_wc_path(&b, "A");
+ APR_ARRAY_PUSH(targets, const char *) = sbox_wc_path(&b, "A2");
+
+ SVN_ERR(sbox_wc_commit_ex(&b, targets, svn_depth_empty));
+ }
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "not-present", 2, "A"},
+ {0, "A2", "normal", 2, "A2"},
+ {0, "A2/B", "normal", 2, "A2/B"},
+ {0, "A2/B/C", "normal", 2, "A2/B/C"},
+ {0, "A2/B/C/f", "normal", 2, "A2/B/C/f"},
+ {3, "A2/B/C", "base-deleted", NO_COPY_FROM, "C2"},
+ {3, "A2/B/C/f", "base-deleted", NO_COPY_FROM},
+
+ /* These need to have their copyfrom information updated */
+ {1, "C2", "normal", 2, "A2/B/C", MOVED_HERE},
+ {1, "C2/f", "normal", 2, "A2/B/C/f", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ {
+ const char *moved_to;
+ const char *expected_to;
+ SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL, NULL, &moved_to,
+ b.wc_ctx->db, sbox_wc_path(&b, "A2/B/C"),
+ pool, pool));
+
+ expected_to = sbox_wc_path(&b, "C2");
+
+ if (strcmp(moved_to, expected_to) != 0)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "Expected moved to %s, but was %s",
+ expected_to, moved_to);
+ }
+
+ {
+ const char *moved_from;
+ const char *expected_from;
+ SVN_ERR(svn_wc__db_scan_moved(&moved_from, NULL, NULL, NULL,
+ b.wc_ctx->db, sbox_wc_path(&b, "C2"),
+ pool, pool));
+
+ expected_from = sbox_wc_path(&b, "A2/B/C");
+
+ if (strcmp(moved_from, expected_from) != 0)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "Expected moved from %s, but was %s",
+ expected_from, moved_from);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+nested_move_update2(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "nested_move_update2", opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "P"));
+ SVN_ERR(sbox_wc_mkdir(&b, "P/Q"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "X"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_move(&b, "A", "A2"));
+ SVN_ERR(sbox_wc_move(&b, "P", "A"));
+ SVN_ERR(sbox_wc_move(&b, "A2", "P"));
+ SVN_ERR(sbox_wc_move(&b, "A/Q", "A/Q2"));
+ SVN_ERR(sbox_wc_move(&b, "P/B", "P/B2"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "P", "normal", 1, "P"},
+ {0, "P/Q", "normal", 1, "P/Q"},
+ {1, "A", "normal", 1, "P", FALSE, "P", TRUE},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/Q", "normal", 1, "P/Q", MOVED_HERE},
+ {1, "P", "normal", 1, "A", FALSE, "A", TRUE},
+ {1, "P/Q", "base-deleted", NO_COPY_FROM},
+ {1, "P/B", "normal", 1, "A/B", MOVED_HERE},
+ {2, "A/Q", "base-deleted", NO_COPY_FROM, "A/Q2"},
+ {2, "A/Q2", "normal", 1, "P/Q", MOVED_HERE},
+ {2, "P/B", "base-deleted", NO_COPY_FROM, "P/B2"},
+ {2, "P/B2", "normal", 1, "A/B", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Update A bumps revisions but only for moves originating in A. In
+ particular A/Q to A/Q2 does not get bumped. */
+ SVN_ERR(sbox_wc_update(&b, "A", 2));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 2, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "P", "normal", 1, "P"},
+ {0, "P/Q", "normal", 1, "P/Q"},
+ {1, "A", "normal", 1, "P", FALSE, "P", TRUE},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/Q", "normal", 1, "P/Q", MOVED_HERE},
+ {1, "P", "normal", 2, "A", FALSE, "A", TRUE},
+ {1, "P/Q", "base-deleted", NO_COPY_FROM},
+ {1, "P/B", "normal", 2, "A/B", MOVED_HERE},
+ {2, "A/Q", "base-deleted", NO_COPY_FROM, "A/Q2"},
+ {2, "A/Q2", "normal", 1, "P/Q", MOVED_HERE},
+ {2, "P/B", "base-deleted", NO_COPY_FROM, "P/B2"},
+ {2, "P/B2", "normal", 2, "A/B", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+check_tree_conflict_repos_path(svn_test__sandbox_t *b,
+ const char *wc_path,
+ const char *repos_path1,
+ const char *repos_path2)
+{
+ svn_skel_t *conflict;
+ svn_wc_operation_t operation;
+ const apr_array_header_t *locations;
+ svn_boolean_t text_conflicted, prop_conflicted, tree_conflicted;
+
+ SVN_ERR(svn_wc__db_read_conflict(&conflict, b->wc_ctx->db,
+ sbox_wc_path(b, wc_path),
+ b->pool, b->pool));
+
+ SVN_ERR(svn_wc__conflict_read_info(&operation, &locations,
+ &text_conflicted, &prop_conflicted,
+ &tree_conflicted,
+ b->wc_ctx->db, b->wc_abspath,
+ conflict, b->pool, b->pool));
+
+ SVN_ERR_ASSERT(tree_conflicted);
+
+ if (repos_path1)
+ {
+ svn_wc_conflict_version_t *version
+ = APR_ARRAY_IDX(locations, 0, svn_wc_conflict_version_t *);
+
+ SVN_ERR_ASSERT(!strcmp(version->path_in_repos, repos_path1));
+ }
+
+ if (repos_path2)
+ {
+ svn_wc_conflict_version_t *version
+ = APR_ARRAY_IDX(locations, 1, svn_wc_conflict_version_t *);
+
+ SVN_ERR_ASSERT(!strcmp(version->path_in_repos, repos_path2));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_update_conflicts(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_update_conflicts", opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "X"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X/A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X/A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X/A/B/C"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X/A/B/C/D"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "X/A/B/C/D/E"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X/A/B/F"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_switch(&b, "", "/X", svn_depth_infinity));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_move(&b, "A", "A2"));
+ SVN_ERR(sbox_wc_move(&b, "A2/B/C", "A2/B/C2"));
+ sbox_file_write(&b, "A2/B/F", "obstruction\n");
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, "X"},
+ {0, "A", "normal", 1, "X/A"},
+ {0, "A/B", "normal", 1, "X/A/B"},
+ {0, "A/B/C", "normal", 1, "X/A/B/C"},
+ {0, "A/B/C/D", "normal", 1, "X/A/B/C/D"},
+ {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, "A/B/C/D", "base-deleted", NO_COPY_FROM},
+ {1, "A2", "normal", 1, "X/A", MOVED_HERE},
+ {1, "A2/B", "normal", 1, "X/A/B", MOVED_HERE},
+ {1, "A2/B/C", "normal", 1, "X/A/B/C", MOVED_HERE},
+ {1, "A2/B/C/D", "normal", 1, "X/A/B/C/D", MOVED_HERE},
+ {3, "A2/B/C", "base-deleted", NO_COPY_FROM, "A2/B/C2"},
+ {3, "A2/B/C/D", "base-deleted", NO_COPY_FROM},
+ {3, "A2/B/C2", "normal", 1, "X/A/B/C", MOVED_HERE},
+ {3, "A2/B/C2/D", "normal", 1, "X/A/B/C/D", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_update(&b, "A", 2));
+ SVN_ERR(check_tree_conflict_repos_path(&b, "A", "X/A", "X/A"));
+ SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, "X"},
+ {0, "A", "normal", 2, "X/A"},
+ {0, "A/B", "normal", 2, "X/A/B"},
+ {0, "A/B/C", "normal", 2, "X/A/B/C"},
+ {0, "A/B/C/D", "normal", 2, "X/A/B/C/D"},
+ {0, "A/B/C/D/E", "normal", 2, "X/A/B/C/D/E"},
+ {0, "A/B/F", "normal", 2, "X/A/B/F"},
+ {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, "A/B/C/D", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C/D/E", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/F", "base-deleted", NO_COPY_FROM},
+ {1, "A2", "normal", 2, "X/A", MOVED_HERE},
+ {1, "A2/B", "normal", 2, "X/A/B", MOVED_HERE},
+ {1, "A2/B/C", "normal", 2, "X/A/B/C", MOVED_HERE},
+ {1, "A2/B/C/D", "normal", 2, "X/A/B/C/D", MOVED_HERE},
+ {1, "A2/B/C/D/E", "normal", 2, "X/A/B/C/D/E", MOVED_HERE},
+ {1, "A2/B/F", "normal", 2, "X/A/B/F", MOVED_HERE},
+ {3, "A2/B/C", "base-deleted", NO_COPY_FROM, "A2/B/C2"},
+ {3, "A2/B/C/D", "base-deleted", NO_COPY_FROM},
+ {3, "A2/B/C/D/E", "base-deleted", NO_COPY_FROM},
+ {3, "A2/B/C2", "normal", 1, "X/A/B/C", MOVED_HERE},
+ {3, "A2/B/C2/D", "normal", 1, "X/A/B/C/D", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(check_tree_conflict_repos_path(&b, "A2/B/C", "X/A/B/C", "X/A/B/C"));
+ SVN_ERR(check_tree_conflict_repos_path(&b, "A2/B/F", NULL, "X/A/B/F"));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_update_delete_mods(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_update_delete_mods", opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/D"));
+ sbox_file_write(&b, "A/B/C/f", "r1 content\n");
+ SVN_ERR(sbox_wc_add(&b, "A/B/C/f"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_delete(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_delete(&b, "A/B/D"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_move(&b, "A/B", "B2"));
+ sbox_file_write(&b, "B2/C/f", "modified content\n");
+ SVN_ERR(sbox_wc_delete(&b, "B2/D"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
+ {0, "A/B/C/f", "normal", 1, "A/B/C/f"},
+ {0, "A/B/D", "normal", 1, "A/B/D"},
+ {2, "A/B", "base-deleted", NO_COPY_FROM, "B2"},
+ {2, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {2, "A/B/C/f", "base-deleted", NO_COPY_FROM},
+ {2, "A/B/D", "base-deleted", NO_COPY_FROM},
+ {1, "B2", "normal", 1, "A/B", MOVED_HERE},
+ {1, "B2/C", "normal", 1, "A/B/C", MOVED_HERE},
+ {1, "B2/C/f", "normal", 1, "A/B/C/f", MOVED_HERE},
+ {1, "B2/D", "normal", 1, "A/B/D", MOVED_HERE},
+ {2, "B2/D", "base-deleted", NO_COPY_FROM},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_update(&b, "A", 2));
+ SVN_ERR(sbox_wc_resolve(&b, "A/B", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 2, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {2, "A/B", "base-deleted", NO_COPY_FROM, "B2"},
+ {1, "B2", "normal", 2, "A/B", MOVED_HERE},
+ {2, "B2/C", "normal", 1, "A/B/C"},
+ {2, "B2/C/f", "normal", 1, "A/B/C/f"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(check_tree_conflict_repos_path(&b, "B2/C", "A/B/C", "A/B/C"));
+ SVN_ERR(check_tree_conflict_repos_path(&b, "B2/D", "A/B/D", "A/B/D"));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+nested_moves2(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "nested_moves2", 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, "A/A/A/A/A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/A/A/A/A/A"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "X"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ SVN_ERR(sbox_wc_move(&b, "A/A/A/A/A/A", "C"));
+ SVN_ERR(sbox_wc_move(&b, "A/A/A/A", "D"));
+ SVN_ERR(sbox_wc_move(&b, "A/A", "E"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 0, ""},
+ {0, "X", "normal", 2, "X"},
+ {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, "A/A/A/A/A", "normal", 1, "A/A/A/A/A"},
+ {0, "A/A/A/A/A/A", "normal", 1, "A/A/A/A/A/A"},
+ {2, "A/A", "base-deleted", NO_COPY_FROM, "E"},
+ {2, "A/A/A", "base-deleted", NO_COPY_FROM},
+ {2, "A/A/A/A", "base-deleted", NO_COPY_FROM},
+ {2, "A/A/A/A/A", "base-deleted", NO_COPY_FROM},
+ {2, "A/A/A/A/A/A", "base-deleted", NO_COPY_FROM},
+ {1, "E", "normal", 1, "A/A", MOVED_HERE},
+ {1, "E/A", "normal", 1, "A/A/A", MOVED_HERE},
+ {1, "E/A/A", "normal", 1, "A/A/A/A", MOVED_HERE},
+ {1, "E/A/A/A", "normal", 1, "A/A/A/A/A", MOVED_HERE},
+ {1, "E/A/A/A/A", "normal", 1, "A/A/A/A/A/A", MOVED_HERE},
+ {3, "E/A/A", "base-deleted", NO_COPY_FROM, "D"},
+ {3, "E/A/A/A", "base-deleted", NO_COPY_FROM},
+ {3, "E/A/A/A/A", "base-deleted", NO_COPY_FROM},
+ {1, "D", "normal", 1, "A/A/A/A", MOVED_HERE},
+ {1, "D/A", "normal", 1, "A/A/A/A/A", MOVED_HERE},
+ {1, "D/A/A", "normal", 1, "A/A/A/A/A/A", MOVED_HERE},
+ {3, "D/A/A", "base-deleted", NO_COPY_FROM, "C"},
+ {1, "C", "normal", 1, "A/A/A/A/A/A", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_update(&b, "A", 2));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 0, ""},
+ {0, "X", "normal", 2, "X"},
+ {0, "A", "normal", 2, "A"},
+ {0, "A/A", "normal", 2, "A/A"},
+ {0, "A/A/A", "normal", 2, "A/A/A"},
+ {0, "A/A/A/A", "normal", 2, "A/A/A/A"},
+ {0, "A/A/A/A/A", "normal", 2, "A/A/A/A/A"},
+ {0, "A/A/A/A/A/A", "normal", 2, "A/A/A/A/A/A"},
+ {2, "A/A", "base-deleted", NO_COPY_FROM, "E"},
+ {2, "A/A/A", "base-deleted", NO_COPY_FROM},
+ {2, "A/A/A/A", "base-deleted", NO_COPY_FROM},
+ {2, "A/A/A/A/A", "base-deleted", NO_COPY_FROM},
+ {2, "A/A/A/A/A/A", "base-deleted", NO_COPY_FROM},
+ {1, "E", "normal", 2, "A/A", MOVED_HERE},
+ {1, "E/A", "normal", 2, "A/A/A", MOVED_HERE},
+ {1, "E/A/A", "normal", 2, "A/A/A/A", MOVED_HERE},
+ {1, "E/A/A/A", "normal", 2, "A/A/A/A/A", MOVED_HERE},
+ {1, "E/A/A/A/A", "normal", 2, "A/A/A/A/A/A", MOVED_HERE},
+ {3, "E/A/A", "base-deleted", NO_COPY_FROM, "D"},
+ {3, "E/A/A/A", "base-deleted", NO_COPY_FROM},
+ {3, "E/A/A/A/A", "base-deleted", NO_COPY_FROM},
+ {1, "D", "normal", 2, "A/A/A/A", MOVED_HERE},
+ {1, "D/A", "normal", 2, "A/A/A/A/A", MOVED_HERE},
+ {1, "D/A/A", "normal", 2, "A/A/A/A/A/A", MOVED_HERE},
+ {3, "D/A/A", "base-deleted", NO_COPY_FROM, "C"},
+ {1, "C", "normal", 2, "A/A/A/A/A/A", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_in_delete(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_in_delete", opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C/D"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C/D/E"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "X"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_move(&b, "A/B/C", "C2"));
+ SVN_ERR(sbox_wc_delete(&b, "A/B"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
+ {2, "A/B", "base-deleted", NO_COPY_FROM},
+ {2, "A/B/C", "base-deleted", NO_COPY_FROM, "C2"},
+ {1, "C2", "normal", 1, "A/B/C", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ SVN_ERR(sbox_wc_resolve(&b, "A/B", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(sbox_wc_resolve(&b, "A/B/C", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 2, ""},
+ {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/D", "normal", 2, "A/B/C/D"},
+ {2, "A/B", "base-deleted", NO_COPY_FROM},
+ {2, "A/B/C", "base-deleted", NO_COPY_FROM, "C2"},
+ {2, "A/B/C/D", "base-deleted", NO_COPY_FROM},
+ {1, "C2", "normal", 2, "A/B/C", MOVED_HERE},
+ {1, "C2/D", "normal", 2, "A/B/C/D", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_update(&b, "", 3));
+ SVN_ERR(sbox_wc_revert(&b, "A/B", svn_depth_empty));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 3, ""},
+ {0, "A", "normal", 3, "A"},
+ {0, "A/B", "normal", 3, "A/B"},
+ {0, "A/B/C", "normal", 3, "A/B/C"},
+ {0, "A/B/C/D", "normal", 3, "A/B/C/D"},
+ {0, "A/B/C/D/E", "normal", 3, "A/B/C/D/E"},
+ {3, "A/B/C", "base-deleted", NO_COPY_FROM, "C2"},
+ {3, "A/B/C/D", "base-deleted", NO_COPY_FROM},
+ {3, "A/B/C/D/E", "base-deleted", NO_COPY_FROM},
+ {1, "C2", "normal", 2, "A/B/C", MOVED_HERE},
+ {1, "C2/D", "normal", 2, "A/B/C/D", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Revert should have left a tree-conflict (or broken the move). */
+ SVN_ERR(sbox_wc_resolve(&b, "A/B/C", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 3, ""},
+ {0, "A", "normal", 3, "A"},
+ {0, "A/B", "normal", 3, "A/B"},
+ {0, "A/B/C", "normal", 3, "A/B/C"},
+ {0, "A/B/C/D", "normal", 3, "A/B/C/D"},
+ {0, "A/B/C/D/E", "normal", 3, "A/B/C/D/E"},
+ {3, "A/B/C", "base-deleted", NO_COPY_FROM, "C2"},
+ {3, "A/B/C/D", "base-deleted", NO_COPY_FROM},
+ {3, "A/B/C/D/E", "base-deleted", NO_COPY_FROM},
+ {1, "C2", "normal", 3, "A/B/C", MOVED_HERE},
+ {1, "C2/D", "normal", 3, "A/B/C/D", MOVED_HERE},
+ {1, "C2/D/E", "normal", 3, "A/B/C/D/E", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+switch_move(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "switch_move", opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/D"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/D/E"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_copy(&b, "A", "X"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "X/B/D/E/F"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_switch(&b, "", "/A", svn_depth_infinity));
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+
+ SVN_ERR(sbox_wc_move(&b, "B/C", "C2"));
+ SVN_ERR(sbox_wc_move(&b, "B/D", "D2"));
+ SVN_ERR(sbox_wc_move(&b, "D2/E", "D2/E2"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 2, "A"},
+ {0, "B", "normal", 2, "A/B"},
+ {0, "B/C", "normal", 2, "A/B/C"},
+ {0, "B/D", "normal", 2, "A/B/D"},
+ {0, "B/D/E", "normal", 2, "A/B/D/E"},
+ {2, "B/C", "base-deleted", NO_COPY_FROM, "C2"},
+ {2, "B/D", "base-deleted", NO_COPY_FROM, "D2"},
+ {2, "B/D/E", "base-deleted", NO_COPY_FROM},
+ {1, "C2", "normal", 2, "A/B/C", MOVED_HERE},
+ {1, "D2", "normal", 2, "A/B/D", MOVED_HERE},
+ {1, "D2/E", "normal", 2, "A/B/D/E", MOVED_HERE},
+ {2, "D2/E", "base-deleted", NO_COPY_FROM, "D2/E2"},
+ {2, "D2/E2", "normal", 2, "A/B/D/E", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Switch "bumps" revisions and paths and raises conflicts just like
+ update. */
+ SVN_ERR(sbox_wc_switch(&b, "", "/X", svn_depth_infinity));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 3, "X"},
+ {0, "B", "normal", 3, "X/B"},
+ {0, "B/C", "normal", 3, "X/B/C"},
+ {0, "B/D", "normal", 3, "X/B/D"},
+ {0, "B/D/E", "normal", 3, "X/B/D/E"},
+ {0, "B/D/E/F", "normal", 3, "X/B/D/E/F"},
+ {2, "B/C", "base-deleted", NO_COPY_FROM, "C2"},
+ {2, "B/D", "base-deleted", NO_COPY_FROM, "D2"},
+ {2, "B/D/E", "base-deleted", NO_COPY_FROM},
+ {2, "B/D/E/F", "base-deleted", NO_COPY_FROM},
+ {1, "C2", "normal", 3, "X/B/C", MOVED_HERE},
+ {1, "D2", "normal", 2, "A/B/D", MOVED_HERE},
+ {1, "D2/E", "normal", 2, "A/B/D/E", MOVED_HERE},
+ {2, "D2/E", "base-deleted", NO_COPY_FROM, "D2/E2"},
+ {2, "D2/E2", "normal", 2, "A/B/D/E", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Conflicts from switch are resolved just like those from update. */
+ SVN_ERR(sbox_wc_resolve(&b, "B/D", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 3, "X"},
+ {0, "B", "normal", 3, "X/B"},
+ {0, "B/C", "normal", 3, "X/B/C"},
+ {0, "B/D", "normal", 3, "X/B/D"},
+ {0, "B/D/E", "normal", 3, "X/B/D/E"},
+ {0, "B/D/E/F", "normal", 3, "X/B/D/E/F"},
+ {2, "B/C", "base-deleted", NO_COPY_FROM, "C2"},
+ {2, "B/D", "base-deleted", NO_COPY_FROM, "D2"},
+ {2, "B/D/E", "base-deleted", NO_COPY_FROM},
+ {2, "B/D/E/F", "base-deleted", NO_COPY_FROM},
+ {1, "C2", "normal", 3, "X/B/C", MOVED_HERE},
+ {1, "D2", "normal", 3, "X/B/D", MOVED_HERE},
+ {1, "D2/E", "normal", 3, "X/B/D/E", MOVED_HERE},
+ {1, "D2/E/F", "normal", 3, "X/B/D/E/F", MOVED_HERE},
+ {2, "D2/E", "base-deleted", NO_COPY_FROM, "D2/E2"},
+ {2, "D2/E/F", "base-deleted", NO_COPY_FROM},
+ {2, "D2/E2", "normal", 2, "A/B/D/E", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_resolve(&b, "D2/E", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 3, "X"},
+ {0, "B", "normal", 3, "X/B"},
+ {0, "B/C", "normal", 3, "X/B/C"},
+ {0, "B/D", "normal", 3, "X/B/D"},
+ {0, "B/D/E", "normal", 3, "X/B/D/E"},
+ {0, "B/D/E/F", "normal", 3, "X/B/D/E/F"},
+ {2, "B/C", "base-deleted", NO_COPY_FROM, "C2"},
+ {2, "B/D", "base-deleted", NO_COPY_FROM, "D2"},
+ {2, "B/D/E", "base-deleted", NO_COPY_FROM},
+ {2, "B/D/E/F", "base-deleted", NO_COPY_FROM},
+ {1, "C2", "normal", 3, "X/B/C", MOVED_HERE},
+ {1, "D2", "normal", 3, "X/B/D", MOVED_HERE},
+ {1, "D2/E", "normal", 3, "X/B/D/E", MOVED_HERE},
+ {1, "D2/E/F", "normal", 3, "X/B/D/E/F", MOVED_HERE},
+ {2, "D2/E", "base-deleted", NO_COPY_FROM, "D2/E2"},
+ {2, "D2/E/F", "base-deleted", NO_COPY_FROM},
+ {2, "D2/E2", "normal", 3, "X/B/D/E", MOVED_HERE},
+ {2, "D2/E2/F", "normal", 3, "X/B/D/E/F", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_replace(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_replace", opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "B"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "B/X"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_move(&b, "A", "X"));
+ SVN_ERR(sbox_wc_move(&b, "B", "A"));
+ SVN_ERR(sbox_wc_move(&b, "X", "B"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "B", "normal", 1, "B"},
+ {1, "A", "normal", 1, "B", FALSE, "B", TRUE},
+ {1, "B", "normal", 1, "A", FALSE, "A", TRUE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 2, ""},
+ {0, "A", "normal", 2, "A"},
+ {0, "B", "normal", 2, "B"},
+ {0, "B/X", "normal", 2, "B/X"},
+ {1, "A", "normal", 1, "B", FALSE, "B", TRUE},
+ {1, "B", "normal", 2, "A", FALSE, "A", TRUE},
+ {1, "B/X", "base-deleted", NO_COPY_FROM},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_resolve(&b, "B", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 2, ""},
+ {0, "A", "normal", 2, "A"},
+ {0, "B", "normal", 2, "B"},
+ {0, "B/X", "normal", 2, "B/X"},
+ {1, "A", "normal", 2, "B", FALSE, "B", TRUE},
+ {1, "A/X", "normal", 2, "B/X", MOVED_HERE},
+ {1, "B", "normal", 2, "A", FALSE, "A", TRUE},
+ {1, "B/X", "base-deleted", NO_COPY_FROM},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+layered_moved_to(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+ svn_error_t *err;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "layered_moved_to", opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C/D"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C/D/E"));
+ SVN_ERR(sbox_wc_mkdir(&b, "C"));
+ SVN_ERR(sbox_wc_mkdir(&b, "C/D"));
+ SVN_ERR(sbox_wc_mkdir(&b, "C/D/E"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_propset(&b, "property", "value", "A/B/C/D/E"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_propset(&b, "property", "value", "C/D/E"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "P"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_propset(&b, "property2", "value", "A/B/C/D/E"));
+ SVN_ERR(sbox_wc_propset(&b, "property2", "value", "C/D/E"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_move(&b, "A", "X"));
+ SVN_ERR(sbox_wc_move(&b, "X/B/C/D/E", "E2"));
+ SVN_ERR(sbox_wc_delete(&b, "X/B/C"));
+ SVN_ERR(sbox_wc_move(&b, "C", "X/B/C"));
+ SVN_ERR(sbox_wc_move(&b, "X/B/C/D/E", "E3"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
+ {0, "A/B/C/D", "normal", 1, "A/B/C/D"},
+ {0, "A/B/C/D/E", "normal", 1, "A/B/C/D/E"},
+ {0, "C", "normal", 1, "C"},
+ {0, "C/D", "normal", 1, "C/D"},
+ {0, "C/D/E", "normal", 1, "C/D/E"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "X"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C/D", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C/D/E", "base-deleted", NO_COPY_FROM},
+ {1, "C", "base-deleted", NO_COPY_FROM, "X/B/C"},
+ {1, "C/D", "base-deleted", NO_COPY_FROM},
+ {1, "C/D/E", "base-deleted", NO_COPY_FROM},
+ {1, "X", "normal", 1, "A", MOVED_HERE},
+ {1, "X/B", "normal", 1, "A/B", MOVED_HERE},
+ {1, "X/B/C", "normal", 1, "A/B/C", MOVED_HERE},
+ {1, "X/B/C/D", "normal", 1, "A/B/C/D", MOVED_HERE},
+ {1, "X/B/C/D/E", "normal", 1, "A/B/C/D/E", MOVED_HERE},
+ {3, "X/B/C", "normal", 1, "C", MOVED_HERE},
+ {3, "X/B/C/D", "normal", 1, "C/D", MOVED_HERE},
+ {3, "X/B/C/D/E", "normal", 1, "C/D/E", FALSE, "E2", TRUE},
+ {5, "X/B/C/D/E", "base-deleted", NO_COPY_FROM, "E3"},
+ {1, "E2", "normal", 1, "A/B/C/D/E", MOVED_HERE},
+ {1, "E3", "normal", 1, "C/D/E", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_update(&b, "A", 2));
+ SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(sbox_wc_resolve(&b, "X/B/C", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(sbox_wc_resolve(&b, "X/B/C/D/E", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {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/D", "normal", 2, "A/B/C/D"},
+ {0, "A/B/C/D/E", "normal", 2, "A/B/C/D/E"},
+ {0, "C", "normal", 1, "C"},
+ {0, "C/D", "normal", 1, "C/D"},
+ {0, "C/D/E", "normal", 1, "C/D/E"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "X"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C/D", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C/D/E", "base-deleted", NO_COPY_FROM},
+ {1, "C", "base-deleted", NO_COPY_FROM, "X/B/C"},
+ {1, "C/D", "base-deleted", NO_COPY_FROM},
+ {1, "C/D/E", "base-deleted", NO_COPY_FROM},
+ {1, "X", "normal", 2, "A", MOVED_HERE},
+ {1, "X/B", "normal", 2, "A/B", MOVED_HERE},
+ {1, "X/B/C", "normal", 2, "A/B/C", MOVED_HERE},
+ {1, "X/B/C/D", "normal", 2, "A/B/C/D", MOVED_HERE},
+ {1, "X/B/C/D/E", "normal", 2, "A/B/C/D/E", MOVED_HERE},
+ {3, "X/B/C", "normal", 1, "C", MOVED_HERE},
+ {3, "X/B/C/D", "normal", 1, "C/D", MOVED_HERE},
+ {3, "X/B/C/D/E", "normal", 1, "C/D/E", FALSE, "E2", TRUE},
+ {5, "X/B/C/D/E", "base-deleted", NO_COPY_FROM, "E3"},
+ {1, "E2", "normal", 2, "A/B/C/D/E", MOVED_HERE},
+ {1, "E3", "normal", 1, "C/D/E", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_update(&b, "C", 3));
+ SVN_ERR(sbox_wc_resolve(&b, "C", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(sbox_wc_resolve(&b, "X/B/C/D/E", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {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/D", "normal", 2, "A/B/C/D"},
+ {0, "A/B/C/D/E", "normal", 2, "A/B/C/D/E"},
+ {0, "C", "normal", 3, "C"},
+ {0, "C/D", "normal", 3, "C/D"},
+ {0, "C/D/E", "normal", 3, "C/D/E"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "X"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C/D", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C/D/E", "base-deleted", NO_COPY_FROM},
+ {1, "C", "base-deleted", NO_COPY_FROM, "X/B/C"},
+ {1, "C/D", "base-deleted", NO_COPY_FROM},
+ {1, "C/D/E", "base-deleted", NO_COPY_FROM},
+ {1, "X", "normal", 2, "A", MOVED_HERE},
+ {1, "X/B", "normal", 2, "A/B", MOVED_HERE},
+ {1, "X/B/C", "normal", 2, "A/B/C", MOVED_HERE},
+ {1, "X/B/C/D", "normal", 2, "A/B/C/D", MOVED_HERE},
+ {1, "X/B/C/D/E", "normal", 2, "A/B/C/D/E", MOVED_HERE},
+ {3, "X/B/C", "normal", 3, "C", MOVED_HERE},
+ {3, "X/B/C/D", "normal", 3, "C/D", MOVED_HERE},
+ {3, "X/B/C/D/E", "normal", 3, "C/D/E", FALSE, "E2", TRUE},
+ {5, "X/B/C/D/E", "base-deleted", NO_COPY_FROM, "E3"},
+ {1, "E2", "normal", 2, "A/B/C/D/E", MOVED_HERE},
+ {1, "E3", "normal", 3, "C/D/E", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* An update with no text/property/tree changes in A, just a revision bump. */
+ SVN_ERR(sbox_wc_update(&b, "A", 4));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 4, "A"},
+ {0, "A/B", "normal", 4, "A/B"},
+ {0, "A/B/C", "normal", 4, "A/B/C"},
+ {0, "A/B/C/D", "normal", 4, "A/B/C/D"},
+ {0, "A/B/C/D/E", "normal", 4, "A/B/C/D/E"},
+ {0, "C", "normal", 3, "C"},
+ {0, "C/D", "normal", 3, "C/D"},
+ {0, "C/D/E", "normal", 3, "C/D/E"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "X"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C/D", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C/D/E", "base-deleted", NO_COPY_FROM},
+ {1, "C", "base-deleted", NO_COPY_FROM, "X/B/C"},
+ {1, "C/D", "base-deleted", NO_COPY_FROM},
+ {1, "C/D/E", "base-deleted", NO_COPY_FROM},
+ {1, "X", "normal", 4, "A", MOVED_HERE},
+ {1, "X/B", "normal", 4, "A/B", MOVED_HERE},
+ {1, "X/B/C", "normal", 4, "A/B/C", MOVED_HERE},
+ {1, "X/B/C/D", "normal", 4, "A/B/C/D", MOVED_HERE},
+ {1, "X/B/C/D/E", "normal", 4, "A/B/C/D/E", MOVED_HERE},
+ {3, "X/B/C", "normal", 3, "C", MOVED_HERE},
+ {3, "X/B/C/D", "normal", 3, "C/D", MOVED_HERE},
+ {3, "X/B/C/D/E", "normal", 3, "C/D/E", FALSE, "E2", TRUE},
+ {5, "X/B/C/D/E", "base-deleted", NO_COPY_FROM, "E3"},
+ {1, "E2", "normal", 4, "A/B/C/D/E", MOVED_HERE},
+ {1, "E3", "normal", 3, "C/D/E", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Update for conflicts on A and C */
+ SVN_ERR(sbox_wc_update(&b, "", 5));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 5, ""},
+ {0, "A", "normal", 5, "A"},
+ {0, "A/B", "normal", 5, "A/B"},
+ {0, "A/B/C", "normal", 5, "A/B/C"},
+ {0, "A/B/C/D", "normal", 5, "A/B/C/D"},
+ {0, "A/B/C/D/E", "normal", 5, "A/B/C/D/E"},
+ {0, "P", "normal", 5, "P"},
+ {0, "C", "normal", 5, "C"},
+ {0, "C/D", "normal", 5, "C/D"},
+ {0, "C/D/E", "normal", 5, "C/D/E"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "X"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C/D", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C/D/E", "base-deleted", NO_COPY_FROM},
+ {1, "C", "base-deleted", NO_COPY_FROM, "X/B/C"},
+ {1, "C/D", "base-deleted", NO_COPY_FROM},
+ {1, "C/D/E", "base-deleted", NO_COPY_FROM},
+ {1, "X", "normal", 4, "A", MOVED_HERE},
+ {1, "X/B", "normal", 4, "A/B", MOVED_HERE},
+ {1, "X/B/C", "normal", 4, "A/B/C", MOVED_HERE},
+ {1, "X/B/C/D", "normal", 4, "A/B/C/D", MOVED_HERE},
+ {1, "X/B/C/D/E", "normal", 4, "A/B/C/D/E", MOVED_HERE},
+ {3, "X/B/C", "normal", 3, "C", MOVED_HERE},
+ {3, "X/B/C/D", "normal", 3, "C/D", MOVED_HERE},
+ {3, "X/B/C/D/E", "normal", 3, "C/D/E", FALSE, "E2", TRUE},
+ {5, "X/B/C/D/E", "base-deleted", NO_COPY_FROM, "E3"},
+ {1, "E2", "normal", 4, "A/B/C/D/E", MOVED_HERE},
+ {1, "E3", "normal", 3, "C/D/E", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Partially resolve A */
+ SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(sbox_wc_resolve(&b, "X/B/C", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+
+ /* Cannot resolve C */
+ err = sbox_wc_resolve(&b, "C", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict);
+ SVN_TEST_ASSERT_ERROR(err, SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE);
+
+ /* Complete resolving A and then resolve C */
+ SVN_ERR(sbox_wc_resolve(&b, "X/B/C/D/E", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(sbox_wc_resolve(&b, "C", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 5, ""},
+ {0, "A", "normal", 5, "A"},
+ {0, "A/B", "normal", 5, "A/B"},
+ {0, "A/B/C", "normal", 5, "A/B/C"},
+ {0, "A/B/C/D", "normal", 5, "A/B/C/D"},
+ {0, "A/B/C/D/E", "normal", 5, "A/B/C/D/E"},
+ {0, "P", "normal", 5, "P"},
+ {0, "C", "normal", 5, "C"},
+ {0, "C/D", "normal", 5, "C/D"},
+ {0, "C/D/E", "normal", 5, "C/D/E"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "X"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C/D", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C/D/E", "base-deleted", NO_COPY_FROM},
+ {1, "C", "base-deleted", NO_COPY_FROM, "X/B/C"},
+ {1, "C/D", "base-deleted", NO_COPY_FROM},
+ {1, "C/D/E", "base-deleted", NO_COPY_FROM},
+ {1, "X", "normal", 5, "A", MOVED_HERE},
+ {1, "X/B", "normal", 5, "A/B", MOVED_HERE},
+ {1, "X/B/C", "normal", 5, "A/B/C", MOVED_HERE},
+ {1, "X/B/C/D", "normal", 5, "A/B/C/D", MOVED_HERE},
+ {1, "X/B/C/D/E", "normal", 5, "A/B/C/D/E", MOVED_HERE},
+ {3, "X/B/C", "normal", 5, "C", MOVED_HERE},
+ {3, "X/B/C/D", "normal", 5, "C/D", MOVED_HERE},
+ {3, "X/B/C/D/E", "normal", 5, "C/D/E", FALSE, "E2", TRUE},
+ {5, "X/B/C/D/E", "base-deleted", NO_COPY_FROM, "E3"},
+ {1, "E2", "normal", 5, "A/B/C/D/E", MOVED_HERE},
+ {1, "E3", "normal", 3, "C/D/E", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+update_within_move(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+ svn_error_t *err;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "update_within_move", opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C/D"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_move(&b, "A", "X"));
+ SVN_ERR(sbox_wc_update(&b, "A/B/C", 2));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/C", "normal", 2, "A/B/C"},
+ {0, "A/B/C/D", "normal", 2, "A/B/C/D"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "X"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C/D", "base-deleted", NO_COPY_FROM},
+ {1, "X", "normal", 1, "A", MOVED_HERE},
+ {1, "X/B", "normal", 1, "A/B", MOVED_HERE},
+ {1, "X/B/C", "normal", 1, "A/B/C", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Can't resolve mixed-revision source to mine-conflict. */
+ err = sbox_wc_resolve(&b, "A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict);
+ SVN_TEST_ASSERT_ERROR(err, SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE);
+
+ SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+ svn_wc_conflict_choose_merged));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/C", "normal", 2, "A/B/C"},
+ {0, "A/B/C/D", "normal", 2, "A/B/C/D"},
+ {1, "A", "base-deleted", NO_COPY_FROM},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C/D", "base-deleted", NO_COPY_FROM},
+ {1, "X", "normal", 1, "A"},
+ {1, "X/B", "normal", 1, "A/B"},
+ {1, "X/B/C", "normal", 1, "A/B/C"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+commit_moved_descendant(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+ SVN_ERR(svn_test__sandbox_create(&b, "commit_moved_descendant", 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, "A/A/A/A/A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/A/A/A/A/A"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_copy(&b, "A", "A_copied"));
+ SVN_ERR(sbox_wc_move(&b, "A/A/A", "AAA_moved"));
+ SVN_ERR(sbox_wc_delete(&b, "A/A"));
+ SVN_ERR(sbox_wc_copy(&b, "A_copied/A", "A/A"));
+
+ /* And now I want to commit AAA_moved (the entire move), but not
+ the replacement of A/A */
+
+ /* For now, just start committing directly */
+ /* ### This fails, because A/A/A is not collected by the commit
+ harvester (it doesn't need committing, but our move filter
+ blocks on it) */
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ /* It would be nicer if we could just do a: */
+ /* SVN_ERR(sbox_wc_commit(&b, "AAA_moved")); */
+ /* Which then includes the delete half of the move, when it is
+ shadowed, like in this case. The commit processing doesn't
+ support this yet though*/
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+commit_moved_away_descendant(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+ SVN_ERR(svn_test__sandbox_create(&b, "commit_moved_away_descendant",
+ 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, "A/A/A/A/A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/A/A/A/A/A"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_copy(&b, "A", "A_copied"));
+ SVN_ERR(sbox_wc_move(&b, "A/A/A", "AAA_moved"));
+ SVN_ERR(sbox_wc_delete(&b, "A/A"));
+ SVN_ERR(sbox_wc_copy(&b, "A_copied/A", "A/A"));
+
+ /* And now I want to make sure that I can't commit A, without also
+ committing AAA_moved, as that would break the move*/
+ SVN_ERR(sbox_wc_commit(&b, "A"));
+
+ return svn_error_create(SVN_ERR_TEST_FAILED, NULL,
+ "The commit should have failed");
+
+ /*return SVN_NO_ERROR;*/
+}
+
+static svn_error_t *
+finite_move_update_bump(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+ svn_error_t *err;
+ SVN_ERR(svn_test__sandbox_create(&b, "finite_move_update_bump",
+ opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_mkdir(&b, "P"));
+ SVN_ERR(sbox_wc_mkdir(&b, "P/Q"));
+ sbox_file_write(&b, "P/Q/f", "r1 content\n");
+ SVN_ERR(sbox_wc_add(&b, "P/Q/f"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "X"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_move(&b, "A/B", "B2"));
+ SVN_ERR(sbox_wc_update(&b, "A/B/C", 2));
+ SVN_ERR(check_tree_conflict_repos_path(&b, "A/B", NULL, NULL));
+ err = sbox_wc_resolve(&b, "A/B", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict);
+ SVN_TEST_ASSERT_ERROR(err, SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE);
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/C", "normal", 2, "A/B/C"},
+ {0, "P", "normal", 1, "P"},
+ {0, "P/Q", "normal", 1, "P/Q"},
+ {0, "P/Q/f", "normal", 1, "P/Q/f"},
+ {2, "A/B", "base-deleted", NO_COPY_FROM, "B2"},
+ {2, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {1, "B2", "normal", 1, "A/B", MOVED_HERE},
+ {1, "B2/C", "normal", 1, "A/B/C", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_revert(&b, "", svn_depth_infinity));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_move(&b, "A/B", "B2"));
+ SVN_ERR(sbox_wc_move(&b, "P/Q", "Q2"));
+ SVN_ERR(sbox_wc_update_depth(&b, "A/B", 2, svn_depth_files, FALSE));
+ SVN_ERR(sbox_wc_update_depth(&b, "P/Q", 2, svn_depth_files, FALSE));
+ SVN_ERR(check_tree_conflict_repos_path(&b, "A/B", NULL, NULL));
+ err = sbox_wc_resolve(&b, "A/B", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict);
+ SVN_TEST_ASSERT_ERROR(err, SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE);
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
+ {0, "P", "normal", 1, "P"},
+ {0, "P/Q", "normal", 2, "P/Q"},
+ {0, "P/Q/f", "normal", 2, "P/Q/f"},
+ {2, "A/B", "base-deleted", NO_COPY_FROM, "B2"},
+ {2, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {2, "P/Q", "base-deleted", NO_COPY_FROM, "Q2"},
+ {2, "P/Q/f", "base-deleted", NO_COPY_FROM},
+ {1, "B2", "normal", 1, "A/B", MOVED_HERE},
+ {1, "B2/C", "normal", 1, "A/B/C", MOVED_HERE},
+ {1, "Q2", "normal", 2, "P/Q", MOVED_HERE},
+ {1, "Q2/f", "normal", 2, "P/Q/f", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_revert(&b, "", svn_depth_infinity));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_move(&b, "A/B", "B2"));
+ SVN_ERR(sbox_wc_move(&b, "P", "P2"));
+ SVN_ERR(sbox_wc_update_depth(&b, "A/B", 2, svn_depth_immediates, FALSE));
+ SVN_ERR(sbox_wc_update_depth(&b, "P", 2, svn_depth_immediates, FALSE));
+ SVN_ERR(check_tree_conflict_repos_path(&b, "P", NULL, NULL));
+ err = sbox_wc_resolve(&b, "P", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict);
+ SVN_TEST_ASSERT_ERROR(err, SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE);
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "A/B/C", "normal", 2, "A/B/C"},
+ {0, "P", "normal", 2, "P"},
+ {0, "P/Q", "normal", 2, "P/Q"},
+ {0, "P/Q/f", "normal", 1, "P/Q/f"},
+ {2, "A/B", "base-deleted", NO_COPY_FROM, "B2"},
+ {2, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {1, "P", "base-deleted", NO_COPY_FROM, "P2"},
+ {1, "P/Q", "base-deleted", NO_COPY_FROM},
+ {1, "P/Q/f", "base-deleted", NO_COPY_FROM},
+ {1, "B2", "normal", 2, "A/B", MOVED_HERE},
+ {1, "B2/C", "normal", 2, "A/B/C", MOVED_HERE},
+ {1, "P2", "normal", 1, "P", MOVED_HERE},
+ {1, "P2/Q", "normal", 1, "P/Q", MOVED_HERE},
+ {1, "P2/Q/f", "normal", 1, "P/Q/f", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_revert(&b, "", svn_depth_infinity));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_move(&b, "A/B/C", "C2"));
+ SVN_ERR(sbox_wc_move(&b, "P/Q", "Q2"));
+ SVN_ERR(sbox_wc_update_depth(&b, "A/B/C", 2, svn_depth_empty, FALSE));
+ SVN_ERR(sbox_wc_update_depth(&b, "P/Q", 2, svn_depth_empty, FALSE));
+ SVN_ERR(check_tree_conflict_repos_path(&b, "P/Q", NULL, NULL));
+ err = sbox_wc_resolve(&b, "P/Q", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict);
+ SVN_TEST_ASSERT_ERROR(err, SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE);
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/C", "normal", 2, "A/B/C"},
+ {0, "P", "normal", 1, "P"},
+ {0, "P/Q", "normal", 2, "P/Q"},
+ {0, "P/Q/f", "normal", 1, "P/Q/f"},
+ {3, "A/B/C", "base-deleted", NO_COPY_FROM, "C2"},
+ {2, "P/Q", "base-deleted", NO_COPY_FROM, "Q2"},
+ {2, "P/Q/f", "base-deleted", NO_COPY_FROM},
+ {1, "C2", "normal", 2, "A/B/C", MOVED_HERE},
+ {1, "Q2", "normal", 1, "P/Q", MOVED_HERE},
+ {1, "Q2/f", "normal", 1, "P/Q/f", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_away_delete_update(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+ SVN_ERR(svn_test__sandbox_create(&b, "move_away_delete_update",
+ opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_mkdir(&b, "P"));
+ SVN_ERR(sbox_wc_mkdir(&b, "P/Q"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_delete(&b, "A/B"));
+ SVN_ERR(sbox_wc_delete(&b, "P/Q"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_move(&b, "A/B/C", "C2"));
+ SVN_ERR(sbox_wc_move(&b, "P/Q", "Q2"));
+
+ /* Update to r2 removes the move sources and clears moved_here from
+ the move destinations. */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 2, ""},
+ {0, "A", "normal", 2, "A"},
+ {0, "P", "normal", 2, "P"},
+ {1, "C2", "normal", 1, "A/B/C"},
+ {1, "Q2", "normal", 1, "P/Q"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_not_present_variants(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+ SVN_ERR(svn_test__sandbox_create(&b, "move_not_present_variants",
+ opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "B/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "C"));
+ SVN_ERR(sbox_wc_mkdir(&b, "C/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "D"));
+ SVN_ERR(sbox_wc_mkdir(&b, "D/B"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_delete(&b, "A/B"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ SVN_ERR(sbox_wc_delete(&b, "B/B"));
+ SVN_ERR(sbox_wc_update(&b, "C/B", 0));
+ SVN_ERR(sbox_wc_exclude(&b, "D/B"));
+
+ SVN_ERR(sbox_wc_copy(&b, "A", "cA"));
+ SVN_ERR(sbox_wc_copy(&b, "B", "cB"));
+ SVN_ERR(sbox_wc_copy(&b, "C", "cC"));
+ SVN_ERR(sbox_wc_copy(&b, "D", "cD"));
+
+ SVN_ERR(sbox_wc_copy(&b, "cA", "ccA"));
+ SVN_ERR(sbox_wc_copy(&b, "cB", "ccB"));
+ SVN_ERR(sbox_wc_copy(&b, "cC", "ccC"));
+ SVN_ERR(sbox_wc_copy(&b, "cD", "ccD"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+
+ /* Copy of a deleted + committed node */
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "not-present", 2, "A/B"},
+
+ {1, "cA", "normal", 1, "A"},
+ {1, "cA/B", "not-present", 2, "A/B"},
+
+ {1, "ccA", "normal", 1, "A"},
+ {1, "ccA/B", "not-present", 2, "A/B"},
+
+ /* Copy of a local deleted node */
+ {0, "B", "normal", 1, "B"},
+ {0, "B/B", "normal", 1, "B/B"},
+ {2, "B/B", "base-deleted", NO_COPY_FROM},
+
+ {1, "cB", "normal", 1, "B",},
+ {1, "cB/B", "normal", 1, "B/B"},
+ {2, "cB/B", "base-deleted", NO_COPY_FROM},
+
+ {1, "ccB", "normal", 1, "B"},
+ {1, "ccB/B", "normal", 1, "B/B"},
+ {2, "ccB/B", "base-deleted", NO_COPY_FROM},
+
+ /* Copy of a to r0 updated node */
+ {0, "C", "normal", 1, "C"},
+ {0, "C/B", "not-present", 0, "C/B"},
+
+ {1, "cC", "normal", 1, "C"},
+ {1, "cC/B", "not-present", 0, "C/B"},
+
+ {1, "ccC", "normal", 1, "C"},
+ {1, "ccC/B", "not-present", 0, "C/B"},
+
+ /* Copy of an excluded node */
+ {0, "D", "normal", 1, "D"},
+ {0, "D/B", "excluded", 1, "D/B"},
+
+ {1, "cD", "normal", 1, "D"},
+ {1, "cD/B", "excluded", 1, "D/B"},
+
+ {1, "ccD", "normal", 1, "D"},
+ {1, "ccD/B", "excluded", 1, "D/B"},
+
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_revert(&b, "", svn_depth_infinity));
+ SVN_ERR(sbox_wc_delete(&b, "B/B"));
+
+ /* And now do the same thing with moves */
+
+ SVN_ERR(sbox_wc_move(&b, "A", "mA"));
+ SVN_ERR(sbox_wc_move(&b, "B", "mB"));
+ SVN_ERR(sbox_wc_move(&b, "C", "mC"));
+ SVN_ERR(sbox_wc_move(&b, "D", "mD"));
+
+ SVN_ERR(sbox_wc_move(&b, "mA", "mmA"));
+ SVN_ERR(sbox_wc_move(&b, "mB", "mmB"));
+ SVN_ERR(sbox_wc_move(&b, "mC", "mmC"));
+ SVN_ERR(sbox_wc_move(&b, "mD", "mmD"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+
+ /* Move of a deleted + committed node */
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "not-present", 2, "A/B"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "mmA"},
+
+ {1, "mmA", "normal", 1, "A", MOVED_HERE},
+ {1, "mmA/B", "not-present", 2, "A/B", MOVED_HERE},
+
+
+ /* Move of a local deleted node */
+ {0, "B", "normal", 1, "B"},
+ {0, "B/B", "normal", 1, "B/B"},
+ {1, "B", "base-deleted", NO_COPY_FROM, "mmB"},
+ {1, "B/B", "base-deleted", NO_COPY_FROM},
+
+ {1, "mmB", "normal", 1, "B", MOVED_HERE},
+ {1, "mmB/B", "normal", 1, "B/B", MOVED_HERE},
+ {2, "mmB/B", "base-deleted", NO_COPY_FROM},
+
+ /* Move of a to r0 updated node */
+ {0, "C", "normal", 1, "C"},
+ {0, "C/B", "not-present", 0, "C/B"},
+ {1, "C", "base-deleted", NO_COPY_FROM, "mmC"},
+
+ {1, "mmC", "normal", 1, "C", MOVED_HERE},
+ {1, "mmC/B", "not-present", 0, "C/B", MOVED_HERE},
+
+ /* Move of an excluded node */
+ {0, "D", "normal", 1, "D",},
+ {0, "D/B", "excluded", 1, "D/B", },
+ {1, "D", "base-deleted", NO_COPY_FROM, "mmD"},
+
+ {1, "mmD", "normal", 1, "D", MOVED_HERE},
+ {1, "mmD/B", "excluded", 1, "D/B", MOVED_HERE},
+
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* And move everything back */
+ SVN_ERR(sbox_wc_move(&b, "mmA", "A"));
+ SVN_ERR(sbox_wc_move(&b, "mmB", "B"));
+ SVN_ERR(sbox_wc_move(&b, "mmC", "C"));
+ SVN_ERR(sbox_wc_move(&b, "mmD", "D"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+
+ /* deleted + committed node */
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "not-present", 2, "A/B"},
+
+ /* local deleted node */
+ {0, "B", "normal", 1, "B"},
+ {0, "B/B", "normal", 1, "B/B"},
+ {2, "B/B", "base-deleted", NO_COPY_FROM},
+
+ /* To r0 updated node */
+ {0, "C", "normal", 1, "C"},
+ {0, "C/B", "not-present", 0, "C/B"},
+
+ /* Move of an excluded node */
+ {0, "D", "normal", 1, "D",},
+ {0, "D/B", "excluded", 1, "D/B", },
+
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+update_child_under_add(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+ svn_error_t *err;
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "not-present", 0, "A/B"},
+ {2, "A/B", "normal", NO_COPY_FROM},
+ {3, "A/B/C", "normal", NO_COPY_FROM},
+ {4, "A/B/C/D", "normal", NO_COPY_FROM},
+ {0}
+ };
+
+ SVN_ERR(svn_test__sandbox_create(&b, "update_child_under_add",
+ opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C/D"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_update(&b, "A/B", 0));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C/D"));
+ SVN_ERR(check_db_rows(&b, "", nodes));
+
+ /* A/B/C/D is skipped as it has no base node parent */
+ SVN_ERR(sbox_wc_update(&b, "A/B/C/D", 1));
+ SVN_ERR(check_db_rows(&b, "", nodes));
+
+ /* A/B/C should be skipped as it has a not-present base node parent */
+ err = sbox_wc_update(&b, "A/B/C", 1);
+ svn_error_clear(err); /* Allow any error and always check NODES. */
+ SVN_ERR(check_db_rows(&b, "", nodes));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+delete_over_moved_away(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "delete_over_moved_away",
+ opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_move(&b, "A/B", "B"));
+ SVN_ERR(sbox_wc_delete(&b, "A"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+
+ {0, "A", "normal", 1, "A"},
+ {1, "A", "base-deleted", NO_COPY_FROM},
+ {0, "A/B", "normal", 1, "A/B"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM, "B"},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
+ {1, "A/B/C", "base-deleted", NO_COPY_FROM},
+
+ {1, "B", "normal", 1, "A/B", MOVED_HERE},
+ {1, "B/C", "normal", 1, "A/B/C", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Now replace A with a similar tree */
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+
+ {0, "A", "normal", 1, "A"},
+ {1, "A", "normal", NO_COPY_FROM},
+ {0, "A/B", "normal", 1, "A/B"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM, "B"},
+ {2, "A/B", "normal", NO_COPY_FROM},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
+ {1, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {3, "A/B/C", "normal", NO_COPY_FROM},
+
+ {1, "B", "normal", 1, "A/B", MOVED_HERE},
+ {1, "B/C", "normal", 1, "A/B/C", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* And delete the new A */
+ SVN_ERR(sbox_wc_delete(&b, "A"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+
+ {0, "A", "normal", 1, "A"},
+ {1, "A", "base-deleted", NO_COPY_FROM},
+ {0, "A/B", "normal", 1, "A/B"},
+ /* And here the moved-to information is lost */
+ {1, "A/B", "base-deleted", NO_COPY_FROM, "B"},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
+ {1, "A/B/C", "base-deleted", NO_COPY_FROM},
+
+ /* But the moved-here is still there */
+ {1, "B", "normal", 1, "A/B", MOVED_HERE},
+ {1, "B/C", "normal", 1, "A/B/C", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+movedto_opdepth(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "moved_to_op_depth",
+ opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_move(&b, "A/B/C", "C"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
+ {3, "A/B/C", "base-deleted", NO_COPY_FROM, "C"},
+
+ {1, "C", "normal", 1, "A/B/C", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* And now the moved_to information has to switch op-depths */
+ SVN_ERR(sbox_wc_delete(&b, "A/B"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
+
+ {2, "A/B", "base-deleted", NO_COPY_FROM},
+ {2, "A/B/C", "base-deleted", NO_COPY_FROM, "C"},
+
+ {1, "C", "normal", 1, "A/B/C", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* And again */
+ SVN_ERR(sbox_wc_delete(&b, "A"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+
+ {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/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C", "base-deleted", NO_COPY_FROM, "C"},
+
+ {1, "C", "normal", 1, "A/B/C", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* And now stay at the depth of A */
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
+
+ {1, "A", "normal", NO_COPY_FROM},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C", "base-deleted", NO_COPY_FROM, "C"},
+
+ {2, "A/B", "normal", NO_COPY_FROM},
+
+ {1, "C", "normal", 1, "A/B/C", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* And see if it can jump back to B again? */
+ SVN_ERR(sbox_wc_delete(&b, "A"));
+ SVN_ERR(sbox_wc_revert(&b, "A", svn_depth_empty));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
+
+ {2, "A/B", "base-deleted", NO_COPY_FROM},
+ {2, "A/B/C", "base-deleted", NO_COPY_FROM, "C"},
+
+ {1, "C", "normal", 1, "A/B/C", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* And can we bump it back to C itself? */
+ SVN_ERR(sbox_wc_revert(&b, "A", svn_depth_immediates));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
+
+ {3, "A/B/C", "base-deleted", NO_COPY_FROM, "C"},
+
+ {1, "C", "normal", 1, "A/B/C", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+new_basemove(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "new_basemove",
+ opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ /* We keep track of moved children of copies */
+ SVN_ERR(sbox_wc_copy(&b, "A", "Copy"));
+ SVN_ERR(sbox_wc_move(&b, "Copy/B/C", "C"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
+
+ {1, "Copy", "normal", 1, "A"},
+ {1, "Copy/B", "normal", 1, "A/B"},
+ {1, "Copy/B/C", "normal", 1, "A/B/C"},
+
+ {3, "Copy/B/C", "base-deleted", NO_COPY_FROM, "C"},
+
+ /* C is a copy of A/B/C */
+ {1, "C", "normal", 1, "A/B/C", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ {
+ apr_array_header_t *targets = apr_array_make(pool, 1, sizeof(char *));
+ APR_ARRAY_PUSH(targets, const char*) = sbox_wc_path(&b, "Copy");
+
+ SVN_ERR(sbox_wc_commit_ex(&b, targets, svn_depth_empty));
+ }
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/C", "normal", 1, "A/B/C"},
+
+ {0, "Copy", "normal", 2, "Copy"},
+ {0, "Copy/B", "normal", 2, "Copy/B"},
+ {0, "Copy/B/C", "normal", 2, "Copy/B/C"},
+
+ {3, "Copy/B/C", "base-deleted", NO_COPY_FROM, "C"},
+
+ /* And this node is now a copy of Copy/B/C at r2 */
+ {1, "C", "normal", 2, "Copy/B/C", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_back(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_back", opts, pool));
+
+ /* X just so we don't always test with local_relpath == repos_path */
+ SVN_ERR(sbox_wc_mkdir(&b, "X"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X/A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X/A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X/A/B/C"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X/A/B/D"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X/E"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_switch(&b, "", "/X", svn_depth_infinity));
+
+ SVN_ERR(sbox_wc_move(&b, "A/B", "A/B2"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, "X"},
+ {0, "A", "normal", 1, "X/A"},
+ {0, "A/B", "normal", 1, "X/A/B"},
+ {0, "A/B/C", "normal", 1, "X/A/B/C"},
+ {0, "A/B/D", "normal", 1, "X/A/B/D"},
+ {0, "E", "normal", 1, "X/E"},
+ {2, "A/B", "base-deleted", NO_COPY_FROM, "A/B2"},
+ {2, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {2, "A/B/D", "base-deleted", NO_COPY_FROM},
+ {2, "A/B2", "normal", 1, "X/A/B", MOVED_HERE},
+ {2, "A/B2/C", "normal", 1, "X/A/B/C", MOVED_HERE},
+ {2, "A/B2/D", "normal", 1, "X/A/B/D", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+ SVN_ERR(sbox_wc_move(&b, "A/B2", "A/B"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, "X"},
+ {0, "A", "normal", 1, "X/A"},
+ {0, "A/B", "normal", 1, "X/A/B"},
+ {0, "A/B/C", "normal", 1, "X/A/B/C"},
+ {0, "A/B/D", "normal", 1, "X/A/B/D"},
+ {0, "E", "normal", 1, "X/E"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_move(&b, "A/B", "A/B2"));
+ SVN_ERR(sbox_wc_move(&b, "A/B2/C", "A/B2/C2"));
+ SVN_ERR(sbox_wc_move(&b, "A/B2/D", "D2"));
+ SVN_ERR(sbox_wc_move(&b, "E", "A/B2/E2"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, "X"},
+ {0, "A", "normal", 1, "X/A"},
+ {0, "A/B", "normal", 1, "X/A/B"},
+ {0, "A/B/C", "normal", 1, "X/A/B/C"},
+ {0, "A/B/D", "normal", 1, "X/A/B/D"},
+ {0, "E", "normal", 1, "X/E"},
+ {1, "D2", "normal", 1, "X/A/B/D", MOVED_HERE},
+ {1, "E", "base-deleted", NO_COPY_FROM, "A/B2/E2"},
+ {2, "A/B", "base-deleted", NO_COPY_FROM, "A/B2"},
+ {2, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {2, "A/B/D", "base-deleted", NO_COPY_FROM},
+ {2, "A/B2", "normal", 1, "X/A/B", MOVED_HERE},
+ {2, "A/B2/C", "normal", 1, "X/A/B/C", MOVED_HERE},
+ {2, "A/B2/D", "normal", 1, "X/A/B/D", MOVED_HERE},
+ {3, "A/B2/C", "base-deleted", NO_COPY_FROM, "A/B2/C2"},
+ {3, "A/B2/D", "base-deleted", NO_COPY_FROM, "D2"},
+ {3, "A/B2/C2", "normal", 1, "X/A/B/C", MOVED_HERE},
+ {3, "A/B2/E2", "normal", 1, "X/E", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+ SVN_ERR(sbox_wc_move(&b, "A/B2", "A/B"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, "X"},
+ {0, "A", "normal", 1, "X/A"},
+ {0, "A/B", "normal", 1, "X/A/B"},
+ {0, "A/B/C", "normal", 1, "X/A/B/C"},
+ {0, "A/B/D", "normal", 1, "X/A/B/D"},
+ {0, "E", "normal", 1, "X/E"},
+ {1, "D2", "normal", 1, "X/A/B/D", MOVED_HERE},
+ {1, "E", "base-deleted", NO_COPY_FROM, "A/B/E2"},
+ {3, "A/B/C", "base-deleted", NO_COPY_FROM, "A/B/C2"},
+ {3, "A/B/D", "base-deleted", NO_COPY_FROM, "D2"},
+ {3, "A/B/C2", "normal", 1, "X/A/B/C", MOVED_HERE},
+ {3, "A/B/E2", "normal", 1, "X/E", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_update_subtree(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+ svn_error_t *err;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_update_subtree", opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C/D"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "X"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 3));
+ SVN_ERR(sbox_wc_copy(&b, "A", "P"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ /* Subtree update is like an interrupted update, it leaves a
+ mixed-revision move source. */
+ SVN_ERR(sbox_wc_move(&b, "A/B", "A/B2"));
+ SVN_ERR(sbox_wc_update(&b, "A/B/C", 2));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/C", "normal", 2, "A/B/C"},
+ {0, "A/B/C/D", "normal", 2, "A/B/C/D"},
+ {2, "A/B", "base-deleted", NO_COPY_FROM, "A/B2"},
+ {2, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {2, "A/B/C/D", "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},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Resolve fails because of the mixed-revision. */
+ err = sbox_wc_resolve(&b, "A/B", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict);
+ SVN_TEST_ASSERT_ERROR(err, SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE);
+
+ /* Update to single-revision to allow resolve; this requires update
+ while the tree-conflict on A/B is present. */
+ SVN_ERR(sbox_wc_update(&b, "A/B", 2));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "A/B/C", "normal", 2, "A/B/C"},
+ {0, "A/B/C/D", "normal", 2, "A/B/C/D"},
+ {2, "A/B", "base-deleted", NO_COPY_FROM, "A/B2"},
+ {2, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {2, "A/B/C/D", "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},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Now resolve is possible. */
+ SVN_ERR(sbox_wc_resolve(&b, "A/B", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "A/B/C", "normal", 2, "A/B/C"},
+ {0, "A/B/C/D", "normal", 2, "A/B/C/D"},
+ {2, "A/B", "base-deleted", NO_COPY_FROM, "A/B2"},
+ {2, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {2, "A/B/C/D", "base-deleted", NO_COPY_FROM},
+ {2, "A/B2", "normal", 2, "A/B", MOVED_HERE},
+ {2, "A/B2/C", "normal", 2, "A/B/C", MOVED_HERE},
+ {2, "A/B2/C/D", "normal", 2, "A/B/C/D", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Subtree update that only bumps. */
+ SVN_ERR(sbox_wc_update(&b, "A/B/C", 3));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "A/B/C", "normal", 3, "A/B/C"},
+ {0, "A/B/C/D", "normal", 3, "A/B/C/D"},
+ {2, "A/B", "base-deleted", NO_COPY_FROM, "A/B2"},
+ {2, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {2, "A/B/C/D", "base-deleted", NO_COPY_FROM},
+ {2, "A/B2", "normal", 2, "A/B", MOVED_HERE},
+ {2, "A/B2/C", "normal", 2, "A/B/C", MOVED_HERE},
+ {2, "A/B2/C/D", "normal", 2, "A/B/C/D", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Resolve fails because of the mixed-revision. */
+ err = sbox_wc_resolve(&b, "A/B", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict);
+ SVN_TEST_ASSERT_ERROR(err, SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE);
+
+ /* Update allowed while tree-conflict is present. */
+ SVN_ERR(sbox_wc_update(&b, "A/B", 3));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 3, "A/B"},
+ {0, "A/B/C", "normal", 3, "A/B/C"},
+ {0, "A/B/C/D", "normal", 3, "A/B/C/D"},
+ {2, "A/B", "base-deleted", NO_COPY_FROM, "A/B2"},
+ {2, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {2, "A/B/C/D", "base-deleted", NO_COPY_FROM},
+ {2, "A/B2", "normal", 2, "A/B", MOVED_HERE},
+ {2, "A/B2/C", "normal", 2, "A/B/C", MOVED_HERE},
+ {2, "A/B2/C/D", "normal", 2, "A/B/C/D", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Now resolve works. */
+ SVN_ERR(sbox_wc_resolve(&b, "A/B", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 3, "A/B"},
+ {0, "A/B/C", "normal", 3, "A/B/C"},
+ {0, "A/B/C/D", "normal", 3, "A/B/C/D"},
+ {2, "A/B", "base-deleted", NO_COPY_FROM, "A/B2"},
+ {2, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {2, "A/B/C/D", "base-deleted", NO_COPY_FROM},
+ {2, "A/B2", "normal", 3, "A/B", MOVED_HERE},
+ {2, "A/B2/C", "normal", 3, "A/B/C", MOVED_HERE},
+ {2, "A/B2/C/D", "normal", 3, "A/B/C/D", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Partial switch of source. */
+ SVN_ERR(sbox_wc_switch(&b, "A", "/P", svn_depth_immediates));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 4, "P"},
+ {0, "A/B", "normal", 4, "P/B"},
+ {0, "A/B/C", "normal", 3, "A/B/C"},
+ {0, "A/B/C/D", "normal", 3, "A/B/C/D"},
+ {2, "A/B", "base-deleted", NO_COPY_FROM, "A/B2"},
+ {2, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {2, "A/B/C/D", "base-deleted", NO_COPY_FROM},
+ {2, "A/B2", "normal", 3, "A/B", MOVED_HERE},
+ {2, "A/B2/C", "normal", 3, "A/B/C", MOVED_HERE},
+ {2, "A/B2/C/D", "normal", 3, "A/B/C/D", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Resolve fails because of the subtree-switch. */
+ err = sbox_wc_resolve(&b, "A/B", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict);
+ SVN_TEST_ASSERT_ERROR(err, SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE);
+
+ /* Switch works while tree-conflict is present. */
+ SVN_ERR(sbox_wc_switch(&b, "A", "/P", svn_depth_infinity));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 4, "P"},
+ {0, "A/B", "normal", 4, "P/B"},
+ {0, "A/B/C", "normal", 4, "P/B/C"},
+ {0, "A/B/C/D", "normal", 4, "P/B/C/D"},
+ {2, "A/B", "base-deleted", NO_COPY_FROM, "A/B2"},
+ {2, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {2, "A/B/C/D", "base-deleted", NO_COPY_FROM},
+ {2, "A/B2", "normal", 3, "A/B", MOVED_HERE},
+ {2, "A/B2/C", "normal", 3, "A/B/C", MOVED_HERE},
+ {2, "A/B2/C/D", "normal", 3, "A/B/C/D", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Now resolve works. */
+ SVN_ERR(sbox_wc_resolve(&b, "A/B", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 4, "P"},
+ {0, "A/B", "normal", 4, "P/B"},
+ {0, "A/B/C", "normal", 4, "P/B/C"},
+ {0, "A/B/C/D", "normal", 4, "P/B/C/D"},
+ {2, "A/B", "base-deleted", NO_COPY_FROM, "A/B2"},
+ {2, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {2, "A/B/C/D", "base-deleted", NO_COPY_FROM},
+ {2, "A/B2", "normal", 4, "P/B", MOVED_HERE},
+ {2, "A/B2/C", "normal", 4, "P/B/C", MOVED_HERE},
+ {2, "A/B2/C/D", "normal", 4, "P/B/C/D", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_parent_into_child(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_parent_into_child", opts, pool));
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_move(&b, "A/B", "B2"));
+ SVN_ERR(sbox_wc_move(&b, "A", "B2/A"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "B2/A"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "B2", "normal", 1, "A/B", MOVED_HERE},
+ {2, "B2/A", "normal", 1, "A", MOVED_HERE},
+ {2, "B2/A/B", "normal", 1, "A/B", MOVED_HERE},
+ {3, "B2/A/B", "base-deleted", NO_COPY_FROM, "B2"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_move(&b, "B2", "A"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {1, "A", "normal", 1, "A/B", FALSE, "A/A", TRUE},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {2, "A/A", "normal", 1, "A", MOVED_HERE},
+ {2, "A/A/B", "normal", 1, "A/B", MOVED_HERE},
+ {3, "A/A/B", "base-deleted", NO_COPY_FROM, "A"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_move(&b, "A/A", "A/B"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {1, "A", "normal", 1, "A/B", FALSE, "A/B", TRUE},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {2, "A/B", "normal", 1, "A", MOVED_HERE},
+ {2, "A/B/B", "normal", 1, "A/B", MOVED_HERE},
+ {3, "A/B/B", "base-deleted", NO_COPY_FROM, "A"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_depth_expand(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_depth_expand", 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, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/A/A"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 0));
+
+ SVN_ERR(sbox_wc_update_depth(&b, "", 1, svn_depth_immediates, TRUE));
+ SVN_ERR(sbox_wc_update_depth(&b, "A", 1, svn_depth_immediates, TRUE));
+ /* Make A/B not present */
+ SVN_ERR(sbox_wc_update_depth(&b, "A/B", 0, svn_depth_immediates, TRUE));
+
+ SVN_ERR(sbox_wc_move(&b, "A", "C"));
+ SVN_ERR(sbox_wc_mkdir(&b, "C/A/A")); /* Local addition obstruction */
+ SVN_ERR(sbox_wc_copy(&b, "C/A", "C/B")); /* Copied obstruction */
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, "" },
+
+ {0, "A", "normal", 1, "A" },
+ {1, "A", "base-deleted", NO_COPY_FROM, "C" },
+ {0, "A/A", "normal", 1, "A/A" },
+ {1, "A/A", "base-deleted", NO_COPY_FROM },
+ {0, "A/B", "not-present", 0, "A/B" },
+
+ {1, "C", "normal", 1, "A", MOVED_HERE },
+
+ {1, "C/A", "normal", 1, "A/A", MOVED_HERE },
+ {3, "C/A/A", "normal", NO_COPY_FROM },
+
+ {1, "C/B", "not-present", 0, "A/B", MOVED_HERE},
+ {2, "C/B", "normal", 1, "A/A" },
+ {3, "C/B/A", "normal", NO_COPY_FROM },
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_update_depth(&b, "", 1, svn_depth_infinity, TRUE));
+
+ /* This used to cause a segfault. Then it asserted in a different place */
+ SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+
+ /* And now verify that there are no not-present nodes left and a
+ consistent working copy */
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, "" },
+
+ {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, "A/B", "normal", 1, "A/B" },
+ {0, "A/B/A", "normal", 1, "A/B/A" },
+ {0, "A/B/A/A", "normal", 1, "A/B/A/A" },
+
+ {1, "A", "base-deleted", NO_COPY_FROM, "C" },
+ {1, "A/A", "base-deleted", NO_COPY_FROM },
+ {1, "A/A/A", "base-deleted", NO_COPY_FROM },
+ {1, "A/B", "base-deleted", NO_COPY_FROM },
+ {1, "A/B/A", "base-deleted", NO_COPY_FROM },
+ {1, "A/B/A/A", "base-deleted", NO_COPY_FROM },
+ {1, "A/A/A/A", "base-deleted", NO_COPY_FROM },
+
+
+ {1, "C", "normal", 1, "A", MOVED_HERE },
+ {1, "C/A", "normal", 1, "A/A", MOVED_HERE },
+ {1, "C/A/A", "normal", 1, "A/A/A", MOVED_HERE },
+ {1, "C/A/A/A", "normal", 1, "A/A/A/A", MOVED_HERE },
+
+ {3, "C/A/A", "normal", NO_COPY_FROM },
+ {3, "C/A/A/A", "base-deleted", NO_COPY_FROM },
+
+ {1, "C/B", "normal", 1, "A/B", MOVED_HERE },
+ {1, "C/B/A", "normal", 1, "A/B/A", MOVED_HERE },
+ {1, "C/B/A/A", "normal", 1, "A/B/A/A", MOVED_HERE },
+
+ {2, "C/B", "normal", 1, "A/A" },
+ {2, "C/B/A", "base-deleted", NO_COPY_FROM },
+ {2, "C/B/A/A", "base-deleted", NO_COPY_FROM },
+
+ {3, "C/B/A", "normal", NO_COPY_FROM },
+
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_retract(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_retract", 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, "A/A/A/C"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/A/A/D"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/A/A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/A/C"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/A/D"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_delete(&b, "A/A/A/A"));
+ SVN_ERR(sbox_wc_delete(&b, "A/A/A/C"));
+ SVN_ERR(sbox_wc_delete(&b, "A/A/A/D"));
+ SVN_ERR(sbox_wc_delete(&b, "A/B/A/C"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_move(&b, "A/B/A/D", "D"));
+ SVN_ERR(sbox_wc_delete(&b, "A/B"));
+ SVN_ERR(sbox_wc_move(&b, "A/A", "A/B"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, "" },
+
+ {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, "A/A/A/C", "normal", 1, "A/A/A/C" },
+ {0, "A/A/A/D", "normal", 1, "A/A/A/D" },
+
+ {2, "A/A", "base-deleted", NO_COPY_FROM, "A/B"},
+ {2, "A/A/A", "base-deleted", NO_COPY_FROM },
+ {2, "A/A/A/A", "base-deleted", NO_COPY_FROM },
+ {2, "A/A/A/C", "base-deleted", NO_COPY_FROM },
+ {2, "A/A/A/D", "base-deleted", NO_COPY_FROM },
+
+ {0, "A/B", "normal", 1, "A/B" },
+ {0, "A/B/A", "normal", 1, "A/B/A" },
+ {0, "A/B/A/A", "normal", 1, "A/B/A/A" },
+ {0, "A/B/A/C", "normal", 1, "A/B/A/C" },
+ {0, "A/B/A/D", "normal", 1, "A/B/A/D" },
+
+ {2, "A/B", "normal", 1, "A/A", MOVED_HERE },
+ {2, "A/B/A", "normal", 1, "A/A/A", MOVED_HERE },
+ {2, "A/B/A/A", "normal", 1, "A/A/A/A", MOVED_HERE },
+ {2, "A/B/A/C", "normal", 1, "A/A/A/C", MOVED_HERE },
+ {2, "A/B/A/D", "normal", 1, "A/A/A/D", FALSE, "D", TRUE },
+
+ {1, "D", "normal", 1, "A/B/A/D", MOVED_HERE },
+
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 2, "" },
+
+ {0, "A", "normal", 2, "A" },
+ {0, "A/A", "normal", 2, "A/A" },
+ {0, "A/A/A", "normal", 2, "A/A/A" },
+
+ {2, "A/A", "base-deleted", NO_COPY_FROM, "A/B"},
+ {2, "A/A/A", "base-deleted", NO_COPY_FROM },
+
+ {0, "A/B", "normal", 2, "A/B" },
+ {0, "A/B/A", "normal", 2, "A/B/A" },
+ {0, "A/B/A/A", "normal", 2, "A/B/A/A" },
+ {0, "A/B/A/D", "normal", 2, "A/B/A/D" },
+
+ {2, "A/B", "normal", 1, "A/A", MOVED_HERE },
+ {2, "A/B/A", "normal", 1, "A/A/A", MOVED_HERE },
+ {2, "A/B/A/A", "normal", 1, "A/A/A/A", MOVED_HERE },
+ {2, "A/B/A/C", "normal", 1, "A/A/A/C", MOVED_HERE },
+ {2, "A/B/A/D", "normal", 1, "A/A/A/D", FALSE, "D", TRUE },
+
+ {1, "D", "normal", 1, "A/B/A/D", MOVED_HERE },
+
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+
+ SVN_ERR(sbox_wc_resolve(&b, "A/A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 2, "" },
+
+ {0, "A", "normal", 2, "A" },
+ {0, "A/A", "normal", 2, "A/A" },
+ {0, "A/A/A", "normal", 2, "A/A/A" },
+
+ {0, "A/B", "normal", 2, "A/B" },
+ {0, "A/B/A", "normal", 2, "A/B/A" },
+ {0, "A/B/A/A", "normal", 2, "A/B/A/A" },
+ {0, "A/B/A/D", "normal", 2, "A/B/A/D" },
+
+ {2, "A/A", "base-deleted", NO_COPY_FROM, "A/B"},
+ {2, "A/A/A", "base-deleted", NO_COPY_FROM },
+
+ {2, "A/B", "normal", 2, "A/A", MOVED_HERE },
+ {2, "A/B/A", "normal", 2, "A/A/A", MOVED_HERE },
+ {2, "A/B/A/A", "base-deleted", NO_COPY_FROM }, /* ### MISSING! */
+ {2, "A/B/A/D", "base-deleted", NO_COPY_FROM, "D" }, /* ### MISSING! */
+
+ /* Still conflicted */
+ {1, "D", "normal", 1, "A/B/A/D", MOVED_HERE },
+
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* ### TODO: Resolve via which specific target? */
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity,
+ svn_wc_conflict_choose_mine_conflict));
+
+ {
+ nodes_row_t nodes[] = {
+
+ {1, "D", "normal", 2, "A/B/A/D", MOVED_HERE },
+
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "D", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_delete_file_externals(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_delete_file_externals", opts,
+ pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ sbox_file_write(&b, "f", "New file");
+ SVN_ERR(sbox_wc_add(&b, "f"));
+ SVN_ERR(sbox_wc_propset(&b, "svn:externals", "^/f B/P/g", "A"));
+ SVN_ERR(sbox_wc_propset(&b, "svn:externals", "^/f Q/g\n^/f g", "A/B"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "f", "normal", 1, "f"},
+ {0, "A/B/g", "normal", 1, "f", TRUE},
+ {0, "A/B/P/g", "normal", 1, "f", TRUE},
+ {0, "A/B/Q/g", "normal", 1, "f", TRUE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Delete removes the file external rows. */
+ SVN_ERR(sbox_wc_delete(&b, "A"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "f", "normal", 1, "f"},
+ {1, "A", "base-deleted", NO_COPY_FROM},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Revert doesn't restore the file external rows... */
+ SVN_ERR(sbox_wc_revert(&b, "A", svn_depth_infinity));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "f", "normal", 1, "f"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+ /* ... but update does. */
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "f", "normal", 1, "f"},
+ {0, "A/B/g", "normal", 1, "f", TRUE},
+ {0, "A/B/P/g", "normal", 1, "f", TRUE},
+ {0, "A/B/Q/g", "normal", 1, "f", TRUE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Move removes the file external rows. */
+ SVN_ERR(sbox_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, "f", "normal", 1, "f"},
+ {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},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+ /* Update adds file external rows to the copy. */
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "f", "normal", 1, "f"},
+ {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},
+ {0, "A2/B/g", "normal", 1, "f", TRUE},
+ {0, "A2/B/P/g", "normal", 1, "f", TRUE},
+ {0, "A2/B/Q/g", "normal", 1, "f", TRUE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+update_with_tree_conflict(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "update_with_tree_conflict", opts,
+ pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_move(&b, "A", "A2"));
+
+ SVN_ERR(sbox_wc_update_depth(&b, "A", 2, svn_depth_empty, FALSE));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 2, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {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},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_update(&b, "A", 2));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 2, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "A/B/C", "normal", 2, "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},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Second update overwrote the existing tree-conflict and that
+ causes the move-update to assert. */
+ SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_infinity,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 2, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "A/B/C", "normal", 2, "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", 2, "A", MOVED_HERE},
+ {1, "A2/B", "normal", 2, "A/B", MOVED_HERE},
+ {1, "A2/B/C", "normal", 2, "A/B/C", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Same again but second update is A/B rather than A which triggers
+ the problem through open_root rather than open_directory. */
+ SVN_ERR(sbox_wc_revert(&b, "", svn_depth_infinity));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_move(&b, "A", "A2"));
+ SVN_ERR(sbox_wc_update_depth(&b, "A", 2, svn_depth_empty, FALSE));
+ SVN_ERR(sbox_wc_update(&b, "A/B", 2));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 2, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "A/B/C", "normal", 2, "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},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+ SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_infinity,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 2, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "A/B/C", "normal", 2, "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", 2, "A", MOVED_HERE},
+ {1, "A2/B", "normal", 2, "A/B", MOVED_HERE},
+ {1, "A2/B/C", "normal", 2, "A/B/C", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_child_to_parent_revert(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/B"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+
+ SVN_ERR(sbox_wc_move(&b, "A/B", "B"));
+ SVN_ERR(sbox_wc_delete(&b, "A"));
+
+ /* Verify that the move is still recorded correctly */
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 0, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+
+ {1, "A", "base-deleted", NO_COPY_FROM},
+ {1, "A/B", "base-deleted", NO_COPY_FROM, "B"},
+
+ {1, "B", "normal", 1, "A/B", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ 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_delete_intermediate(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_delete_intermediate", 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},
+
+ {0},
+ };
+ 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 delete A */
+ SVN_ERR(sbox_wc_delete(&b, "A"));
+
+ /* AAA_1, AAA_2 and AAA_3 should still be moves after deleting A */
+ {
+ 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", "base-deleted", NO_COPY_FROM},
+ {1, "A/A", "base-deleted", NO_COPY_FROM},
+ {1, "A/A/A", "base-deleted", NO_COPY_FROM, "AAA_1"},
+ {1, "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},
+ {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},
+
+ {0},
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_revert_intermediate(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_revert_intermediate", 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},
+
+ {0},
+ };
+ 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},
+
+ {0},
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_mixed_rev_mods(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "copy_mixed_rev_mods", opts,
+ pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_update(&b, "A/B", 2));
+ SVN_ERR(sbox_wc_delete(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "A/B/C", "normal", 2, "A/B/C"},
+ {2, "A/B", "normal", NO_COPY_FROM},
+ {2, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_copy(&b, "A", "X"));
+ {
+ nodes_row_t nodes[] = {
+ {1, "X", "normal", 1, "A"},
+ {1, "X/B", "not-present", 2, "A/B"},
+ {2, "X/B", "normal", NO_COPY_FROM},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "X", nodes));
+ }
+
+ SVN_ERR(sbox_wc_commit(&b, "X"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "X", "normal", 3, "X"},
+ {0, "X/B", "normal", 3, "X/B"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "X", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_replace_ancestor_with_child(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_replace_ancestor_with_child", opts,
+ pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/A"));
+
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_move(&b, "A", "A2"));
+
+ {
+ nodes_row_t nodes[] = {
+
+ { 0, "", "normal", 1, "" },
+
+ { 0, "A", "normal", 1, "A"},
+ { 0, "A/A", "normal", 1, "A/A" },
+
+ { 1, "A", "base-deleted", NO_COPY_FROM , "A2"},
+ { 1, "A/A", "base-deleted", NO_COPY_FROM },
+
+ { 1, "A2", "normal", 1, "A", MOVED_HERE },
+ { 1, "A2/A", "normal", 1, "A/A", MOVED_HERE },
+
+ { 0 },
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_move(&b, "A2/A", "A"));
+
+ {
+ nodes_row_t nodes[] = {
+ { 0, "", "normal", 1, "" },
+
+ { 0, "A", "normal", 1, "A"},
+ { 0, "A/A", "normal", 1, "A/A" },
+
+ { 1, "A", "normal", 1, "A/A", FALSE, "A2", TRUE },
+ { 1, "A/A", "base-deleted", NO_COPY_FROM },
+
+ { 1, "A2", "normal", 1, "A", MOVED_HERE },
+ { 1, "A2/A", "normal", 1, "A/A", MOVED_HERE },
+
+ { 2, "A2/A", "base-deleted", NO_COPY_FROM, "A" },
+ { 0 },
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* ### This currently fails with an assertion in maintainer mode */
+ SVN_ERR(sbox_wc_delete(&b, "A2"));
+
+ {
+ nodes_row_t nodes[] = {
+ { 0, "", "normal", 1, "" },
+
+ { 0, "A", "normal", 1, "A"},
+ { 0, "A/A", "normal", 1, "A/A" },
+
+ { 1, "A", "normal", 1, "A/A", MOVED_HERE },
+ { 1, "A/A", "base-deleted", NO_COPY_FROM, "A" },
+
+ { 0 },
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_commit(&b, "A"));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_twice_within_delete(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_twice_within_delete", 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_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "B"));
+ SVN_ERR(sbox_wc_move(&b, "A", "B/A"));
+ SVN_ERR(sbox_wc_move(&b, "B/A/A", "B/AA"));
+ SVN_ERR(sbox_wc_move(&b, "B/AA/A", "AA"));
+
+ {
+ nodes_row_t nodes[] = {
+
+ { 0, "", "normal", 1, "" },
+
+ { 0, "A", "normal", 1, "A" },
+ { 0, "A/A", "normal", 1, "A/A" },
+ { 0, "A/A/A", "normal", 1, "A/A/A" },
+
+ { 1, "A", "base-deleted", NO_COPY_FROM, "B/A" },
+ { 1, "A/A", "base-deleted", NO_COPY_FROM },
+ { 1, "A/A/A", "base-deleted", NO_COPY_FROM },
+
+ { 1, "AA", "normal", 1, "A/A/A", MOVED_HERE },
+
+ { 1, "B", "normal", NO_COPY_FROM },
+ { 2, "B/A", "normal", 1, "A", MOVED_HERE },
+ { 2, "B/A/A", "normal", 1, "A/A", MOVED_HERE },
+ { 2, "B/A/A/A", "normal", 1, "A/A/A", MOVED_HERE },
+
+ { 3, "B/A/A", "base-deleted", NO_COPY_FROM, "B/AA" },
+ { 3, "B/A/A/A", "base-deleted", NO_COPY_FROM },
+
+ { 2, "B/AA", "normal", 1, "A/A", MOVED_HERE},
+ { 2, "B/AA/A", "normal", 1, "A/A/A", MOVED_HERE },
+
+ { 3, "B/AA/A", "base-deleted", NO_COPY_FROM, "AA" },
+
+ { 0 },
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_delete(&b, "B"));
+
+ {
+ nodes_row_t nodes[] = {
+ { 0, "", "normal", 1, "" },
+
+ { 0, "A", "normal", 1, "A" },
+ { 0, "A/A", "normal", 1, "A/A" },
+ { 0, "A/A/A", "normal", 1, "A/A/A" },
+
+ { 1, "A", "base-deleted", NO_COPY_FROM },
+ { 1, "A/A", "base-deleted", NO_COPY_FROM },
+ { 1, "A/A/A", "base-deleted", NO_COPY_FROM, "AA" },
+
+ { 1, "AA", "normal", 1, "A/A/A", MOVED_HERE },
+
+ { 0 },
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+repo_wc_copy(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+ const char *repos_dir;
+ const char *new_repos_dir;
+ const char *new_repos_url;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "repo_wc_copy",
+ opts, pool));
+ SVN_ERR(sbox_add_and_commit_greek_tree(&b));
+
+ SVN_ERR(sbox_wc_copy_url(&b,
+ svn_path_url_add_component2(b.repos_url, "A/B",
+ pool),
+ -1, "AA"));
+
+ {
+ nodes_row_t nodes[] = {
+
+ {1, "AA/lambda", "normal", 1, "A/B/lambda"},
+ {1, "AA", "normal", 1, "A/B"},
+ {1, "AA/E/beta", "normal", 1, "A/B/E/beta"},
+ {1, "AA/E/alpha", "normal", 1, "A/B/E/alpha"},
+ {1, "AA/F", "normal", 1, "A/B/F"},
+ {1, "AA/E", "normal", 1, "A/B/E"},
+
+ { 0 },
+ };
+ SVN_ERR(check_db_rows(&b, "AA", nodes));
+ }
+
+ SVN_ERR(svn_uri_get_dirent_from_file_url(&repos_dir, b.repos_url,
+ pool));
+ new_repos_dir = apr_pstrcat(pool, repos_dir, "-2", SVN_VA_NULL);
+ new_repos_url = apr_pstrcat(pool, b.repos_url, "-2", SVN_VA_NULL);
+
+ svn_test_add_dir_cleanup(new_repos_dir);
+
+ SVN_ERR(svn_io_remove_dir2(new_repos_dir, TRUE, NULL, NULL, pool));
+ SVN_ERR(svn_io_copy_dir_recursively(repos_dir,
+ svn_dirent_dirname(new_repos_dir, pool),
+ svn_dirent_basename(new_repos_dir, pool),
+ FALSE, NULL, NULL, pool));
+
+ SVN_ERR(sbox_wc_relocate(&b, new_repos_url));
+
+ /* This produced an invalid copy in Subversion <= 1.8.8.
+ Status would show all descendants as incomplete */
+ SVN_ERR(sbox_wc_copy_url(&b,
+ svn_path_url_add_component2(b.repos_url, "A/B",
+ pool),
+ -1, "BB"));
+
+ {
+ nodes_row_t nodes[] = {
+
+ {1, "BB/lambda", "normal", 1, "A/B/lambda"},
+ {1, "BB", "normal", 1, "A/B"},
+ {1, "BB/E/beta", "normal", 1, "A/B/E/beta"},
+ {1, "BB/E/alpha", "normal", 1, "A/B/E/alpha"},
+ {1, "BB/F", "normal", 1, "A/B/F"},
+ {1, "BB/E", "normal", 1, "A/B/E"},
+
+ { 0 },
+ };
+ SVN_ERR(check_db_rows(&b, "BB", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+movedhere_extract_retract(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "movedhere_extract_retract",
+ opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B1"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B2"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B3"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/C1"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/C2"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/C3"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/D1"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/D2"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/D3"));
+
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ SVN_ERR(sbox_wc_propset(&b, "k", "v", "A/B1"));
+ SVN_ERR(sbox_wc_propset(&b, "k", "v", "A/B2"));
+ SVN_ERR(sbox_wc_propset(&b, "k", "v", "A/B3"));
+ SVN_ERR(sbox_wc_delete(&b, "A/C1"));
+ SVN_ERR(sbox_wc_delete(&b, "A/C2"));
+ SVN_ERR(sbox_wc_delete(&b, "A/C3"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/E1"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/E2"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/E3"));
+
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_move(&b, "A", "Z"));
+
+ SVN_ERR(sbox_wc_delete(&b, "Z/B1"));
+ SVN_ERR(sbox_wc_delete(&b, "Z/C1"));
+ SVN_ERR(sbox_wc_delete(&b, "Z/D1"));
+
+ SVN_ERR(sbox_wc_move(&b, "Z/B2", "B2"));
+ SVN_ERR(sbox_wc_move(&b, "Z/C2", "C2"));
+ SVN_ERR(sbox_wc_move(&b, "Z/D2", "D2"));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "Z/B2"));
+ SVN_ERR(sbox_wc_mkdir(&b, "Z/C2"));
+ SVN_ERR(sbox_wc_mkdir(&b, "Z/D2"));
+ SVN_ERR(sbox_wc_mkdir(&b, "Z/E2"));
+
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(sbox_wc_resolve(&b, "Z/B1", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(sbox_wc_resolve(&b, "Z/B2", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+
+ SVN_ERR(sbox_wc_resolve(&b, "Z/C1", svn_depth_empty,
+ svn_wc_conflict_choose_merged));
+ SVN_ERR(sbox_wc_resolve(&b, "Z/C2", svn_depth_empty,
+ svn_wc_conflict_choose_merged));
+
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ nodes_row_t nodes[] = {
+
+ {0, "", "normal", 2, ""},
+ {0, "A", "normal", 2, "A"},
+ {0, "A/B1", "normal", 2, "A/B1", FALSE, NULL, FALSE, "k"},
+ {0, "A/B2", "normal", 2, "A/B2", FALSE, NULL, FALSE, "k"},
+ {0, "A/B3", "normal", 2, "A/B3", FALSE, NULL, FALSE, "k"},
+ {0, "A/D1", "normal", 2, "A/D1"},
+ {0, "A/D2", "normal", 2, "A/D2"},
+ {0, "A/D3", "normal", 2, "A/D3"},
+ {0, "A/E1", "normal", 2, "A/E1"},
+ {0, "A/E2", "normal", 2, "A/E2"},
+ {0, "A/E3", "normal", 2, "A/E3"},
+
+ {1, "A", "base-deleted", NO_COPY_FROM, "Z"},
+ {1, "A/B1", "base-deleted", NO_COPY_FROM},
+ {1, "A/B2", "base-deleted", NO_COPY_FROM},
+ {1, "A/B3", "base-deleted", NO_COPY_FROM},
+
+ {1, "A/D1", "base-deleted", NO_COPY_FROM},
+ {1, "A/D2", "base-deleted", NO_COPY_FROM},
+ {1, "A/D3", "base-deleted", NO_COPY_FROM},
+
+ {1, "A/E1", "base-deleted", NO_COPY_FROM},
+ {1, "A/E2", "base-deleted", NO_COPY_FROM},
+ {1, "A/E3", "base-deleted", NO_COPY_FROM},
+
+ {1, "B2", "normal", 2, "A/B2", MOVED_HERE, "k"},
+ {1, "C2", "normal", 1, "A/C2"},
+ {1, "D2", "normal", 1, "A/D2", MOVED_HERE},
+
+ {1, "Z", "normal", 2, "A", MOVED_HERE},
+ {1, "Z/B1", "normal", 2, "A/B1", MOVED_HERE, "k"},
+ {1, "Z/B2", "normal", 2, "A/B2", MOVED_HERE, "k"},
+ {1, "Z/B3", "normal", 2, "A/B3", MOVED_HERE, "k"},
+ {1, "Z/D1", "normal", 2, "A/D1", MOVED_HERE},
+ {1, "Z/D2", "normal", 2, "A/D2", MOVED_HERE},
+ {1, "Z/D3", "normal", 2, "A/D3", MOVED_HERE},
+ {1, "Z/E1", "normal", 2, "A/E1", MOVED_HERE},
+ {1, "Z/E2", "normal", 2, "A/E2", MOVED_HERE},
+ {1, "Z/E3", "normal", 2, "A/E3", MOVED_HERE},
+
+ {2, "Z/B2", "normal", NO_COPY_FROM, "B2"},
+ {2, "Z/C2", "normal", NO_COPY_FROM},
+ {2, "Z/D2", "normal", NO_COPY_FROM, "D2"},
+ {2, "Z/E2", "normal", NO_COPY_FROM},
+
+ {2, "Z/B1", "base-deleted", NO_COPY_FROM},
+ {2, "Z/D1", "base-deleted", NO_COPY_FROM},
+
+ { 0 },
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+
+static svn_error_t *
+nested_move_delete(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "nested_move_delete", opts, pool));
+
+ SVN_ERR(sbox_add_and_commit_greek_tree(&b));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A/Z"));
+ SVN_ERR(sbox_wc_move(&b, "A/B/lambda", "A/Z/lambda"));
+
+ SVN_ERR(sbox_wc_delete(&b, "A/B"));
+
+ {
+ nodes_row_t nodes_AB[] = {
+ {0, "A/B", "normal", 1, "A/B"},
+ {2, "A/B", "base-deleted", NO_COPY_FROM},
+ {0, "A/B/E", "normal", 1, "A/B/E"},
+ {2, "A/B/E", "base-deleted", NO_COPY_FROM},
+ {0, "A/B/E/alpha", "normal", 1, "A/B/E/alpha"},
+ {2, "A/B/E/alpha", "base-deleted", NO_COPY_FROM},
+ {0, "A/B/E/beta", "normal", 1, "A/B/E/beta"},
+ {2, "A/B/E/beta", "base-deleted", NO_COPY_FROM},
+ {0, "A/B/F", "normal", 1, "A/B/F"},
+ {2, "A/B/F", "base-deleted", NO_COPY_FROM},
+ {0, "A/B/lambda", "normal", 1, "A/B/lambda"},
+ {2, "A/B/lambda", "base-deleted", NO_COPY_FROM, "A/Z/lambda"},
+ {0}
+ };
+ nodes_row_t nodes_AZ[] = {
+ {2, "A/Z", "normal", NO_COPY_FROM},
+ {3, "A/Z/lambda", "normal", 1, "A/B/lambda", MOVED_HERE },
+ {0}
+ };
+
+ SVN_ERR(check_db_rows(&b, "A/B", nodes_AB));
+ SVN_ERR(check_db_rows(&b, "A/Z", nodes_AZ));
+ }
+
+ SVN_ERR(sbox_wc_move(&b, "A", "A_moved"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 0, ""},
+ {0, "A", "normal", 1, "A"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A_moved"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {0, "A/B/E", "normal", 1, "A/B/E"},
+ {1, "A/B/E", "base-deleted", NO_COPY_FROM},
+ {0, "A/B/E/alpha", "normal", 1, "A/B/E/alpha"},
+ {1, "A/B/E/alpha", "base-deleted", NO_COPY_FROM},
+ {0, "A/B/E/beta", "normal", 1, "A/B/E/beta"},
+ {1, "A/B/E/beta", "base-deleted", NO_COPY_FROM},
+ {0, "A/B/F", "normal", 1, "A/B/F"},
+ {1, "A/B/F", "base-deleted", NO_COPY_FROM},
+ {0, "A/B/lambda", "normal", 1, "A/B/lambda"},
+ {1, "A/B/lambda", "base-deleted", NO_COPY_FROM},
+ {0, "A/C", "normal", 1, "A/C"},
+ {1, "A/C", "base-deleted", NO_COPY_FROM},
+ {0, "A/D", "normal", 1, "A/D"},
+ {1, "A/D", "base-deleted", NO_COPY_FROM},
+ {0, "A/D/G", "normal", 1, "A/D/G"},
+ {1, "A/D/G", "base-deleted", NO_COPY_FROM},
+ {0, "A/D/G/pi", "normal", 1, "A/D/G/pi"},
+ {1, "A/D/G/pi", "base-deleted", NO_COPY_FROM},
+ {0, "A/D/G/rho", "normal", 1, "A/D/G/rho"},
+ {1, "A/D/G/rho", "base-deleted", NO_COPY_FROM},
+ {0, "A/D/G/tau", "normal", 1, "A/D/G/tau"},
+ {1, "A/D/G/tau", "base-deleted", NO_COPY_FROM},
+ {0, "A/D/H", "normal", 1, "A/D/H"},
+ {1, "A/D/H", "base-deleted", NO_COPY_FROM},
+ {0, "A/D/H/chi", "normal", 1, "A/D/H/chi"},
+ {1, "A/D/H/chi", "base-deleted", NO_COPY_FROM},
+ {0, "A/D/H/omega", "normal", 1, "A/D/H/omega"},
+ {1, "A/D/H/omega", "base-deleted", NO_COPY_FROM},
+ {0, "A/D/H/psi", "normal", 1, "A/D/H/psi"},
+ {1, "A/D/H/psi", "base-deleted", NO_COPY_FROM},
+ {0, "A/D/gamma", "normal", 1, "A/D/gamma"},
+ {1, "A/D/gamma", "base-deleted", NO_COPY_FROM},
+ {0, "A/mu", "normal", 1, "A/mu"},
+ {1, "A/mu", "base-deleted", NO_COPY_FROM},
+ {1, "A_moved", "normal", 1, "A", MOVED_HERE},
+ {1, "A_moved/B", "normal", 1, "A/B", MOVED_HERE},
+ {2, "A_moved/B", "base-deleted", NO_COPY_FROM},
+ {2, "A_moved/B/E", "base-deleted", NO_COPY_FROM},
+ {1, "A_moved/B/E", "normal", 1, "A/B/E", MOVED_HERE},
+ {1, "A_moved/B/E/alpha", "normal", 1, "A/B/E/alpha", MOVED_HERE},
+ {2, "A_moved/B/E/alpha", "base-deleted", NO_COPY_FROM},
+ {1, "A_moved/B/E/beta", "normal", 1, "A/B/E/beta", MOVED_HERE},
+ {2, "A_moved/B/E/beta", "base-deleted", NO_COPY_FROM},
+ {1, "A_moved/B/F", "normal", 1, "A/B/F", MOVED_HERE},
+ {2, "A_moved/B/F", "base-deleted", NO_COPY_FROM},
+ {1, "A_moved/B/lambda", "normal", 1, "A/B/lambda", MOVED_HERE},
+ {2, "A_moved/B/lambda", "base-deleted", NO_COPY_FROM, "A_moved/Z/lambda"},
+ {1, "A_moved/C", "normal", 1, "A/C", MOVED_HERE},
+ {1, "A_moved/D", "normal", 1, "A/D", MOVED_HERE},
+ {1, "A_moved/D/G", "normal", 1, "A/D/G", MOVED_HERE},
+ {1, "A_moved/D/G/pi", "normal", 1, "A/D/G/pi", MOVED_HERE},
+ {1, "A_moved/D/G/rho", "normal", 1, "A/D/G/rho", MOVED_HERE},
+ {1, "A_moved/D/G/tau", "normal", 1, "A/D/G/tau", MOVED_HERE},
+ {1, "A_moved/D/H", "normal", 1, "A/D/H", MOVED_HERE},
+ {1, "A_moved/D/H/chi", "normal", 1, "A/D/H/chi", MOVED_HERE},
+ {1, "A_moved/D/H/omega", "normal", 1, "A/D/H/omega", MOVED_HERE},
+ {1, "A_moved/D/H/psi", "normal", 1, "A/D/H/psi", MOVED_HERE},
+ {1, "A_moved/D/gamma", "normal", 1, "A/D/gamma", MOVED_HERE},
+ {2, "A_moved/Z", "normal", NO_COPY_FROM},
+ {3, "A_moved/Z/lambda", "normal", 1, "A/B/lambda", MOVED_HERE},
+ {1, "A_moved/mu", "normal", 1, "A/mu", MOVED_HERE},
+ {0, "iota", "normal", 1, "iota"},
+
+ {0}
+ };
+
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
/* ---------------------------------------------------------------------- */
/* The list of test functions */
@@ -3606,7 +9081,116 @@ struct svn_test_descriptor_t test_funcs[] =
#endif
SVN_TEST_OPTS_PASS(commit_file_external,
"commit_file_external (issue #4002)"),
+ SVN_TEST_OPTS_PASS(revert_file_externals,
+ "revert_file_externals"),
+ SVN_TEST_OPTS_PASS(copy_file_externals,
+ "copy_file_externals"),
+ SVN_TEST_OPTS_PASS(copy_wc_wc_server_excluded,
+ "test_wc_wc_copy_server_excluded"),
SVN_TEST_OPTS_PASS(incomplete_switch,
"incomplete_switch (issue 4040)"),
+ SVN_TEST_OPTS_PASS(nested_moves_child_first,
+ "nested_moves_child_first"),
+ SVN_TEST_OPTS_PASS(nested_moves_child_last,
+ "nested_moves_child_last"),
+ SVN_TEST_OPTS_PASS(move_in_copy,
+ "move_in_copy"),
+ SVN_TEST_OPTS_PASS(move_in_replace,
+ "move_in_replace"),
+ SVN_TEST_OPTS_PASS(copy_a_move,
+ "copy_a_move"),
+ SVN_TEST_OPTS_PASS(move_to_swap,
+ "move_to_swap"),
+ SVN_TEST_OPTS_PASS(revert_nested_move,
+ "revert_nested_move"),
+ SVN_TEST_OPTS_PASS(move_on_move,
+ "move_on_move"),
+ SVN_TEST_OPTS_PASS(move_on_move2,
+ "move_on_move2"),
+ SVN_TEST_OPTS_PASS(move_added,
+ "move_added"),
+ SVN_TEST_OPTS_PASS(move_update,
+ "move_update"),
+ SVN_TEST_OPTS_PASS(test_scan_delete,
+ "scan_delete"),
+ SVN_TEST_OPTS_PASS(test_follow_moved_to,
+ "follow_moved_to"),
+ SVN_TEST_OPTS_WIMP(mixed_rev_move,
+ "mixed_rev_move",
+ "needs different libsvn_wc entry point"),
+ SVN_TEST_OPTS_PASS(update_prop_mod_into_moved,
+ "update_prop_mod_into_moved"),
+ SVN_TEST_OPTS_PASS(nested_move_update,
+ "nested_move_update"),
+ SVN_TEST_OPTS_PASS(nested_move_commit,
+ "nested_move_commit (issue 4291)"),
+ SVN_TEST_OPTS_PASS(nested_move_update2,
+ "nested_move_update2"),
+ SVN_TEST_OPTS_PASS(move_update_conflicts,
+ "move_update_conflicts"),
+ SVN_TEST_OPTS_PASS(move_update_delete_mods,
+ "move_update_delete_mods"),
+ SVN_TEST_OPTS_PASS(nested_moves2,
+ "nested_moves2"),
+ SVN_TEST_OPTS_PASS(move_in_delete,
+ "move_in_delete (issue 4303)"),
+ SVN_TEST_OPTS_PASS(switch_move,
+ "switch_move"),
+ SVN_TEST_OPTS_PASS(move_replace,
+ "move_replace"),
+ SVN_TEST_OPTS_PASS(layered_moved_to,
+ "layered_moved_to"),
+ SVN_TEST_OPTS_PASS(update_within_move,
+ "update_within_move"),
+ SVN_TEST_OPTS_PASS(commit_moved_descendant,
+ "commit_moved_descendant"),
+ SVN_TEST_OPTS_XFAIL(commit_moved_away_descendant,
+ "commit_moved_away_descendant"),
+ SVN_TEST_OPTS_PASS(finite_move_update_bump,
+ "finite_move_update_bump"),
+ SVN_TEST_OPTS_PASS(move_away_delete_update,
+ "move_away_delete_update"),
+ SVN_TEST_OPTS_PASS(move_not_present_variants,
+ "move_not_present_variants"),
+ SVN_TEST_OPTS_PASS(update_child_under_add,
+ "update_child_under_add (issue 4111)"),
+ SVN_TEST_OPTS_PASS(delete_over_moved_away,
+ "delete_over_moved_away"),
+ SVN_TEST_OPTS_PASS(movedto_opdepth,
+ "moved_to op_depth"),
+ SVN_TEST_OPTS_PASS(new_basemove,
+ "new_basemove"),
+ SVN_TEST_OPTS_PASS(move_back,
+ "move_back (issue 4302)"),
+ SVN_TEST_OPTS_PASS(move_update_subtree,
+ "move_update_subtree (issue 4232)"),
+ SVN_TEST_OPTS_PASS(move_parent_into_child,
+ "move_parent_into_child (issue 4333)"),
+ SVN_TEST_OPTS_PASS(move_depth_expand,
+ "move depth expansion"),
+ SVN_TEST_OPTS_PASS(move_retract,
+ "move retract (issue 4336)"),
+ SVN_TEST_OPTS_PASS(move_delete_file_externals,
+ "move/delete file externals (issue 4293)"),
+ SVN_TEST_OPTS_PASS(update_with_tree_conflict,
+ "update with tree conflict (issue 4347)"),
+ SVN_TEST_OPTS_PASS(move_child_to_parent_revert,
+ "move child to parent and revert (issue 4436)"),
+ SVN_TEST_OPTS_PASS(move_delete_intermediate,
+ "move more than once, delete intermediate"),
+ SVN_TEST_OPTS_XFAIL(move_revert_intermediate,
+ "move more than once, revert intermediate"),
+ SVN_TEST_OPTS_PASS(move_replace_ancestor_with_child,
+ "move replace ancestor with child"),
+ SVN_TEST_OPTS_PASS(move_twice_within_delete,
+ "move twice and then delete"),
+ SVN_TEST_OPTS_PASS(repo_wc_copy,
+ "repo_wc_copy"),
+ SVN_TEST_OPTS_PASS(copy_mixed_rev_mods,
+ "copy mixed-rev with mods"),
+ SVN_TEST_OPTS_PASS(movedhere_extract_retract,
+ "movedhere extract retract"),
+ SVN_TEST_OPTS_PASS(nested_move_delete,
+ "nested move delete"),
SVN_TEST_NULL
};