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.c3547
1 files changed, 3222 insertions, 325 deletions
diff --git a/subversion/tests/libsvn_wc/op-depth-test.c b/subversion/tests/libsvn_wc/op-depth-test.c
index 39afcf4..c0ec24b 100644
--- a/subversion/tests/libsvn_wc/op-depth-test.c
+++ b/subversion/tests/libsvn_wc/op-depth-test.c
@@ -28,6 +28,7 @@
#include <apr_general.h>
#include "svn_types.h"
+#include "svn_hash.h"
#include "svn_io.h"
#include "svn_dirent_uri.h"
#include "svn_pools.h"
@@ -39,9 +40,10 @@
#include "utils.h"
-#include "private/svn_wc_private.h"
-#include "private/svn_sqlite.h"
#include "private/svn_dep_compat.h"
+#include "private/svn_sorts_private.h"
+#include "private/svn_sqlite.h"
+#include "private/svn_wc_private.h"
#include "../../libsvn_wc/wc.h"
#include "../../libsvn_wc/wc_db.h"
#include "../../libsvn_wc/workqueue.h"
@@ -51,17 +53,9 @@
#include "../svn_test.h"
-#ifdef _MSC_VER
-#pragma warning(disable: 4221) /* nonstandard extension used */
-#endif
+#include "wc-test-queries.h"
-/* 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
+WC_TEST_QUERIES_SQL_DECLARE_STATEMENTS(op_depth_statements);
/* Compare strings, like strcmp but either or both may be NULL which
* compares equal to NULL and not equal to any non-NULL string. */
@@ -83,13 +77,13 @@ strcmp_null(const char *s1, const char *s2)
static svn_error_t *
open_wc_db(svn_sqlite__db_t **sdb,
const char *wc_root_abspath,
- const char *const *my_statements,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
SVN_ERR(svn_wc__db_util_open_db(sdb, wc_root_abspath, "wc.db",
svn_sqlite__mode_readwrite,
- FALSE /* exclusive */, my_statements,
+ FALSE /* exclusive */, 0 /* timeout */,
+ op_depth_statements,
result_pool, scratch_pool));
return SVN_NO_ERROR;
}
@@ -111,11 +105,30 @@ typedef struct nodes_row_t {
const char *props; /* comma-separated list of prop names */
} nodes_row_t;
+/* Tree conflict details */
+typedef struct tree_conflict_info
+{
+ svn_wc_conflict_action_t action;
+ svn_wc_conflict_reason_t reason;
+ const char *delete_path;
+ svn_boolean_t conflicted_fb; /* fallback for reason, action and path 0 */
+} tree_conflict_info;
+
+/* What conflicts are on a path. */
+typedef struct conflict_info_t {
+ const char *local_relpath;
+ svn_boolean_t text_conflicted;
+ svn_boolean_t prop_conflicted;
+
+ tree_conflict_info tc;
+} conflict_info_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, FALSE
#define MOVED_HERE FALSE, NULL, TRUE
#define NOT_MOVED FALSE, NULL, FALSE
+#define FILE_EXTERNAL TRUE
/* 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
@@ -145,28 +158,36 @@ props_hash_to_text(apr_hash_t *props, apr_pool_t *pool)
return str->len ? str->data : NULL;
}
-/* Return a human-readable string representing ROW. */
+/* Return a human-readable string representing ROW. With a tiny bit of editting
+ this can be used to create expected results */
static const char *
print_row(const nodes_row_t *row,
apr_pool_t *result_pool)
{
+ const char *relpath_str, *presence_str;
const char *file_external_str, *moved_here_str, *moved_to_str, *props;
if (row == NULL)
return "(null)";
+ relpath_str = apr_psprintf(result_pool, "\"%s\",", row->local_relpath);
+ presence_str = apr_psprintf(result_pool, "\"%s\",", row->presence);
if (row->moved_to)
- moved_to_str = apr_psprintf(result_pool, ", moved-to %s", row->moved_to);
+ moved_to_str = apr_psprintf(result_pool, ", \"%s\"", row->moved_to);
else
moved_to_str = "";
- if (row->moved_here)
- moved_here_str = ", moved-here";
+ if (row->moved_here && !row->file_external && !row->moved_to)
+ moved_here_str = ", MOVED_HERE";
+ else if (row->moved_to)
+ moved_here_str = ", TRUE";
else
moved_here_str = "";
if (row->file_external)
- file_external_str = ", file-external";
+ file_external_str = ", FILE_EXTERNAL";
+ else if (row->moved_to || row->props)
+ file_external_str = ", FALSE";
else
file_external_str = "";
@@ -176,19 +197,17 @@ print_row(const nodes_row_t *row,
props = "";
if (row->repo_revnum == SVN_INVALID_REVNUM)
- return apr_psprintf(result_pool, "%d, \"%s\", \"%s\"%s%s%s%s",
- row->op_depth, row->local_relpath, row->presence,
- moved_here_str, moved_to_str,
- file_external_str, props);
+ return apr_psprintf(result_pool, "%d, %-20s%-15s NO_COPY_FROM%s%s%s%s",
+ row->op_depth, relpath_str, presence_str,
+ file_external_str, moved_here_str, moved_to_str,
+ props);
else
- 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,
- moved_here_str, moved_to_str,
- file_external_str, props);
+ return apr_psprintf(result_pool, "%d, %-20s%-15s %d, \"%s\"%s%s%s%s",
+ row->op_depth, relpath_str, presence_str,
+ (int)row->repo_revnum, row->repo_relpath,
+ file_external_str, moved_here_str, moved_to_str,
+ props);
}
-
/* A baton to pass through svn_hash_diff() to compare_nodes_rows(). */
typedef struct comparison_baton_t {
apr_hash_t *expected_hash; /* Maps "OP_DEPTH PATH" to nodes_row_t. */
@@ -259,20 +278,9 @@ check_db_rows(svn_test__sandbox_t *b,
const char *root_path,
const nodes_row_t *expected_rows)
{
- const char *base_relpath = root_path;
svn_sqlite__db_t *sdb;
int i;
svn_sqlite__stmt_t *stmt;
- static const char *const statements[] = {
- "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
svn_boolean_t have_row;
apr_hash_t *found_hash = apr_hash_make(b->pool);
@@ -285,12 +293,10 @@ check_db_rows(svn_test__sandbox_t *b,
comparison_baton.errors = NULL;
/* Fill ACTUAL_HASH with data from the WC DB. */
- SVN_ERR(open_wc_db(&sdb, b->wc_abspath, statements, b->pool, b->pool));
+ SVN_ERR(open_wc_db(&sdb, b->wc_abspath, b->pool, b->pool));
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_NODES_INFO));
- SVN_ERR(svn_sqlite__bindf(stmt, "ss", base_relpath,
- (base_relpath[0]
- ? apr_psprintf(b->pool, "%s/%%", base_relpath)
- : "_%")));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", (apr_int64_t)1 /* wc_id */,
+ root_path));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
while (have_row)
{
@@ -304,16 +310,17 @@ 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);
+ 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));
+
key = apr_psprintf(b->pool, "%d %s", row->op_depth, row->local_relpath);
apr_hash_set(found_hash, key, APR_HASH_KEY_STRING, row);
@@ -338,6 +345,257 @@ check_db_rows(svn_test__sandbox_t *b,
return comparison_baton.errors;
}
+#define EDIT_EDIT_TC {svn_wc_conflict_reason_edited, \
+ svn_wc_conflict_action_edit, \
+ NULL, TRUE}
+#define NO_TC { 0 }
+static const char *
+print_conflict(const conflict_info_t *row,
+ apr_pool_t *result_pool)
+{
+ const char *tc_text;
+
+ if (!row->tc.reason && !row->tc.action && !row->tc.delete_path)
+ {
+ if (row->tc.conflicted_fb)
+ tc_text = "EDIT_EDIT_TC";
+ else
+ tc_text = "NO_TC";
+ }
+ else
+ {
+ const char *action;
+ const char *reason;
+ const char *path;
+
+#define CASE_ENUM_STRVAL(x, y) case y: x = #y; break
+ switch(row->tc.action)
+ {
+ CASE_ENUM_STRVAL(action, svn_wc_conflict_action_edit);
+ CASE_ENUM_STRVAL(action, svn_wc_conflict_action_add);
+ CASE_ENUM_STRVAL(action, svn_wc_conflict_action_delete);
+ CASE_ENUM_STRVAL(action, svn_wc_conflict_action_replace);
+ default:
+ SVN_ERR_MALFUNCTION_NO_RETURN();
+ }
+ switch(row->tc.reason)
+ {
+ CASE_ENUM_STRVAL(reason, svn_wc_conflict_reason_edited);
+ CASE_ENUM_STRVAL(reason, svn_wc_conflict_reason_obstructed);
+ CASE_ENUM_STRVAL(reason, svn_wc_conflict_reason_deleted);
+ CASE_ENUM_STRVAL(reason, svn_wc_conflict_reason_missing);
+ CASE_ENUM_STRVAL(reason, svn_wc_conflict_reason_unversioned);
+ CASE_ENUM_STRVAL(reason, svn_wc_conflict_reason_added);
+ CASE_ENUM_STRVAL(reason, svn_wc_conflict_reason_replaced);
+ CASE_ENUM_STRVAL(reason, svn_wc_conflict_reason_moved_away);
+ CASE_ENUM_STRVAL(reason, svn_wc_conflict_reason_moved_here);
+ default:
+ SVN_ERR_MALFUNCTION_NO_RETURN();
+ }
+
+ if (row->tc.delete_path)
+ path = apr_psprintf(result_pool, ", \"%s\"", row->tc.delete_path);
+ else
+ path = "";
+
+ tc_text = apr_psprintf(result_pool, "{%s, %s%s}", action,
+ reason, path);
+ }
+
+ return apr_psprintf(result_pool, "\"%s\", %s, %s, %s",
+ row->local_relpath,
+ row->text_conflicted ? "TRUE" : "FALSE",
+ row->prop_conflicted ? "TRUE" : "FALSE",
+ tc_text);
+}
+
+static svn_boolean_t
+tree_conflicts_match(const tree_conflict_info *expected,
+ const tree_conflict_info *actual)
+{
+ if (expected->action != actual->action)
+ return FALSE;
+ else if (expected->reason != actual->reason)
+ return FALSE;
+ else if (strcmp_null(expected->delete_path, actual->delete_path) != 0)
+ return FALSE;
+ else if (expected->conflicted_fb != actual->conflicted_fb)
+ return FALSE;
+
+ return TRUE;
+}
+
+static svn_error_t *
+compare_conflict_info(const void *key, apr_ssize_t klen,
+ enum svn_hash_diff_key_status status,
+ void *baton)
+{
+ comparison_baton_t *b = baton;
+ conflict_info_t *expected = apr_hash_get(b->expected_hash, key, klen);
+ conflict_info_t *found = apr_hash_get(b->found_hash, key, klen);
+
+ if (! expected)
+ {
+ b->errors = svn_error_createf(
+ SVN_ERR_TEST_FAILED, b->errors,
+ "found {%s}",
+ print_conflict(found, b->scratch_pool));
+ }
+ else if (! found)
+ {
+ b->errors = svn_error_createf(
+ SVN_ERR_TEST_FAILED, b->errors,
+ "expected {%s}",
+ print_conflict(expected, b->scratch_pool));
+ }
+ else if (expected->text_conflicted != found->text_conflicted
+ || expected->prop_conflicted != found->prop_conflicted
+ || !tree_conflicts_match(&expected->tc, &found->tc))
+ {
+ b->errors = svn_error_createf(
+ SVN_ERR_TEST_FAILED, b->errors,
+ "expected {%s}; found {%s}",
+ print_conflict(expected, b->scratch_pool),
+ print_conflict(found, b->scratch_pool));
+ }
+
+ /* Don't terminate the comparison: accumulate all differences. */
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+check_db_conflicts(svn_test__sandbox_t *b,
+ const char *root_path,
+ const conflict_info_t *expected_conflicts)
+{
+ svn_sqlite__db_t *sdb;
+ int i;
+ svn_sqlite__stmt_t *stmt;
+
+ svn_boolean_t have_row;
+ apr_hash_t *found_hash = apr_hash_make(b->pool);
+ apr_hash_t *expected_hash = apr_hash_make(b->pool);
+ apr_pool_t *iterpool = svn_pool_create(b->pool);
+ apr_hash_index_t *hi;
+ comparison_baton_t comparison_baton;
+
+ comparison_baton.expected_hash = expected_hash;
+ comparison_baton.found_hash = found_hash;
+ comparison_baton.scratch_pool = b->pool;
+ comparison_baton.errors = NULL;
+
+ /* Fill ACTUAL_HASH with data from the WC DB. */
+ SVN_ERR(open_wc_db(&sdb, b->wc_abspath, b->pool, b->pool));
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_ACTUAL_INFO));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", (apr_int64_t)1 /* wc_id */,
+ root_path));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ while (have_row)
+ {
+ conflict_info_t *row = apr_pcalloc(b->pool, sizeof(*row));
+
+ row->local_relpath = svn_sqlite__column_text(stmt, 0, b->pool);
+
+ svn_hash_sets(found_hash, row->local_relpath, row);
+
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ }
+ SVN_ERR(svn_sqlite__reset(stmt));
+ SVN_ERR(svn_sqlite__close(sdb));
+
+ for (hi = apr_hash_first(b->pool, found_hash); hi; hi = apr_hash_next(hi))
+ {
+ svn_skel_t *conflict;
+ conflict_info_t *info = apr_hash_this_val(hi);
+ const char *local_abspath;
+ svn_boolean_t tree_conflicted;
+
+ svn_pool_clear(iterpool);
+
+ local_abspath = svn_dirent_join(b->wc_abspath, info->local_relpath,
+ iterpool);
+
+ SVN_ERR(svn_wc__db_read_conflict(&conflict, NULL, NULL,
+ b->wc_ctx->db, local_abspath,
+ iterpool, iterpool));
+
+ SVN_TEST_ASSERT(conflict != NULL);
+
+ SVN_ERR(svn_wc__conflict_read_info(NULL, NULL,
+ &info->text_conflicted,
+ &info->prop_conflicted,
+ &tree_conflicted,
+ b->wc_ctx->db, local_abspath,
+ conflict,
+ iterpool, iterpool));
+
+ if (tree_conflicted)
+ {
+ const char *move_src_abspath;
+ SVN_ERR(svn_wc__conflict_read_tree_conflict(&info->tc.reason,
+ &info->tc.action,
+ &move_src_abspath,
+ b->wc_ctx->db,
+ local_abspath,
+ conflict,
+ b->pool, iterpool));
+
+ if (move_src_abspath)
+ info->tc.delete_path =
+ svn_dirent_skip_ancestor(b->wc_abspath, move_src_abspath);
+
+ if (!info->tc.reason
+ && !info->tc.action
+ && !info->tc.delete_path)
+ {
+ info->tc.conflicted_fb = TRUE;
+ }
+ }
+ }
+
+ /* Fill EXPECTED_HASH with data from EXPECTED_ROWS. */
+ if (expected_conflicts)
+ for (i = 0; expected_conflicts[i].local_relpath != NULL; i++)
+ {
+ const conflict_info_t *row = &expected_conflicts[i];
+
+ svn_hash_sets(expected_hash, row->local_relpath, row);
+ }
+
+ /* Compare EXPECTED_HASH with ACTUAL_HASH and return any errors. */
+ SVN_ERR(svn_hash_diff(expected_hash, found_hash,
+ compare_conflict_info, &comparison_baton, b->pool));
+ return comparison_baton.errors;
+}
+
+static svn_error_t *
+verify_db_callback(void *baton,
+ const char *wc_abspath,
+ const char *local_relpath,
+ int op_depth,
+ int id,
+ const char *msg,
+ apr_pool_t *scratch_pool)
+{
+ if (op_depth >= 0)
+ return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
+ "Verify: %s: %s (%d): SV%04d %s",
+ wc_abspath, local_relpath, op_depth, id, msg);
+ else
+ return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
+ "DB-VRFY: %s: %s: SV%04d %s",
+ wc_abspath, local_relpath, id, msg);
+}
+
+static svn_error_t *
+verify_db(svn_test__sandbox_t *b)
+{
+ SVN_ERR(svn_wc__db_verify_db_full(b->wc_ctx->db, b->wc_abspath,
+ verify_db_callback, NULL, b->pool));
+
+ return SVN_NO_ERROR;
+}
+
/* ---------------------------------------------------------------------- */
/* The test functions */
@@ -374,7 +632,7 @@ wc_wc_copies(svn_test__sandbox_t *b)
/* Create the various kinds of source node which will be copied */
- sbox_file_write(b, source_added_file, "New file");
+ SVN_ERR(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));
@@ -578,7 +836,7 @@ repo_wc_copies(svn_test__sandbox_t *b)
}
/* Perform each copy. */
- SVN_ERR(svn_client_create_context(&ctx, b->pool));
+ SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
for (subtest = subtests; subtest->from_path; subtest++)
{
svn_opt_revision_t rev = { svn_opt_revision_number, { 1 } };
@@ -647,7 +905,7 @@ test_deletes(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(svn_test__sandbox_create(&b, "deletes", opts, pool));
SVN_ERR(sbox_add_and_commit_greek_tree(&b));
- sbox_file_write(&b, "A/B/E/new-file", "New file");
+ SVN_ERR(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[] = {
@@ -709,7 +967,7 @@ test_adds(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(sbox_add_and_commit_greek_tree(&b));
/* add file */
- sbox_file_write(&b, "new-file", "New file");
+ SVN_ERR(sbox_file_write(&b, "new-file", "New file"));
SVN_ERR(sbox_wc_add(&b, "new-file"));
{
nodes_row_t rows[] = {
@@ -731,7 +989,7 @@ test_adds(const svn_test_opts_t *opts, apr_pool_t *pool)
/* replace file */
SVN_ERR(sbox_wc_delete(&b, "iota"));
- sbox_file_write(&b, "iota", "New iota file");
+ SVN_ERR(sbox_file_write(&b, "iota", "New iota file"));
SVN_ERR(sbox_wc_add(&b, "iota"));
{
nodes_row_t rows[] = {
@@ -766,12 +1024,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(svn_test__sandbox_create(&b, "test_adds_change_kind", opts, pool));
SVN_ERR(sbox_add_and_commit_greek_tree(&b));
/* replace dir with file */
SVN_ERR(sbox_wc_delete(&b, "A/B/E"));
- sbox_file_write(&b, "A/B/E", "New E file");
+ SVN_ERR(sbox_file_write(&b, "A/B/E", "New E file"));
SVN_ERR(sbox_wc_add(&b, "A/B/E"));
{
nodes_row_t rows[] = {
@@ -1024,47 +1282,53 @@ insert_dirs(svn_test__sandbox_t *b,
{
svn_sqlite__db_t *sdb;
svn_sqlite__stmt_t *stmt;
- static const char * const statements[] = {
- "DELETE FROM nodes;",
- "INSERT INTO nodes (local_relpath, op_depth, presence, repos_path,"
- " revision, wc_id, repos_id, kind, depth)"
- " VALUES (?1, ?2, ?3, ?4, ?5, 1, 1, 'dir', 'infinity');",
- "INSERT INTO nodes (local_relpath, op_depth, presence, repos_path,"
- " revision, parent_relpath, wc_id, repos_id, kind, depth)"
- " VALUES (?1, ?2, ?3, ?4, ?5, ?6, 1, 1, 'dir', 'infinity');",
- NULL,
- };
- SVN_ERR(open_wc_db(&sdb, b->wc_abspath, statements, b->pool, b->pool));
+ SVN_ERR(open_wc_db(&sdb, b->wc_abspath, b->pool, b->pool));
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, 0));
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_DELETE_NODES));
SVN_ERR(svn_sqlite__step_done(stmt));
while(nodes->local_relpath)
{
- if (nodes->local_relpath[0])
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "sdssrs",
+ nodes->local_relpath,
+ nodes->op_depth,
+ nodes->presence,
+ nodes->repo_relpath,
+ nodes->repo_revnum,
+ nodes->local_relpath[0]
+ ? svn_relpath_dirname(nodes->local_relpath,
+ b->pool)
+ : NULL));
+
+ if (nodes->moved_to)
+ SVN_ERR(svn_sqlite__bind_text(stmt, 7, nodes->moved_to));
+ if (nodes->moved_here)
+ SVN_ERR(svn_sqlite__bind_int(stmt, 8, 1));
+ if (nodes->props)
{
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, 2));
- SVN_ERR(svn_sqlite__bindf(stmt, "sdssrs",
- nodes->local_relpath,
- nodes->op_depth,
- nodes->presence,
- nodes->repo_relpath,
- nodes->repo_revnum,
- svn_relpath_dirname(nodes->local_relpath,
- b->pool)));
+ int i;
+ apr_hash_t *props = apr_hash_make(b->pool);
+ apr_array_header_t *names = svn_cstring_split(nodes->props, ",",
+ TRUE, b->pool);
+
+ for (i = 0; i < names->nelts; i++)
+ {
+ const char *name = APR_ARRAY_IDX(names, i, const char *);
+ svn_hash_sets(props, name, svn_string_create(name, b->pool));
+ }
+
+ SVN_ERR(svn_sqlite__bind_properties(stmt, 9, props, b->pool));
}
- else
+ else if (nodes->repo_relpath
+ && strcmp(nodes->presence, "normal") == 0)
{
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, 1));
- SVN_ERR(svn_sqlite__bindf(stmt, "sdssr",
- nodes->local_relpath,
- nodes->op_depth,
- nodes->presence,
- nodes->repo_relpath,
- nodes->repo_revnum));
+ SVN_ERR(svn_sqlite__bind_text(stmt, 9, "()"));
}
+ /* File externals? */
+
SVN_ERR(svn_sqlite__step_done(stmt));
++nodes;
}
@@ -1102,7 +1366,7 @@ 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, NULL,
b->pool));
after = apr_palloc(b->pool, sizeof(*after) * (apr_size_t)(num_before + num_added + 1));
@@ -1115,9 +1379,7 @@ 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,
- FALSE /* keep_as_Working */,
- FALSE /* queue_deletes */,
- FALSE /* remove_locks */,
+ FALSE, FALSE, FALSE,
SVN_INVALID_REVNUM,
NULL, NULL, b->pool));
SVN_ERR(svn_wc__wq_run(b->wc_ctx->db, dir_abspath,
@@ -1427,29 +1689,11 @@ test_base_dir_insert_remove(const svn_test_opts_t *opts, apr_pool_t *pool)
}
static svn_error_t *
-temp_op_make_copy(svn_test__sandbox_t *b,
- const char *local_relpath,
- nodes_row_t *before,
- nodes_row_t *after)
-{
- const char *dir_abspath = svn_path_join(b->wc_abspath, local_relpath,
- b->pool);
-
- SVN_ERR(insert_dirs(b, before));
-
- 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));
-
- return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-test_temp_op_make_copy(const svn_test_opts_t *opts, apr_pool_t *pool)
+test_db_make_copy(const svn_test_opts_t *opts, apr_pool_t *pool)
{
svn_test__sandbox_t b;
- SVN_ERR(svn_test__sandbox_create(&b, "temp_op_make_copy", opts, pool));
+ SVN_ERR(svn_test__sandbox_create(&b, "make_copy", opts, pool));
{
/* / norm -
@@ -1480,7 +1724,7 @@ test_temp_op_make_copy(const svn_test_opts_t *opts, apr_pool_t *pool)
{ 2, "A/F", "normal", 1, "S2" },
{ 2, "A/F/G", "normal", 1, "S2/G" },
{ 2, "A/F/H", "not-present", 1, "S2/H" },
- { 2, "A/F/E", "base-deleted", 2, "A/F/E" },
+ { 2, "A/F/E", "base-deleted", NO_COPY_FROM },
{ 0 }
};
/* / norm -
@@ -1518,14 +1762,18 @@ test_temp_op_make_copy(const svn_test_opts_t *opts, apr_pool_t *pool)
{ 2, "A/B", "normal", NO_COPY_FROM },
{ 2, "A/B/C", "base-deleted", NO_COPY_FROM },
{ 2, "A/F", "normal", 1, "S2" },
- { 2, "A/F/E", "base-deleted", 2, "A/F/E" },
+ { 2, "A/F/E", "base-deleted", NO_COPY_FROM },
{ 2, "A/F/G", "normal", 1, "S2/G" },
{ 2, "A/F/H", "not-present", 1, "S2/H" },
{ 3, "A/B/C", "normal", NO_COPY_FROM },
{ 0 }
};
- SVN_ERR(temp_op_make_copy(&b, "A", before, after));
+ SVN_ERR(insert_dirs(&b, before));
+ SVN_ERR(svn_wc__db_op_make_copy(b.wc_ctx->db, sbox_wc_path(&b, "A"),
+ NULL, NULL, pool));
+
+ SVN_ERR(check_db_rows(&b, "", after));
}
return SVN_NO_ERROR;
@@ -1821,46 +2069,32 @@ insert_actual(svn_test__sandbox_t *b,
{
svn_sqlite__db_t *sdb;
svn_sqlite__stmt_t *stmt;
- static const char * const statements[] = {
- "DELETE FROM actual_node;",
- "INSERT INTO actual_node (local_relpath, changelist, wc_id)"
- " VALUES (?1, ?2, 1)",
- "INSERT INTO actual_node (local_relpath, parent_relpath, changelist, wc_id)"
- " VALUES (?1, ?2, ?3, 1)",
- "UPDATE nodes SET kind = 'file' WHERE wc_id = 1 and local_relpath = ?1",
- NULL,
- };
if (!actual)
return SVN_NO_ERROR;
- SVN_ERR(open_wc_db(&sdb, b->wc_abspath, statements, b->pool, b->pool));
+ SVN_ERR(open_wc_db(&sdb, b->wc_abspath, b->pool, b->pool));
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, 0));
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_DELETE_ACTUAL));
SVN_ERR(svn_sqlite__step_done(stmt));
while(actual->local_relpath)
{
- if (actual->local_relpath[0])
- {
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, 2));
- SVN_ERR(svn_sqlite__bindf(stmt, "sss",
- actual->local_relpath,
- svn_relpath_dirname(actual->local_relpath,
- b->pool),
- actual->changelist));
- }
- else
- {
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, 1));
- SVN_ERR(svn_sqlite__bindf(stmt, "ss",
- actual->local_relpath,
- actual->changelist));
- }
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_ACTUAL));
+ SVN_ERR(svn_sqlite__bindf(stmt, "sss",
+ actual->local_relpath,
+ actual->local_relpath[0]
+ ? svn_relpath_dirname(actual->local_relpath,
+ b->pool)
+ : NULL,
+ actual->changelist));
SVN_ERR(svn_sqlite__step_done(stmt));
if (actual->changelist)
{
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, 3));
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+ STMT_ENSURE_EMPTY_PRISTINE));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_NODES_SET_FILE));
SVN_ERR(svn_sqlite__bindf(stmt, "s", actual->local_relpath));
SVN_ERR(svn_sqlite__step_done(stmt));
}
@@ -1876,10 +2110,6 @@ check_db_actual(svn_test__sandbox_t* b, actual_row_t *rows)
{
svn_sqlite__db_t *sdb;
svn_sqlite__stmt_t *stmt;
- static const char * const statements[] = {
- "SELECT local_relpath FROM actual_node WHERE wc_id = 1;",
- NULL,
- };
svn_boolean_t have_row;
apr_hash_t *path_hash = apr_hash_make(b->pool);
@@ -1893,15 +2123,15 @@ check_db_actual(svn_test__sandbox_t* b, actual_row_t *rows)
++rows;
}
- SVN_ERR(open_wc_db(&sdb, b->wc_abspath, statements, b->pool, b->pool));
+ SVN_ERR(open_wc_db(&sdb, b->wc_abspath, b->pool, b->pool));
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, 0));
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_ALL_ACTUAL));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
while (have_row)
{
const char *local_relpath = svn_sqlite__column_text(stmt, 0, b->pool);
if (!apr_hash_get(path_hash, local_relpath, APR_HASH_KEY_STRING))
- return svn_error_createf(SVN_ERR_TEST_FAILED, svn_sqlite__close(sdb),
+ return svn_error_createf(SVN_ERR_TEST_FAILED, svn_sqlite__reset(stmt),
"actual '%s' unexpected", local_relpath);
apr_hash_set(path_hash, local_relpath, APR_HASH_KEY_STRING, NULL);
SVN_ERR(svn_sqlite__step(&have_row, stmt));
@@ -1910,8 +2140,8 @@ check_db_actual(svn_test__sandbox_t* b, actual_row_t *rows)
if (apr_hash_count(path_hash))
{
const char *local_relpath
- = svn__apr_hash_index_key(apr_hash_first(b->pool, path_hash));
- return svn_error_createf(SVN_ERR_TEST_FAILED, svn_sqlite__close(sdb),
+ = apr_hash_this_key(apr_hash_first(b->pool, path_hash));
+ return svn_error_createf(SVN_ERR_TEST_FAILED, svn_sqlite__reset(stmt),
"actual '%s' expected", local_relpath);
}
@@ -1943,7 +2173,7 @@ revert(svn_test__sandbox_t *b,
SVN_ERR(insert_actual(b, before_actual));
SVN_ERR(check_db_rows(b, "", before_nodes));
SVN_ERR(check_db_actual(b, before_actual));
- err = svn_wc__db_op_revert(b->wc_ctx->db, local_abspath, depth,
+ err = svn_wc__db_op_revert(b->wc_ctx->db, local_abspath, depth, FALSE,
b->pool, b->pool);
if (err)
{
@@ -2511,7 +2741,7 @@ check_hash_keys(apr_hash_t *hash,
for (hi = apr_hash_first(scratch_pool, hash); hi;
hi = apr_hash_next(hi))
{
- const char *name = svn__apr_hash_index_key(hi);
+ const char *name = apr_hash_this_key(hi);
err = svn_error_compose_create(
err, svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
_("Found, not expected: '%s'"), name));
@@ -2613,8 +2843,8 @@ test_children_of_replaced_dir(const svn_test_opts_t *opts, apr_pool_t *pool)
&children_array, b.wc_ctx->db, A_abspath, pool, pool));
SVN_ERR(CHECK_ARRAY(children_array, working_children_inc_hidden, pool));
- SVN_ERR(svn_wc__node_get_children(&children_array, b.wc_ctx, A_abspath,
- TRUE /* show_hidden */, pool, pool));
+ SVN_ERR(svn_wc__db_read_children(&children_array, b.wc_ctx->db, A_abspath,
+ pool, pool));
SVN_ERR(CHECK_ARRAY(children_array, all_children_inc_hidden, pool));
/* I am not testing svn_wc__node_get_children(show_hidden=FALSE) because
@@ -2623,17 +2853,14 @@ test_children_of_replaced_dir(const svn_test_opts_t *opts, apr_pool_t *pool)
* a 'hidden' child of the working dir (so should be excluded). */
SVN_ERR(svn_wc__node_get_children_of_working_node(
- &children_array, b.wc_ctx, A_abspath, TRUE /* show_hidden */,
- pool, pool));
- SVN_ERR(CHECK_ARRAY(children_array, working_children_inc_hidden, pool));
-
- SVN_ERR(svn_wc__node_get_children_of_working_node(
- &children_array, b.wc_ctx, A_abspath, FALSE /* show_hidden */,
+ &children_array, b.wc_ctx, A_abspath,
pool, pool));
SVN_ERR(CHECK_ARRAY(children_array, working_children_exc_hidden, pool));
SVN_ERR(svn_wc__db_read_children_info(&children_hash, &conflicts_hash,
- b.wc_ctx->db, A_abspath, pool, pool));
+ b.wc_ctx->db, A_abspath,
+ FALSE /* base_tree_only */,
+ pool, pool));
SVN_ERR(CHECK_HASH(children_hash, all_children_inc_hidden, pool));
/* We don't yet have a svn_wc__db_read_children_info2() to test. */
@@ -2970,7 +3197,7 @@ 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. */
- sbox_file_write(&b, "iota", "This is iota");
+ SVN_ERR(sbox_file_write(&b, "iota", "This is iota"));
SVN_ERR(sbox_wc_add(&b, "iota"));
SVN_ERR(sbox_wc_commit(&b, ""));
@@ -2985,7 +3212,7 @@ test_shadowed_update(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(sbox_wc_commit(&b, ""));
/* And change something in r3 */
- sbox_file_write(&b, "iota", "This is a new iota");
+ SVN_ERR(sbox_file_write(&b, "iota", "This is a new iota"));
SVN_ERR(sbox_wc_commit(&b, ""));
/* And delete C & M */
@@ -3306,12 +3533,12 @@ 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));
- sbox_file_write(&b, "f", "this is f\n");
+ SVN_ERR(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_file_write(&b, "g", "this is f\nmodified via g\n"));
SVN_ERR(sbox_wc_commit(&b, ""));
SVN_ERR(sbox_wc_update(&b, "", 2));
@@ -3334,7 +3561,7 @@ 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_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, ""));
@@ -3356,11 +3583,13 @@ revert_file_externals(const svn_test_opts_t *opts, apr_pool_t *pool)
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, "", "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, "g", "not-present", 0, "g"},
{ 0 }
};
SVN_ERR(check_db_rows(&b, "", rows));
@@ -3369,10 +3598,12 @@ revert_file_externals(const svn_test_opts_t *opts, apr_pool_t *pool)
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, "", "normal", 1, "" },
+ { 0, "f", "normal", 1, "f" },
+ { 0, "h", "normal", 1, "f", TRUE },
+ { 0, "A/g", "normal", 1, "f", TRUE },
+
+ { 0, "g", "not-present", 0, "g"},
{ 0 }
};
SVN_ERR(check_db_rows(&b, "", rows));
@@ -3381,9 +3612,11 @@ revert_file_externals(const svn_test_opts_t *opts, apr_pool_t *pool)
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, "", "normal", 1, "" },
+ { 0, "f", "normal", 1, "f" },
+ { 0, "g", "normal", 1, "f", TRUE },
+
+ { 0, "h", "not-present", 0, "h"},
{ 0 }
};
SVN_ERR(check_db_rows(&b, "", rows));
@@ -3398,7 +3631,7 @@ 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_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"));
@@ -3560,6 +3793,8 @@ incomplete_switch(const svn_test_opts_t *opts, apr_pool_t *pool)
};
SVN_ERR(insert_dirs(&b, before));
+ SVN_ERR(svn_io_remove_dir2(sbox_wc_path(&b, "A/B/C/D"), FALSE,
+ NULL, NULL, pool));
SVN_ERR(check_db_rows(&b, "", before));
SVN_ERR(sbox_wc_update(&b, "", 4));
SVN_ERR(check_db_rows(&b, "", after_update));
@@ -4430,27 +4665,27 @@ move_update(const svn_test_opts_t *opts, apr_pool_t *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_file_write(&b, "A/B/f", "r1 content\n"));
+ SVN_ERR(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_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_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_file_write(&b, "X/f", "r4 content\n"));
+ SVN_ERR(sbox_file_write(&b, "X/g", "r4 content\n"));
+ SVN_ERR(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"));
@@ -5031,8 +5266,10 @@ mixed_rev_move(const svn_test_opts_t *opts, apr_pool_t *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_mkdir(&b, "A/D"));
SVN_ERR(sbox_wc_commit(&b, ""));
SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/D/E"));
SVN_ERR(sbox_wc_commit(&b, ""));
{
@@ -5041,6 +5278,8 @@ mixed_rev_move(const svn_test_opts_t *opts, apr_pool_t *pool)
{0, "A", "normal", 1, "A"},
{0, "A/B", "normal", 2, "A/B"},
{0, "A/B/C", "normal", 3, "A/B/C"},
+ {0, "A/D", "normal", 2, "A/D"},
+ {0, "A/D/E", "normal", 3, "A/D/E"},
{0}
};
SVN_ERR(check_db_rows(&b, "", nodes));
@@ -5060,20 +5299,30 @@ mixed_rev_move(const svn_test_opts_t *opts, apr_pool_t *pool)
{0, "A", "normal", 1, "A"},
{0, "A/B", "normal", 2, "A/B"},
{0, "A/B/C", "normal", 3, "A/B/C"},
+ {0, "A/D", "normal", 2, "A/D"},
+ {0, "A/D/E", "normal", 3, "A/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/D", "base-deleted", NO_COPY_FROM},
+ {1, "A/D/E", "base-deleted", NO_COPY_FROM},
{1, "X", "normal", 1, "A", MOVED_HERE},
{1, "X/B", "not-present", 2, "A/B"},
+ {1, "X/D", "not-present", 2, "A/D"},
{2, "X/B", "normal", 2, "A/B"},
{2, "X/B/C", "not-present", 3, "A/B/C"},
+ {2, "X/D", "normal", 2, "A/D"},
+ {2, "X/D/E", "not-present", 3, "A/D/E"},
{3, "X/B/C", "normal", 3, "A/B/C"},
+ {3, "X/D/E", "normal", 3, "A/D/E"},
+
{0}
};
SVN_ERR(check_db_rows(&b, "", nodes));
}
/* ### These values PASS but I'm not sure they are correct. */
+ /* A/B/C doesn't exist as X/B/C at op depth 1, but is reported */
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"));
@@ -5099,32 +5348,109 @@ mixed_rev_move(const svn_test_opts_t *opts, apr_pool_t *pool)
{0, "A", "normal", 1, "A"},
{0, "A/B", "normal", 2, "A/B"},
{0, "A/B/C", "normal", 3, "A/B/C"},
+ {0, "A/D", "normal", 2, "A/D"},
+ {0, "A/D/E", "normal", 3, "A/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/D", "base-deleted", NO_COPY_FROM},
+ {1, "A/D/E", "base-deleted", NO_COPY_FROM},
{1, "X", "normal", 1, "A", MOVED_HERE},
{1, "X/B", "not-present", 2, "A/B"},
+ {1, "X/D", "not-present", 2, "A/D"},
+ {2, "X/D", "normal", 2, "A/D"},
+ {2, "X/D/E", "not-present", 3, "A/D/E"},
{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"},
+ {3, "X/D/E", "normal", 3, "A/D/E"},
+
{0}
};
SVN_ERR(check_db_rows(&b, "", nodes));
}
+ /* A/B/C still doesn't exist as X/B/C at op depth 1 */
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(check_moved_to(moved_tos, 0, 1, "X/B/C"));
+ SVN_TEST_ASSERT(moved_tos->nelts == 1);
+ /* A/B doesn't exist exist as X/B and the move to Y can't be tracked in
+ the current scheme */
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(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);
+
+
+ SVN_ERR(sbox_wc_mkdir(&b, "Z"));
+ SVN_ERR(sbox_wc_commit(&b, "Z")); /* r4 */
+
+ SVN_ERR(sbox_wc_update(&b, "", 4));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 4, ""},
+ {0, "A", "normal", 4, "A"},
+ {0, "A/B", "normal", 4, "A/B"},
+ {0, "A/B/C", "normal", 4, "A/B/C"},
+ {0, "A/D", "normal", 4, "A/D"},
+ {0, "A/D/E", "normal", 4, "A/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/D", "base-deleted", NO_COPY_FROM},
+ {1, "A/D/E", "base-deleted", NO_COPY_FROM},
+ /* X is expanded on update. The not-present nodes are now here */
+ {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/D", "normal", 4, "A/D", MOVED_HERE},
+ {1, "X/D/E", "normal", 4, "A/D/E", MOVED_HERE},
+ {2, "X/D", "normal", 2, "A/D"},
+ {2, "X/D/E", "not-present", 3, "A/D/E"},
+ {2, "X/Y", "normal", 2, "A/B"},
+ {2, "X/Y/C", "not-present", NO_COPY_FROM},
+ {3, "X/D/E", "normal", 3, "A/D/E"},
+ {3, "X/Y/C", "normal", 3, "A/B/C"},
+
+ {0, "Z", "normal", 4, "Z"},
+ {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_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);
+ {
+ conflict_info_t conflicts[] = {
+ { "X/D", FALSE, FALSE, {0 /* ### Needs fixing */} },
+ {0}
+ };
+
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+
return SVN_NO_ERROR;
}
@@ -5140,8 +5466,8 @@ update_prop_mod_into_moved(const svn_test_opts_t *opts, apr_pool_t *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_file_write(&b, "A/B/f", "r1 content\n"));
+ SVN_ERR(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"));
@@ -5152,14 +5478,14 @@ update_prop_mod_into_moved(const svn_test_opts_t *opts, apr_pool_t *pool)
/* 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_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_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"));
@@ -5222,9 +5548,22 @@ update_prop_mod_into_moved(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(check_db_rows(&b, "", nodes));
}
+ {
+ conflict_info_t conflicts[] = {
+ { "A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "A"}},
+ {0}
+ };
+
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+
/* Resolve should update the move. */
SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
svn_wc_conflict_choose_mine_conflict));
+
+ SVN_ERR(check_db_conflicts(&b, "", NULL));
+
{
nodes_row_t nodes[] = {
{0, "", "normal", 2, ""},
@@ -5259,12 +5598,12 @@ nested_move_update(const svn_test_opts_t *opts, apr_pool_t *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"));
- sbox_file_write(&b, "A/B/C/f", "r1 content\n");
+ SVN_ERR(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_file_write(&b, "A/B/C/f", "r1 content\nr2 content\n"));
SVN_ERR(sbox_wc_commit(&b, ""));
/* r3: Create 'X' */
@@ -5301,12 +5640,37 @@ nested_move_update(const svn_test_opts_t *opts, apr_pool_t *pool)
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/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", 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));
+ }
+
/* 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));
+ SVN_ERR(check_db_conflicts(&b, "", NULL /* no conflicts */));
{
nodes_row_t nodes[] = {
{0, "", "normal", 2, ""},
@@ -5333,6 +5697,8 @@ nested_move_update(const svn_test_opts_t *opts, apr_pool_t *pool)
/* Update A to r3 brings no changes but updates the revisions. */
SVN_ERR(sbox_wc_update(&b, "A", 3));
+ SVN_ERR(check_db_conflicts(&b, "", NULL /* no conflicts */));
+
{
nodes_row_t nodes[] = {
{0, "", "normal", 2, ""},
@@ -5371,7 +5737,7 @@ nested_move_commit(const svn_test_opts_t *opts, apr_pool_t *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"));
- sbox_file_write(&b, "A/B/C/f", "r1 content\n");
+ SVN_ERR(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));
@@ -5615,10 +5981,12 @@ check_tree_conflict_repos_path(svn_test__sandbox_t *b,
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),
+ SVN_ERR(svn_wc__db_read_conflict(&conflict, NULL, NULL,
+ b->wc_ctx->db, sbox_wc_path(b, wc_path),
b->pool, b->pool));
+ SVN_TEST_ASSERT(conflict != NULL);
+
SVN_ERR(svn_wc__conflict_read_info(&operation, &locations,
&text_conflicted, &prop_conflicted,
&tree_conflicted,
@@ -5632,7 +6000,9 @@ check_tree_conflict_repos_path(svn_test__sandbox_t *b,
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));
+ SVN_TEST_ASSERT(version != NULL);
+
+ SVN_TEST_STRING_ASSERT(version->path_in_repos, repos_path1);
}
if (repos_path2)
@@ -5640,7 +6010,9 @@ check_tree_conflict_repos_path(svn_test__sandbox_t *b,
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));
+ SVN_TEST_ASSERT(version != NULL);
+
+ SVN_TEST_STRING_ASSERT(version->path_in_repos, repos_path2);
}
return SVN_NO_ERROR;
@@ -5666,7 +6038,7 @@ move_update_conflicts(const svn_test_opts_t *opts, apr_pool_t *pool)
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");
+ SVN_ERR(sbox_file_write(&b, "A2/B/F", "obstruction\n"));
{
nodes_row_t nodes[] = {
@@ -5744,7 +6116,7 @@ move_update_delete_mods(const svn_test_opts_t *opts, apr_pool_t *pool)
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_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"));
@@ -5753,7 +6125,7 @@ move_update_delete_mods(const svn_test_opts_t *opts, apr_pool_t *pool)
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_file_write(&b, "B2/C/f", "modified content\n"));
SVN_ERR(sbox_wc_delete(&b, "B2/D"));
{
nodes_row_t nodes[] = {
@@ -5791,7 +6163,16 @@ move_update_delete_mods(const svn_test_opts_t *opts, apr_pool_t *pool)
{2, "B2/C/f", "normal", 1, "A/B/C/f"},
{0}
};
+ conflict_info_t conflicts[] = {
+ {"B2/C", FALSE, FALSE, {svn_wc_conflict_action_delete,
+ svn_wc_conflict_reason_edited}},
+ {"B2/D", FALSE, FALSE, {svn_wc_conflict_action_delete,
+ svn_wc_conflict_reason_deleted}},
+ { 0 }
+ };
+
SVN_ERR(check_db_rows(&b, "", nodes));
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
}
SVN_ERR(check_tree_conflict_repos_path(&b, "B2/C", "A/B/C", "A/B/C"));
@@ -5949,6 +6330,34 @@ move_in_delete(const svn_test_opts_t *opts, apr_pool_t *pool)
}
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/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"},
+
+ {1, "C2", "normal", 2, "A/B/C", MOVED_HERE},
+ {1, "C2/D", "normal", 2, "A/B/C/D", MOVED_HERE},
+
+ {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},
+ {2, "A/B/C/D/E", "base-deleted", NO_COPY_FROM},
+
+ {0}
+ };
+ conflict_info_t conflicts[] = {
+ {"A/B", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_deleted}},
+ {0}
+ };
+
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
SVN_ERR(sbox_wc_revert(&b, "A/B", svn_depth_empty));
{
nodes_row_t nodes[] = {
@@ -5965,7 +6374,14 @@ move_in_delete(const svn_test_opts_t *opts, apr_pool_t *pool)
{1, "C2/D", "normal", 2, "A/B/C/D", MOVED_HERE},
{0}
};
+ conflict_info_t conflicts[] = {
+ {"A/B/C", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "A/B/C"}},
+ {0}
+ };
SVN_ERR(check_db_rows(&b, "", nodes));
+ /* Where did this conflict come from? */
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
}
/* Revert should have left a tree-conflict (or broken the move). */
@@ -5988,6 +6404,7 @@ move_in_delete(const svn_test_opts_t *opts, apr_pool_t *pool)
{0}
};
SVN_ERR(check_db_rows(&b, "", nodes));
+ SVN_ERR(check_db_conflicts(&b, "", NULL));
}
return SVN_NO_ERROR;
@@ -6563,6 +6980,31 @@ commit_moved_descendant(const svn_test_opts_t *opts, apr_pool_t *pool)
shadowed, like in this case. The commit processing doesn't
support this yet though*/
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 0, ""},
+ {0, "A", "normal", 1, "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"},
+ {0, "A_copied", "normal", 2, "A_copied"},
+ {0, "A_copied/A", "normal", 2, "A_copied/A"},
+ {0, "A_copied/A/A", "normal", 2, "A_copied/A/A"},
+ {0, "A_copied/A/A/A", "normal", 2, "A_copied/A/A/A"},
+ {0, "A_copied/A/A/A/A", "normal", 2, "A_copied/A/A/A/A"},
+ {0, "A_copied/A/A/A/A/A","normal", 2, "A_copied/A/A/A/A/A"},
+ {0, "AAA_moved", "normal", 2, "AAA_moved"},
+ {0, "AAA_moved/A", "normal", 2, "AAA_moved/A"},
+ {0, "AAA_moved/A/A", "normal", 2, "AAA_moved/A/A"},
+ {0, "AAA_moved/A/A/A", "normal", 2, "AAA_moved/A/A/A"},
+
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
return SVN_NO_ERROR;
}
@@ -6585,10 +7027,63 @@ commit_moved_away_descendant(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(sbox_wc_delete(&b, "A/A"));
SVN_ERR(sbox_wc_copy(&b, "A_copied/A", "A/A"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 0, ""},
+ {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"},
+ {1, "A_copied", "normal", 1, "A"},
+ {1, "A_copied/A", "normal", 1, "A/A"},
+ {1, "A_copied/A/A", "normal", 1, "A/A/A"},
+ {1, "A_copied/A/A/A", "normal", 1, "A/A/A/A"},
+ {1, "A_copied/A/A/A/A", "normal", 1, "A/A/A/A/A"},
+ {1, "A_copied/A/A/A/A/A", "normal", 1, "A/A/A/A/A/A"},
+ {1, "AAA_moved", "normal", 1, "A/A/A", MOVED_HERE},
+ {1, "AAA_moved/A", "normal", 1, "A/A/A/A", MOVED_HERE},
+ {1, "AAA_moved/A/A", "normal", 1, "A/A/A/A/A", MOVED_HERE},
+ {1, "AAA_moved/A/A/A", "normal", 1, "A/A/A/A/A/A", MOVED_HERE},
+ {2, "A/A", "normal", 1, "A/A"},
+ {2, "A/A/A", "normal", 1, "A/A/A", FALSE, "AAA_moved"},
+ {2, "A/A/A/A", "normal", 1, "A/A/A/A"},
+ {2, "A/A/A/A/A", "normal", 1, "A/A/A/A/A"},
+ {2, "A/A/A/A/A/A", "normal", 1, "A/A/A/A/A/A"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
/* 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"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 0, ""},
+ {0, "A", "normal", 1, "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"},
+ {1, "A_copied", "normal", 1, "A"},
+ {1, "A_copied/A", "normal", 1, "A/A"},
+ {1, "A_copied/A/A", "normal", 1, "A/A/A"},
+ {1, "A_copied/A/A/A", "normal", 1, "A/A/A/A"},
+ {1, "A_copied/A/A/A/A", "normal", 1, "A/A/A/A/A"},
+ {1, "A_copied/A/A/A/A/A", "normal", 1, "A/A/A/A/A/A"},
+ {1, "AAA_moved", "normal", 1, "A/A/A"},
+ {1, "AAA_moved/A", "normal", 1, "A/A/A/A"},
+ {1, "AAA_moved/A/A", "normal", 1, "A/A/A/A/A"},
+ {1, "AAA_moved/A/A/A", "normal", 1, "A/A/A/A/A/A"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
return svn_error_create(SVN_ERR_TEST_FAILED, NULL,
"The commit should have failed");
@@ -6608,7 +7103,7 @@ finite_move_update_bump(const svn_test_opts_t *opts, apr_pool_t *pool)
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_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"));
@@ -6645,10 +7140,27 @@ finite_move_update_bump(const svn_test_opts_t *opts, apr_pool_t *pool)
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));
+ {
+ conflict_info_t conflicts[] = {
+ {"A/B", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "A/B"}},
+ {"P/Q", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "P/Q"}},
+ {0}
+ };
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+
+ SVN_ERR(check_tree_conflict_repos_path(&b, "A/B", "A/B", "A/B"));
+ SVN_ERR(check_tree_conflict_repos_path(&b, "P/Q", "P/Q", "P/Q"));
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);
+
+ /* sbox_wc_resolve() obtains a lock on the target path, so now it
+ will apply the change on the target */
+ SVN_ERR(sbox_wc_resolve(&b, "P/Q", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
{
nodes_row_t nodes[] = {
{0, "", "normal", 1, ""},
@@ -6677,10 +7189,23 @@ finite_move_update_bump(const svn_test_opts_t *opts, apr_pool_t *pool)
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));
+ {
+ conflict_info_t conflicts[] = {
+ {"A/B", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "A/B"}},
+ {"P", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "P"}},
+ {0}
+ };
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+ SVN_ERR(check_tree_conflict_repos_path(&b, "P", "P", "P"));
+ SVN_ERR(check_tree_conflict_repos_path(&b, "A/B", "A/B", "A/B"));
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);
+ SVN_ERR(sbox_wc_resolve(&b, "A/B", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
{
nodes_row_t nodes[] = {
{0, "", "normal", 1, ""},
@@ -6711,10 +7236,24 @@ finite_move_update_bump(const svn_test_opts_t *opts, apr_pool_t *pool)
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));
+ {
+ conflict_info_t conflicts[] = {
+ {"A/B/C", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "A/B/C"}},
+ {"P/Q", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "P/Q"}},
+
+ {0}
+ };
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+ SVN_ERR(check_tree_conflict_repos_path(&b, "A/B/C", "A/B/C", "A/B/C"));
+ SVN_ERR(check_tree_conflict_repos_path(&b, "P/Q", "P/Q", "P/Q"));
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);
+ SVN_ERR(sbox_wc_resolve(&b, "A/B/C", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
{
nodes_row_t nodes[] = {
{0, "", "normal", 1, ""},
@@ -6767,11 +7306,23 @@ move_away_delete_update(const svn_test_opts_t *opts, apr_pool_t *pool)
{0, "", "normal", 2, ""},
{0, "A", "normal", 2, "A"},
{0, "P", "normal", 2, "P"},
- {1, "C2", "normal", 1, "A/B/C"},
+ {1, "C2", "normal", 1, "A/B/C", MOVED_HERE},
{1, "Q2", "normal", 1, "P/Q"},
+
+ {2, "A/B", "normal", 1, "A/B"},
+ {2, "A/B/C", "normal", 1, "A/B/C"},
+ {3, "A/B/C", "base-deleted", NO_COPY_FROM, "C2"},
+ {0}
+ };
+ conflict_info_t conflicts[] = {
+ {"A/B", FALSE, FALSE, {svn_wc_conflict_action_delete,
+ svn_wc_conflict_reason_edited}},
+ {"P/Q", FALSE, FALSE, {svn_wc_conflict_action_delete,
+ svn_wc_conflict_reason_moved_away, "P/Q"}},
{0}
};
SVN_ERR(check_db_rows(&b, "", nodes));
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
}
return SVN_NO_ERROR;
@@ -7092,7 +7643,7 @@ 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",
+ SVN_ERR(svn_test__sandbox_create(&b, "movedto_opdepth",
opts, pool));
SVN_ERR(sbox_wc_mkdir(&b, "A"));
@@ -7731,6 +8282,42 @@ move_depth_expand(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(sbox_wc_update_depth(&b, "", 1, svn_depth_infinity, TRUE));
+ /* 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/B", "not-present", 0, "A/B", MOVED_HERE},
+
+ {2, "C/B", "normal", 1, "A/A" },
+
+ {3, "C/A/A", "normal", NO_COPY_FROM },
+ {3, "C/B/A", "normal", NO_COPY_FROM },
+
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
/* 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));
@@ -7762,10 +8349,6 @@ move_depth_expand(const svn_test_opts_t *opts, apr_pool_t *pool)
{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 },
@@ -7774,6 +8357,8 @@ move_depth_expand(const svn_test_opts_t *opts, apr_pool_t *pool)
{2, "C/B/A", "base-deleted", NO_COPY_FROM },
{2, "C/B/A/A", "base-deleted", NO_COPY_FROM },
+ {3, "C/A/A", "normal", NO_COPY_FROM },
+ {3, "C/A/A/A", "base-deleted", NO_COPY_FROM },
{3, "C/B/A", "normal", NO_COPY_FROM },
{0}
@@ -7878,7 +8463,15 @@ move_retract(const svn_test_opts_t *opts, apr_pool_t *pool)
{0}
};
+ conflict_info_t conflicts[] = {
+ {"A/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "A/A"}},
+ {"A/B", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_replaced}},
+ { 0 },
+ };
SVN_ERR(check_db_rows(&b, "", nodes));
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
}
@@ -7909,9 +8502,21 @@ move_retract(const svn_test_opts_t *opts, apr_pool_t *pool)
/* Still conflicted */
{1, "D", "normal", 1, "A/B/A/D", MOVED_HERE },
+ {4, "A/B/A/C", "normal", 1, "A/A/A/C"},
+
+
+ {0}
+ };
+ conflict_info_t conflicts[] = {
+ {"A/B", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_replaced}},
+ {"A/B/A/C", FALSE, FALSE, {svn_wc_conflict_action_delete,
+ svn_wc_conflict_reason_edited}},
{0}
};
+
SVN_ERR(check_db_rows(&b, "", nodes));
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
}
/* ### TODO: Resolve via which specific target? */
@@ -7921,7 +8526,7 @@ move_retract(const svn_test_opts_t *opts, apr_pool_t *pool)
{
nodes_row_t nodes[] = {
- {1, "D", "normal", 2, "A/B/A/D", MOVED_HERE },
+ {1, "D", "normal", 1, "A/B/A/D", MOVED_HERE },
{0}
};
@@ -7941,7 +8546,7 @@ move_delete_file_externals(const svn_test_opts_t *opts, apr_pool_t *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_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"));
@@ -8158,6 +8763,128 @@ update_with_tree_conflict(const svn_test_opts_t *opts, apr_pool_t *pool)
}
static svn_error_t *
+move_update_parent_replace(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_update_parent_replace", 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_delete(&b, "A/B"));
+ 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/C", "A/C"));
+
+ /* Update breaks the move and leaves a conflict. */
+ 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"},
+
+ {2, "A/C", "normal", 1, "A/B/C", MOVED_HERE},
+
+ {2, "A/B", "normal", 1, "A/B"},
+ {2, "A/B/C", "normal", 1, "A/B/C", FALSE},
+
+ {3, "A/B/C", "base-deleted", NO_COPY_FROM, "A/C"},
+
+ {0}
+ };
+ conflict_info_t conflicts[] = {
+ {"A/B", FALSE, FALSE, {svn_wc_conflict_action_replace,
+ svn_wc_conflict_reason_edited}},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+
+ SVN_ERR(sbox_wc_resolve(&b, "A/B", svn_depth_infinity,
+ svn_wc_conflict_choose_merged));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 2, ""},
+ {0, "A", "normal", 2, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {2, "A/C", "normal", 1, "A/B/C", MOVED_HERE},
+ {2, "A/B", "normal", 1, "A/B"},
+ {2, "A/B/C", "normal", 1, "A/B/C", FALSE},
+ {3, "A/B/C", "base-deleted", NO_COPY_FROM, "A/C"},
+
+ {0}
+ };
+
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ SVN_ERR(check_db_conflicts(&b, "", NULL));
+ }
+
+ 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_child_to_parent_revert(const svn_test_opts_t *opts, apr_pool_t *pool)
{
svn_test__sandbox_t b;
@@ -8493,61 +9220,6 @@ move_revert_intermediate(const svn_test_opts_t *opts, apr_pool_t *pool)
}
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;
@@ -8650,15 +9322,15 @@ move_twice_within_delete(const svn_test_opts_t *opts, apr_pool_t *pool)
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 },
@@ -8703,73 +9375,1160 @@ move_twice_within_delete(const svn_test_opts_t *opts, apr_pool_t *pool)
return SVN_NO_ERROR;
}
+/* Helper function for 4 move4 tests */
static svn_error_t *
-repo_wc_copy(const svn_test_opts_t *opts, apr_pool_t *pool)
+init_move4(svn_test__sandbox_t *sandbox,
+ const char *test_name,
+ const svn_test_opts_t *opts,
+ svn_boolean_t move_away,
+ apr_pool_t *pool)
+{
+ SVN_ERR(svn_test__sandbox_create(sandbox, test_name, opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(sandbox, "A"));
+ SVN_ERR(sbox_wc_mkdir(sandbox, "A/A"));
+ SVN_ERR(sbox_wc_mkdir(sandbox, "A/A/A"));
+ SVN_ERR(sbox_wc_mkdir(sandbox, "A/A/A/A"));
+
+ SVN_ERR(sbox_wc_mkdir(sandbox, "B"));
+ SVN_ERR(sbox_wc_mkdir(sandbox, "B/A"));
+ SVN_ERR(sbox_wc_mkdir(sandbox, "B/A/A"));
+ SVN_ERR(sbox_wc_mkdir(sandbox, "B/A/A/A"));
+
+ SVN_ERR(sbox_wc_mkdir(sandbox, "C"));
+ SVN_ERR(sbox_wc_mkdir(sandbox, "C/A"));
+ SVN_ERR(sbox_wc_mkdir(sandbox, "C/A/A"));
+ SVN_ERR(sbox_wc_mkdir(sandbox, "C/A/A/A"));
+
+ SVN_ERR(sbox_wc_mkdir(sandbox, "D"));
+ SVN_ERR(sbox_wc_mkdir(sandbox, "D/A"));
+ SVN_ERR(sbox_wc_mkdir(sandbox, "D/A/A"));
+ SVN_ERR(sbox_wc_mkdir(sandbox, "D/A/A/A"));
+
+ SVN_ERR(sbox_wc_commit(sandbox, "")); /* r1 */
+
+ if (strstr(test_name, "_edit_"))
+ {
+ SVN_ERR(sbox_wc_propset(sandbox, "key", "value", "A/A/A"));
+ SVN_ERR(sbox_wc_propset(sandbox, "key", "value", "B/A/A"));
+ SVN_ERR(sbox_wc_propset(sandbox, "key", "value", "C/A/A"));
+ SVN_ERR(sbox_wc_propset(sandbox, "key", "value", "D/A/A"));
+ SVN_ERR(sbox_wc_propset(sandbox, "key", "value", "A/A/A/A"));
+ SVN_ERR(sbox_wc_propset(sandbox, "key", "value", "B/A/A/A"));
+ SVN_ERR(sbox_wc_propset(sandbox, "key", "value", "C/A/A/A"));
+ SVN_ERR(sbox_wc_propset(sandbox, "key", "value", "D/A/A/A"));
+ }
+ else if (strstr(test_name, "_delete_"))
+ {
+ SVN_ERR(sbox_wc_delete(sandbox, "A/A/A/A"));
+ SVN_ERR(sbox_wc_delete(sandbox, "B/A/A/A"));
+ SVN_ERR(sbox_wc_delete(sandbox, "C/A/A/A"));
+ SVN_ERR(sbox_wc_delete(sandbox, "D/A/A/A"));
+ }
+ else if (strstr(test_name, "_add_"))
+ {
+ SVN_ERR(sbox_wc_mkdir(sandbox, "A/A/A/NEW"));
+ SVN_ERR(sbox_wc_mkdir(sandbox, "B/A/A/NEW"));
+ SVN_ERR(sbox_wc_mkdir(sandbox, "C/A/A/NEW"));
+ SVN_ERR(sbox_wc_mkdir(sandbox, "D/A/A/NEW"));
+ }
+ else if (strstr(test_name, "_replace_"))
+ {
+ SVN_ERR(sbox_wc_delete(sandbox, "A/A/A/A"));
+ SVN_ERR(sbox_wc_delete(sandbox, "B/A/A/A"));
+ SVN_ERR(sbox_wc_delete(sandbox, "C/A/A/A"));
+ SVN_ERR(sbox_wc_delete(sandbox, "D/A/A/A"));
+ SVN_ERR(sbox_file_write(sandbox, "A/A/A/A", "A"));
+ SVN_ERR(sbox_file_write(sandbox, "B/A/A/A", "A"));
+ SVN_ERR(sbox_file_write(sandbox, "C/A/A/A", "A"));
+ SVN_ERR(sbox_file_write(sandbox, "D/A/A/A", "A"));
+ SVN_ERR(sbox_wc_add(sandbox, "A/A/A/A"));
+ SVN_ERR(sbox_wc_add(sandbox, "B/A/A/A"));
+ SVN_ERR(sbox_wc_add(sandbox, "C/A/A/A"));
+ SVN_ERR(sbox_wc_add(sandbox, "D/A/A/A"));
+ }
+ else if (strstr(test_name, "_delself_"))
+ {
+ SVN_ERR(sbox_wc_delete(sandbox, "A/A/A"));
+ SVN_ERR(sbox_wc_delete(sandbox, "B/A/A"));
+ SVN_ERR(sbox_wc_delete(sandbox, "C/A/A"));
+ SVN_ERR(sbox_wc_delete(sandbox, "D/A/A"));
+ }
+ else if (strstr(test_name, "_replaceself_"))
+ {
+ SVN_ERR(sbox_wc_delete(sandbox, "A/A/A"));
+ SVN_ERR(sbox_wc_delete(sandbox, "B/A/A"));
+ SVN_ERR(sbox_wc_delete(sandbox, "C/A/A"));
+ SVN_ERR(sbox_wc_delete(sandbox, "D/A/A"));
+ SVN_ERR(sbox_file_write(sandbox, "A/A/A", "A"));
+ SVN_ERR(sbox_file_write(sandbox, "B/A/A", "A"));
+ SVN_ERR(sbox_file_write(sandbox, "C/A/A", "A"));
+ SVN_ERR(sbox_file_write(sandbox, "D/A/A", "A"));
+ SVN_ERR(sbox_wc_add(sandbox, "A/A/A"));
+ SVN_ERR(sbox_wc_add(sandbox, "B/A/A"));
+ SVN_ERR(sbox_wc_add(sandbox, "C/A/A"));
+ SVN_ERR(sbox_wc_add(sandbox, "D/A/A"));
+ }
+
+ SVN_ERR(sbox_wc_commit(sandbox, ""));
+ SVN_ERR(sbox_wc_update(sandbox, "", 1));
+
+ SVN_ERR(sbox_wc_move(sandbox, "A/A/A", "AAA_1"));
+
+ if (move_away)
+ SVN_ERR(sbox_wc_move(sandbox, "A", "A_moved"));
+ else
+ SVN_ERR(sbox_wc_delete(sandbox, "A"));
+
+ SVN_ERR(sbox_wc_move(sandbox, "B", "A"));
+
+ SVN_ERR(sbox_wc_move(sandbox, "A/A/A", "AAA_2"));
+
+ if (move_away)
+ SVN_ERR(sbox_wc_move(sandbox, "A/A", "BA_moved"));
+ else
+ SVN_ERR(sbox_wc_delete(sandbox, "A/A"));
+
+ SVN_ERR(sbox_wc_move(sandbox, "C/A", "A/A"));
+
+ SVN_ERR(sbox_wc_move(sandbox, "A/A/A", "AAA_3"));
+
+ SVN_ERR(sbox_wc_move(sandbox, "D/A/A", "A/A/A"));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+del4_update_edit_AAA(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(init_move4(&b, "del4_update_edit_AAA", opts, FALSE, pool));
- SVN_ERR(sbox_wc_copy_url(&b,
- svn_path_url_add_component2(b.repos_url, "A/B",
- pool),
- -1, "AA"));
+ {
+ nodes_row_t nodes[] = {
+
+ { 0, "A/A/A", "normal", 1, "A/A/A" },
+ { 1, "A/A/A", "normal", 1, "B/A/A", FALSE, "AAA_1", TRUE },
+ { 2, "A/A/A", "normal", 1, "C/A/A", FALSE, "AAA_2", TRUE },
+ { 3, "A/A/A", "normal", 1, "D/A/A", FALSE, "AAA_3", TRUE },
+
+ { 0, "A/A/A/A", "normal", 1, "A/A/A/A" },
+ { 1, "A/A/A/A", "normal", 1, "B/A/A/A", FALSE, NULL, TRUE },
+ { 2, "A/A/A/A", "normal", 1, "C/A/A/A", FALSE, NULL, TRUE },
+ { 3, "A/A/A/A", "normal", 1, "D/A/A/A", FALSE, NULL, TRUE },
+
+ { 0 },
+ };
+
+ SVN_ERR(check_db_rows(&b, "A/A/A", nodes));
+ }
+
+ /* Update and resolve via mine strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ 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/A", "normal", 2, "A/A"},
+ {0, "A/A/A", "normal", 2, "A/A/A", NOT_MOVED, "key"},
+ {0, "A/A/A/A", "normal", 2, "A/A/A/A", NOT_MOVED, "key"},
+ {0, "B", "normal", 2, "B"},
+ {0, "B/A", "normal", 2, "B/A"},
+ {0, "B/A/A", "normal", 2, "B/A/A", NOT_MOVED, "key"},
+ {0, "B/A/A/A", "normal", 2, "B/A/A/A", NOT_MOVED, "key"},
+ {0, "C", "normal", 2, "C"},
+ {0, "C/A", "normal", 2, "C/A"},
+ {0, "C/A/A", "normal", 2, "C/A/A", NOT_MOVED, "key"},
+ {0, "C/A/A/A", "normal", 2, "C/A/A/A", NOT_MOVED, "key"},
+ {0, "D", "normal", 2, "D"},
+ {0, "D/A", "normal", 2, "D/A"},
+ {0, "D/A/A", "normal", 2, "D/A/A", NOT_MOVED, "key"},
+ {0, "D/A/A/A", "normal", 2, "D/A/A/A", NOT_MOVED, "key"},
+
+ {1, "A", "normal", 2, "B", MOVED_HERE},
+ {1, "A/A", "normal", 2, "B/A", MOVED_HERE},
+ {1, "A/A/A", "normal", 2, "B/A/A", FALSE, "AAA_1", TRUE, "key"},
+ {1, "A/A/A/A", "normal", 2, "B/A/A/A", FALSE, NULL, TRUE, "key"},
+ {1, "AAA_1", "normal", 2, "A/A/A", MOVED_HERE, "key"},
+ {1, "AAA_1/A", "normal", 2, "A/A/A/A", MOVED_HERE, "key"},
+ {1, "AAA_2", "normal", 2, "B/A/A", MOVED_HERE, "key"},
+ {1, "AAA_2/A", "normal", 2, "B/A/A/A", MOVED_HERE, "key"},
+ {1, "AAA_3", "normal", 2, "C/A/A", MOVED_HERE, "key"},
+ {1, "AAA_3/A", "normal", 2, "C/A/A/A", MOVED_HERE, "key"},
+ {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},
+
+ {2, "A/A", "normal", 2, "C/A", MOVED_HERE},
+ {2, "A/A/A", "normal", 2, "C/A/A", FALSE, "AAA_2", TRUE, "key"},
+ {2, "A/A/A/A", "normal", 2, "C/A/A/A", FALSE, NULL, TRUE, "key"},
+ {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},
+
+ {3, "A/A/A", "normal", 2, "D/A/A", FALSE, "AAA_3", TRUE, "key"},
+ {3, "A/A/A/A", "normal", 2, "D/A/A/A", FALSE, NULL, TRUE, "key"},
+ {3, "D/A/A", "base-deleted", NO_COPY_FROM, "A/A/A"},
+ {3, "D/A/A/A", "base-deleted", NO_COPY_FROM},
+
+ { 0 },
+ };
+
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ SVN_ERR(check_db_conflicts(&b, "", NULL));
+ }
+
+ /* Go back to start position */
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+
+ {
+ 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", NOT_MOVED},
+ {0, "A/A/A/A", "normal", 1, "A/A/A/A", NOT_MOVED},
+ {0, "B", "normal", 1, "B"},
+ {0, "B/A", "normal", 1, "B/A"},
+ {0, "B/A/A", "normal", 1, "B/A/A", NOT_MOVED},
+ {0, "B/A/A/A", "normal", 1, "B/A/A/A", NOT_MOVED},
+ {0, "C", "normal", 1, "C"},
+ {0, "C/A", "normal", 1, "C/A"},
+ {0, "C/A/A", "normal", 1, "C/A/A", NOT_MOVED},
+ {0, "C/A/A/A", "normal", 1, "C/A/A/A", NOT_MOVED},
+ {0, "D", "normal", 1, "D"},
+ {0, "D/A", "normal", 1, "D/A"},
+ {0, "D/A/A", "normal", 1, "D/A/A", NOT_MOVED},
+ {0, "D/A/A/A", "normal", 1, "D/A/A/A", NOT_MOVED},
+
+ {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", FALSE, NULL, TRUE},
+ {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},
+ {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},
+
+ {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", FALSE, NULL, TRUE},
+ {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},
+
+ {3, "A/A/A", "normal", 1, "D/A/A", FALSE, "AAA_3", TRUE},
+ {3, "A/A/A/A", "normal", 1, "D/A/A/A", FALSE, NULL, TRUE},
+ {3, "D/A/A", "base-deleted", NO_COPY_FROM, "A/A/A"},
+ {3, "D/A/A/A", "base-deleted", NO_COPY_FROM},
+
+ { 0 },
+ };
+
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ SVN_ERR(check_db_conflicts(&b, "", NULL));
+ }
+
+ /* Update and resolve via their strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ {
+ conflict_info_t conflicts[] = {
+ {"A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_replaced}},
+ {"B", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "B"}},
+ {"C/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "C/A"}},
+ {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "D/A/A"}},
+ {0},
+ };
+
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+ /* This breaks the move A/A/A -> AAA_1 */
+ SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty, svn_wc_conflict_choose_merged));
+ /* This breaks the move B -> A */
+ SVN_ERR(sbox_wc_resolve(&b, "B", svn_depth_empty, svn_wc_conflict_choose_merged));
+ /* This breaks the move C/A/A -> A/A */
+ SVN_ERR(sbox_wc_resolve(&b, "C/A", svn_depth_empty, svn_wc_conflict_choose_merged));
+ /* This breaks the move from D/A/A -> A/A/A */
+ SVN_ERR(sbox_wc_resolve(&b, "D/A/A", svn_depth_empty, svn_wc_conflict_choose_merged));
{
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", NOT_MOVED, "key"},
+ {0, "A/A/A/A", "normal", 2, "A/A/A/A", NOT_MOVED, "key"},
+ {0, "B", "normal", 2, "B"},
+ {0, "B/A", "normal", 2, "B/A"},
+ {0, "B/A/A", "normal", 2, "B/A/A", NOT_MOVED, "key"},
+ {0, "B/A/A/A", "normal", 2, "B/A/A/A", NOT_MOVED, "key"},
+ {0, "C", "normal", 2, "C"},
+ {0, "C/A", "normal", 2, "C/A"},
+ {0, "C/A/A", "normal", 2, "C/A/A", NOT_MOVED, "key"},
+ {0, "C/A/A/A", "normal", 2, "C/A/A/A", NOT_MOVED, "key"},
+ {0, "D", "normal", 2, "D"},
+ {0, "D/A", "normal", 2, "D/A"},
+ {0, "D/A/A", "normal", 2, "D/A/A", NOT_MOVED, "key"},
+ {0, "D/A/A/A", "normal", 2, "D/A/A/A", NOT_MOVED, "key"},
+ {1, "A", "normal", 1, "B"},
+ {1, "A/A", "normal", 1, "B/A"},
+ {1, "A/A/A", "normal", 1, "B/A/A", FALSE},
+ {1, "A/A/A/A", "normal", 1, "B/A/A/A"},
+ {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},
+ {1, "B", "base-deleted", NO_COPY_FROM},
+ {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},
+ {2, "A/A", "normal", 1, "C/A"},
+ {2, "A/A/A", "normal", 1, "C/A/A", FALSE, "AAA_2"},
+ {2, "A/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},
+ {2, "C/A/A/A", "base-deleted", NO_COPY_FROM},
+ {3, "A/A/A", "normal", 1, "D/A/A", FALSE, "AAA_3"},
+ {3, "A/A/A/A", "normal", 1, "D/A/A/A"},
+ {3, "D/A/A", "base-deleted", NO_COPY_FROM},
+ {3, "D/A/A/A", "base-deleted", NO_COPY_FROM},
- {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, "", nodes));
+ }
+
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+del4_update_delete_AAA(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(init_move4(&b, "del4_update_delete_AAA", opts, FALSE, pool));
+
+ /* Update and resolve via mine strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ {
+ conflict_info_t conflicts[] = {
+ {"A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_replaced}},
+ {"B", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "B"}},
+ {"C/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "C/A"}},
+ {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "D/A/A"}},
+ {0}
+ };
+
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+ /* Go back to start position */
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ {
+ conflict_info_t conflicts[] = {
+ {"A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_replaced}},
+ {"B", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "B"}},
+ {"C/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "C/A"}},
+ {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "D/A/A"}},
+ {0}
+ };
+
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+ /* Update and resolve via their strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ {
+ conflict_info_t conflicts[] = {
+ {"A", FALSE, FALSE, {svn_wc_conflict_action_edit, svn_wc_conflict_reason_replaced}},
+ {"B", FALSE, FALSE, {svn_wc_conflict_action_edit, svn_wc_conflict_reason_moved_away, "B"}},
+ {"C/A", FALSE, FALSE, {svn_wc_conflict_action_edit, svn_wc_conflict_reason_moved_away, "C/A"}},
+ {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_edit, svn_wc_conflict_reason_moved_away, "D/A/A"}},
+ {0}
+ };
+
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+del4_update_add_AAA(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(init_move4(&b, "del4_update_add_AAA", opts, FALSE, pool));
+
+ /* Update and resolve via mine strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ {
+ conflict_info_t conflicts[] = {
+ {"A", FALSE, FALSE, {svn_wc_conflict_action_edit, svn_wc_conflict_reason_replaced}},
+ {"B", FALSE, FALSE, {svn_wc_conflict_action_edit, svn_wc_conflict_reason_moved_away, "B"}},
+ {"C/A", FALSE, FALSE, {svn_wc_conflict_action_edit, svn_wc_conflict_reason_moved_away, "C/A"}},
+ {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_edit, svn_wc_conflict_reason_moved_away, "D/A/A"}},
+ {0}
+ };
+
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+ /* Go back to start position */
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ {
+ conflict_info_t conflicts[] = {
+ {"A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_replaced}},
+ {"B", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "B"}},
+ {"C/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "C/A"}},
+ {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "D/A/A"}},
+ {0}
+ };
+
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+ /* Update and resolve via their strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ {
+ conflict_info_t conflicts[] = {
+ {"A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_replaced}},
+ {"B", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "B"}},
+ {"C/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "C/A"}},
+ {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "D/A/A"}},
+ {0}
+ };
+
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+del4_update_replace_AAA(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(init_move4(&b, "del4_update_replace_AAA", opts, FALSE, pool));
+
+ /* Update and resolve via mine strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ {
+ conflict_info_t conflicts[] = {
+ {"A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_replaced}},
+ {"B", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "B"}},
+ {"C/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "C/A"}},
+ {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "D/A/A"}},
+ {0}
+ };
+
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+ /* Go back to start position */
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ {
+ conflict_info_t conflicts[] = {
+ {"A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_replaced}},
+ {"B", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "B"}},
+ {"C/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "C/A"}},
+ {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "D/A/A"}},
+ {0}
+ };
+
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+ /* Update and resolve via their strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ {
+ conflict_info_t conflicts[] = {
+ {"A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_replaced}},
+ {"B", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "B"}},
+ {"C/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "C/A"}},
+ {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "D/A/A"}},
+ {0}
+ };
+
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+del4_update_delself_AAA(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(init_move4(&b, "del4_update_delself_AAA", opts, FALSE, pool));
+
+ /* Update and resolve via mine strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+
+ {
+ conflict_info_t conflicts[] = {
+ {"A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_replaced}},
+ {"B", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "B"}},
+ {"C/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "C/A"}},
+ {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_delete,
+ svn_wc_conflict_reason_moved_away, "D/A/A"}},
+ {0}
+ };
+
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+
+
+ /* Resolve a few conflicts manually */
+ SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(sbox_wc_resolve(&b, "B", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(sbox_wc_resolve(&b, "C/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, "B", "normal", 2, "B"},
+ {0, "B/A", "normal", 2, "B/A"},
+ {0, "C", "normal", 2, "C"},
+ {0, "C/A", "normal", 2, "C/A"},
+ {0, "D", "normal", 2, "D"},
+ {0, "D/A", "normal", 2, "D/A"},
+ {1, "A", "normal", 2, "B", MOVED_HERE},
+ {1, "A/A", "normal", 2, "B/A", MOVED_HERE},
+ {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"},
+ {1, "AAA_2/A", "normal", 1, "B/A/A/A"},
+ {1, "AAA_3", "normal", 1, "C/A/A"},
+ {1, "AAA_3/A", "normal", 1, "C/A/A/A"},
+ {1, "B", "base-deleted", NO_COPY_FROM, "A"},
+ {1, "B/A", "base-deleted", NO_COPY_FROM},
+ {2, "A/A", "normal", 2, "C/A", MOVED_HERE},
+ {2, "C/A", "base-deleted", NO_COPY_FROM, "A/A"},
+ {3, "A/A/A", "normal", 1, "D/A/A"},
+ {3, "A/A/A/A", "normal", 1, "D/A/A/A"},
{ 0 },
};
- SVN_ERR(check_db_rows(&b, "AA", nodes));
+
+ SVN_ERR(check_db_rows(&b, "", nodes));
}
+ {
+ conflict_info_t conflicts[] = {
+ /* Not resolved yet */
+ {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_delete,
+ svn_wc_conflict_reason_moved_away, "D/A/A"}},
- 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);
+ /* New */
+ {"A/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_deleted}},
+ {"A/A/A", FALSE, FALSE, {svn_wc_conflict_action_delete,
+ svn_wc_conflict_reason_moved_away, "A/A/A"}},
- svn_test_add_dir_cleanup(new_repos_dir);
+ {0}
+ };
- 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(check_db_conflicts(&b, "", conflicts));
+ }
- SVN_ERR(sbox_wc_relocate(&b, new_repos_url));
+ /* These can only be resolved to merged, as the merge is already broken
+ (because the move source is gone): incoming delete on moved_away */
+ SVN_ERR(sbox_wc_resolve(&b, "D/A/A", svn_depth_empty,
+ svn_wc_conflict_choose_merged));
+ SVN_ERR(sbox_wc_resolve(&b, "A/A/A", svn_depth_empty,
+ svn_wc_conflict_choose_merged));
- /* 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"));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+ /* Go back to start position */
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ {
+ conflict_info_t conflicts[] = {
+ {"A", FALSE, FALSE, { svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_replaced}},
+ {"B", FALSE, FALSE, { svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "B"}},
+ {"C/A", FALSE, FALSE, { svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "C/A"}},
+ {0}
+ };
+
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+ SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(sbox_wc_resolve(&b, "B", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(sbox_wc_resolve(&b, "C/A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ conflict_info_t conflicts[] = {
+ {"A/A", FALSE, FALSE, { svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_deleted}},
+ {"A/A/A", FALSE, FALSE, { svn_wc_conflict_action_add,
+ svn_wc_conflict_reason_added}},
+ {0}
+ };
+
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+ SVN_ERR(sbox_wc_resolve(&b, "A/A/A", svn_depth_empty,
+ svn_wc_conflict_choose_merged));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity,
+ svn_wc_conflict_choose_mine_conflict));
+ /* Update and resolve via their strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+del4_update_replaceself_AAA(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(init_move4(&b, "del4_update_replaceself_AAA", opts, FALSE, pool));
+
+ /* Update and resolve via mine strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+ /* Go back to start position */
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+ /* Update and resolve via their strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
+
+ return SVN_NO_ERROR;
+}
+
+
+static svn_error_t *
+move4_update_edit_AAA(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(init_move4(&b, "move4_update_edit_AAA", opts, TRUE, pool));
+
+ {
+ nodes_row_t nodes[] = {
+
+ { 0, "A/A/A", "normal", 1, "A/A/A" },
+ { 1, "A/A/A", "normal", 1, "B/A/A", FALSE, NULL /*"AAA_1"*/, TRUE },
+ { 2, "A/A/A", "normal", 1, "C/A/A", FALSE, NULL /*"AAA_2"*/, TRUE },
+ { 3, "A/A/A", "normal", 1, "D/A/A", FALSE, "AAA_3", TRUE },
+
+ { 0, "A/A/A/A", "normal", 1, "A/A/A/A" },
+ { 1, "A/A/A/A", "normal", 1, "B/A/A/A", FALSE, NULL, TRUE },
+ { 2, "A/A/A/A", "normal", 1, "C/A/A/A", FALSE, NULL, TRUE },
+ { 3, "A/A/A/A", "normal", 1, "D/A/A/A", FALSE, NULL, TRUE },
+
+
+ { 0 },
+ };
+
+ SVN_ERR(check_db_rows(&b, "A/A/A", nodes));
+ }
+
+ /* Update and resolve via mine strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+
+ {
+ nodes_row_t nodes[] = {
+
+ { 0, "A/A/A", "normal", 2, "A/A/A", NOT_MOVED, "key" },
+ { 1, "A/A/A", "normal", 2, "B/A/A", FALSE, NULL /*"AAA_1"*/, TRUE, "key" },
+ { 2, "A/A/A", "normal", 2, "C/A/A", FALSE, NULL /*"AAA_2"*/, TRUE, "key" },
+ { 3, "A/A/A", "normal", 2, "D/A/A", FALSE, "AAA_3", TRUE, "key" },
+
+ { 0, "A/A/A/A", "normal", 2, "A/A/A/A", NOT_MOVED, "key" },
+ { 1, "A/A/A/A", "normal", 2, "B/A/A/A", FALSE, NULL, TRUE, "key" },
+ { 2, "A/A/A/A", "normal", 2, "C/A/A/A", FALSE, NULL, TRUE, "key" },
+ { 3, "A/A/A/A", "normal", 2, "D/A/A/A", FALSE, NULL, TRUE, "key" },
+
+ { 0 },
+ };
+ SVN_ERR(check_db_rows(&b, "A/A/A", nodes));
+ }
+
+ /* Go back to start position */
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+ /* Update and resolve via their strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
+
+ {
+ nodes_row_t nodes[] = {
+
+ { 0, "A/A/A", "normal", 2, "A/A/A", NOT_MOVED, "key" },
+ { 1, "A/A/A", "normal", 1, "B/A/A" },
+ { 2, "A/A/A", "normal", 1, "C/A/A" },
+ { 3, "A/A/A", "normal", 1, "D/A/A", FALSE, "AAA_3"},
+
+ { 0, "A/A/A/A", "normal", 2, "A/A/A/A", NOT_MOVED, "key" },
+ { 1, "A/A/A/A", "normal", 1, "B/A/A/A" },
+ { 2, "A/A/A/A", "normal", 1, "C/A/A/A" },
+ { 3, "A/A/A/A", "normal", 1, "D/A/A/A" },
+
+ { 0 },
+ };
+
+ SVN_ERR(check_db_rows(&b, "A/A/A", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move4_update_delete_AAA(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(init_move4(&b, "move4_update_delete_AAA", opts, TRUE, pool));
+
+ /* Update and resolve via mine strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+ /* Go back to start position */
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+ /* Update and resolve via their strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move4_update_add_AAA(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(init_move4(&b, "move4_update_add_AAA", opts, TRUE, pool));
+
+ /* Update and resolve via mine strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+ /* Go back to start position */
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+ /* Update and resolve via their strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move4_update_replace_AAA(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(init_move4(&b, "move4_update_replace_AAA", opts, TRUE, pool));
+
+ /* Update and resolve via mine strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+ /* Go back to start position */
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+ /* Update and resolve via their strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move4_update_delself_AAA(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(init_move4(&b, "move4_update_delself_AAA", opts, TRUE, pool));
+
+ /* Update and resolve via mine strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+
+ {
+ nodes_row_t nodes[] = {
+
+ {1, "A_moved", "normal", 1, "A", MOVED_HERE},
+ {1, "A_moved/A", "normal", 1, "A/A", MOVED_HERE},
+ {1, "A_moved/A/A", "normal", 1, "A/A/A", MOVED_HERE},
+ {3, "A_moved/A/A", "base-deleted", NO_COPY_FROM, "AAA_1"},
+ {1, "A_moved/A/A/A", "normal", 1, "A/A/A/A", MOVED_HERE},
+ {3, "A_moved/A/A/A", "base-deleted", NO_COPY_FROM},
+
+ { 0 },
+ };
+ SVN_ERR(check_db_rows(&b, "A_moved", nodes));
+ }
+
+ /* Resolve a few conflicts manually */
+ 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/A", "normal", 2, "A/A"},
+ {0, "B", "normal", 2, "B"},
+ {0, "B/A", "normal", 2, "B/A"},
+ {0, "C", "normal", 2, "C"},
+ {0, "C/A", "normal", 2, "C/A"},
+ {0, "D", "normal", 2, "D"},
+ {0, "D/A", "normal", 2, "D/A"},
+ {1, "A", "normal", 1, "B", FALSE, "A_moved", TRUE},
+ {1, "A/A", "normal", 1, "B/A", MOVED_HERE},
+ {1, "A/A/A", "normal", 1, "B/A/A", MOVED_HERE},
+ {1, "A/A/A/A", "normal", 1, "B/A/A/A", MOVED_HERE},
+ {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},
+ {1, "A_moved", "normal", 2, "A", MOVED_HERE},
+ {1, "A_moved/A", "normal", 2, "A/A", MOVED_HERE},
+ {1, "B", "base-deleted", NO_COPY_FROM, "A"},
+ {1, "B/A", "base-deleted", NO_COPY_FROM},
+ {1, "BA_moved", "normal", 1, "B/A", MOVED_HERE},
+ {1, "BA_moved/A", "normal", 1, "B/A/A", MOVED_HERE},
+ {1, "BA_moved/A/A", "normal", 1, "B/A/A/A", MOVED_HERE},
+ {2, "A/A", "normal", 1, "C/A", FALSE, "BA_moved", TRUE},
+ {2, "A/A/A", "normal", 1, "C/A/A", MOVED_HERE},
+ {2, "A/A/A/A", "normal", 1, "C/A/A/A", MOVED_HERE},
+ {2, "BA_moved/A", "base-deleted", NO_COPY_FROM, "AAA_2"},
+ {2, "BA_moved/A/A", "base-deleted", NO_COPY_FROM},
+ {2, "C/A", "base-deleted", NO_COPY_FROM, "A/A"},
+ {3, "A/A/A", "normal", 1, "D/A/A", FALSE, "AAA_3"},
+ {3, "A/A/A/A", "normal", 1, "D/A/A/A"},
+
+ { 0 },
+ };
+ conflict_info_t conflicts[] = {
+ {"A_moved/A/A", FALSE, FALSE, {svn_wc_conflict_action_delete,
+ svn_wc_conflict_reason_moved_away, "A_moved/A/A"}},
+ {"B", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "B"}},
+ {"C/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "C/A"}},
+ {"D/A/A", FALSE, FALSE, {svn_wc_conflict_action_delete,
+ svn_wc_conflict_reason_moved_away, "D/A/A"}},
+
+ { 0 },
+ };
+
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+
+ SVN_ERR(sbox_wc_resolve(&b, "B", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(sbox_wc_resolve(&b, "C/A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+
+
+ /* ### These can currently only be resolved to merged ???? */
+ SVN_ERR(sbox_wc_resolve(&b, "D/A/A", svn_depth_empty,
+ svn_wc_conflict_choose_merged));
+ SVN_ERR(sbox_wc_resolve(&b, "A/A/A", svn_depth_empty,
+ svn_wc_conflict_choose_merged));
+ SVN_ERR(sbox_wc_resolve(&b, "A_moved/A/A", svn_depth_empty,
+ svn_wc_conflict_choose_merged));
+ SVN_ERR(sbox_wc_resolve(&b, "A/A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(sbox_wc_resolve(&b, "BA_moved/A", svn_depth_empty,
+ svn_wc_conflict_choose_merged));
+ SVN_ERR(check_db_conflicts(&b, "", NULL));
+ /* Go back to start position */
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ {
+ 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, "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"},
+ {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"},
+ {0, "D", "normal", 1, "D"},
+ {0, "D/A", "normal", 1, "D/A"},
+ {0, "D/A/A", "normal", 1, "D/A/A"},
+ {0, "D/A/A/A", "normal", 1, "D/A/A/A"},
+ {1, "A", "normal", 2, "B", FALSE, "A_moved", TRUE},
+ {1, "A/A", "normal", 2, "B/A", MOVED_HERE},
+ {1, "A/A/A", "base-deleted", NO_COPY_FROM},
+ {1, "A/A/A/A", "base-deleted", NO_COPY_FROM},
+ {1, "A_moved", "normal", 2, "A", MOVED_HERE},
+ {1, "A_moved/A", "normal", 2, "A/A", MOVED_HERE},
+ {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"},
+ {1, "AAA_2/A", "normal", 1, "B/A/A/A"},
+ {1, "AAA_3", "normal", 1, "C/A/A"},
+ {1, "AAA_3/A", "normal", 1, "C/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},
+ {1, "BA_moved", "normal", 2, "B/A", MOVED_HERE},
+ {2, "A/A", "normal", 2, "C/A", FALSE, "BA_moved", TRUE},
+ {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},
+ {3, "A/A/A", "normal", 1, "D/A/A"},
+ {3, "A/A/A/A", "normal", 1, "D/A/A/A"},
+
+ { 0 },
+ };
+
+ conflict_info_t conflicts[] = {
+ {"A", FALSE, FALSE, { svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_replaced}},
+ {"B", FALSE, FALSE, { svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "B"}},
+ {"C/A", FALSE, FALSE, { svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "C/A"}},
+ {0}
+ };
+
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+
+ SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(sbox_wc_resolve(&b, "B", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(sbox_wc_resolve(&b, "C/A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ conflict_info_t conflicts[] = {
+ {"A/A", FALSE, FALSE, { svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "A/A"}},
+ {"A/A/A", FALSE, FALSE, { svn_wc_conflict_action_add,
+ svn_wc_conflict_reason_added}},
+ {0}
+ };
+
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+ SVN_ERR(sbox_wc_resolve(&b, "A/A/A", svn_depth_empty,
+ svn_wc_conflict_choose_merged));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+ /* Update and resolve via their strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move4_update_replaceself_AAA(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(init_move4(&b, "move4_update_replaceself_AAA", opts, TRUE, pool));
+
+ /* Update and resolve via mine strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+ /* Go back to start position */
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+ /* Update and resolve via their strategy */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+simple_move_bump(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "simple_move_bump", opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+
+ SVN_ERR(sbox_wc_propset(&b, "old_A", "val", "A"));
+ SVN_ERR(sbox_wc_propset(&b, "old_B", "val", "A/B"));
+
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ SVN_ERR(sbox_wc_propset(&b, "new_A", "val", "A"));
+ SVN_ERR(sbox_wc_propset(&b, "new_B", "val", "A/B"));
+
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_move(&b, "A/B", "A/B_mv"));
+ SVN_ERR(sbox_wc_move(&b, "A", "A_mv"));
{
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, "", "normal", 1, ""},
+ { 0, "A", "normal", 1, "A", NOT_MOVED, "old_A"},
+ { 0, "A/B", "normal", 1, "A/B", NOT_MOVED, "old_B"},
+
+ { 1, "A", "base-deleted", NO_COPY_FROM, "A_mv"},
+ { 1, "A/B", "base-deleted", NO_COPY_FROM},
+
+ { 1, "A_mv", "normal", 1, "A", MOVED_HERE, "old_A" },
+ { 1, "A_mv/B", "normal", 1, "A/B", MOVED_HERE, "old_B" },
+
+ { 2, "A_mv/B", "base-deleted", NO_COPY_FROM, "A_mv/B_mv" },
+ { 2, "A_mv/B_mv", "normal", 1, "A/B", FALSE, NULL, TRUE, "old_B" },
{ 0 },
};
- SVN_ERR(check_db_rows(&b, "BB", nodes));
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+
+ /* Expect the A tree to be updated */
+ {
+ nodes_row_t nodes[] = {
+
+ { 0, "", "normal", 2, ""},
+ { 0, "A", "normal", 2, "A", NOT_MOVED, "new_A,old_A"},
+ { 0, "A/B", "normal", 2, "A/B", NOT_MOVED, "new_B,old_B"},
+
+ { 1, "A", "base-deleted", NO_COPY_FROM, "A_mv"},
+ { 1, "A/B", "base-deleted", NO_COPY_FROM},
+
+ { 1, "A_mv", "normal", 1, "A", MOVED_HERE, "old_A" },
+ { 1, "A_mv/B", "normal", 1, "A/B", MOVED_HERE, "old_B" },
+
+ { 2, "A_mv/B", "base-deleted", NO_COPY_FROM, "A_mv/B_mv" },
+ { 2, "A_mv/B_mv", "normal", 1, "A/B", FALSE, NULL, TRUE, "old_B" },
+
+ { 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", 2, ""},
+ { 0, "A", "normal", 2, "A", NOT_MOVED, "new_A,old_A"},
+ { 0, "A/B", "normal", 2, "A/B", NOT_MOVED, "new_B,old_B"},
+
+ { 1, "A", "base-deleted", NO_COPY_FROM, "A_mv"},
+ { 1, "A/B", "base-deleted", NO_COPY_FROM},
+
+ { 1, "A_mv", "normal", 2, "A", MOVED_HERE, "new_A,old_A" },
+ { 1, "A_mv/B", "normal", 2, "A/B", MOVED_HERE, "new_B,old_B" },
+
+ { 2, "A_mv/B", "base-deleted", NO_COPY_FROM, "A_mv/B_mv" },
+ { 2, "A_mv/B_mv", "normal", 1, "A/B", FALSE, NULL, TRUE, "old_B" },
+
+ { 0 },
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_resolve(&b, "A_mv/B", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+
+ {
+ nodes_row_t nodes[] = {
+
+ { 0, "", "normal", 2, ""},
+ { 0, "A", "normal", 2, "A", NOT_MOVED, "new_A,old_A"},
+ { 0, "A/B", "normal", 2, "A/B", NOT_MOVED, "new_B,old_B"},
+
+ { 1, "A", "base-deleted", NO_COPY_FROM, "A_mv"},
+ { 1, "A/B", "base-deleted", NO_COPY_FROM},
+
+ { 1, "A_mv", "normal", 2, "A", MOVED_HERE, "new_A,old_A" },
+ { 1, "A_mv/B", "normal", 2, "A/B", MOVED_HERE, "new_B,old_B" },
+
+ { 2, "A_mv/B", "base-deleted", NO_COPY_FROM, "A_mv/B_mv" },
+ { 2, "A_mv/B_mv", "normal", 2, "A/B", FALSE, NULL, TRUE, "new_B,old_B" },
+
+ { 0 },
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
}
return SVN_NO_ERROR;
@@ -8826,8 +10585,35 @@ movedhere_extract_retract(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(sbox_wc_mkdir(&b, "Z/E2"));
SVN_ERR(sbox_wc_update(&b, "", 2));
+ {
+ conflict_info_t conflicts[] = {
+ {"A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "A"}},
+ {0}
+ };
+
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
svn_wc_conflict_choose_mine_conflict));
+ {
+ conflict_info_t conflicts[] = {
+ {"Z/B1", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_deleted}},
+ {"Z/B2", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "Z/B2"}},
+ {"Z/C1", FALSE, FALSE, {svn_wc_conflict_action_delete,
+ svn_wc_conflict_reason_deleted}},
+ {"Z/C2", FALSE, FALSE, {svn_wc_conflict_action_delete,
+ svn_wc_conflict_reason_moved_away, "Z/C2"}},
+ {"Z/E2", FALSE, FALSE, {svn_wc_conflict_action_add,
+ svn_wc_conflict_reason_added}},
+
+ {0}
+ };
+
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
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,
@@ -8838,8 +10624,10 @@ movedhere_extract_retract(const svn_test_opts_t *opts, apr_pool_t *pool)
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));
+ SVN_ERR(sbox_wc_resolve(&b, "Z/E2", svn_depth_empty,
+ svn_wc_conflict_choose_merged));
+
+ SVN_ERR(check_db_conflicts(&b, "", NULL));
{
nodes_row_t nodes[] = {
@@ -8894,6 +10682,168 @@ movedhere_extract_retract(const svn_test_opts_t *opts, apr_pool_t *pool)
{ 0 },
};
SVN_ERR(check_db_rows(&b, "", nodes));
+
+ SVN_ERR(check_db_conflicts(&b, "", NULL));
+ }
+
+ 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 *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));
+ }
+
+ new_repos_dir = apr_pstrcat(pool, b.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(b.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 *
+break_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, "break_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, "X"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X/Y"));
+ SVN_ERR(sbox_wc_mkdir(&b, "X/Y/Z"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_propset(&b, "key", "value", "X/Y/Z"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_move(&b, "X/Y/Z", "A/Z"));
+ SVN_ERR(sbox_wc_delete(&b, "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, "X/Y/Z", "normal", 1, "X/Y/Z"},
+ {1, "X", "base-deleted", NO_COPY_FROM},
+ {1, "X/Y", "base-deleted", NO_COPY_FROM},
+ {1, "X/Y/Z", "base-deleted", NO_COPY_FROM, "A/Z"},
+ {2, "A/Z", "normal", 1, "X/Y/Z", 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/B", "normal", 2, "A/B"},
+ {0, "X", "normal", 2, "X"},
+ {0, "X/Y", "normal", 2, "X/Y"},
+ {0, "X/Y/Z", "normal", 2, "X/Y/Z"},
+ {1, "X", "base-deleted", NO_COPY_FROM},
+ {1, "X/Y", "base-deleted", NO_COPY_FROM},
+ {1, "X/Y/Z", "base-deleted", NO_COPY_FROM, "A/Z"},
+ {2, "A/Z", "normal", 1, "X/Y/Z", MOVED_HERE},
+ {0}
+ };
+ conflict_info_t conflicts1[] = {
+ {"X", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_deleted}},
+ {0}
+ };
+ conflict_info_t conflicts2[] = {
+ {"X/Y/Z", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "X"}},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ SVN_ERR(check_db_conflicts(&b, "", conflicts1));
+ SVN_ERR(sbox_wc_resolve(&b, "X", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ SVN_ERR(check_db_conflicts(&b, "", conflicts2));
+ }
+
+ SVN_ERR(sbox_wc_resolved(&b, "X/Y/Z"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 2, ""},
+ {0, "A", "normal", 2, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "X", "normal", 2, "X"},
+ {0, "X/Y", "normal", 2, "X/Y"},
+ {0, "X/Y/Z", "normal", 2, "X/Y/Z"},
+ {1, "X", "base-deleted", NO_COPY_FROM},
+ {1, "X/Y", "base-deleted", NO_COPY_FROM},
+ {1, "X/Y/Z", "base-deleted", NO_COPY_FROM},
+ {2, "A/Z", "normal", 1, "X/Y/Z"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ SVN_ERR(check_db_conflicts(&b, "", NULL));
}
return SVN_NO_ERROR;
@@ -9021,10 +10971,911 @@ nested_move_delete(const svn_test_opts_t *opts, apr_pool_t *pool)
return SVN_NO_ERROR;
}
+static svn_error_t *
+move_within_mixed_move(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_within_mixed_move", opts, pool));
+
+ SVN_ERR(sbox_add_and_commit_greek_tree(&b));
+
+ SVN_ERR(sbox_wc_delete(&b, "iota"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ /* Make A mixed revision */
+ SVN_ERR(sbox_wc_update(&b, "A/B/E", 2));
+
+ /* Single rev moves.. ok */
+ SVN_ERR(sbox_wc_move(&b, "A/D", "A/D_mv"));
+ SVN_ERR(sbox_wc_move(&b, "A/C", "C_mv"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 0, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/E", "normal", 2, "A/B/E"},
+ {0, "A/B/E/alpha", "normal", 2, "A/B/E/alpha"},
+ {0, "A/B/E/beta", "normal", 2, "A/B/E/beta"},
+ {0, "A/B/F", "normal", 1, "A/B/F"},
+ {0, "A/B/lambda", "normal", 1, "A/B/lambda"},
+ {0, "A/C", "normal", 1, "A/C"},
+ {0, "A/D", "normal", 1, "A/D"},
+ {0, "A/D/G", "normal", 1, "A/D/G"},
+ {0, "A/D/G/pi", "normal", 1, "A/D/G/pi"},
+ {0, "A/D/G/rho", "normal", 1, "A/D/G/rho"},
+ {0, "A/D/G/tau", "normal", 1, "A/D/G/tau"},
+ {0, "A/D/gamma", "normal", 1, "A/D/gamma"},
+ {0, "A/D/H", "normal", 1, "A/D/H"},
+ {0, "A/D/H/chi", "normal", 1, "A/D/H/chi"},
+ {0, "A/D/H/omega", "normal", 1, "A/D/H/omega"},
+ {0, "A/D/H/psi", "normal", 1, "A/D/H/psi"},
+ {0, "A/mu", "normal", 1, "A/mu"},
+ {0, "iota", "not-present", 2, "iota"},
+ {1, "C_mv", "normal", 1, "A/C", MOVED_HERE},
+ {2, "A/C", "base-deleted", NO_COPY_FROM, "C_mv"},
+ {2, "A/D", "base-deleted", NO_COPY_FROM, "A/D_mv"},
+ {2, "A/D/G", "base-deleted", NO_COPY_FROM},
+ {2, "A/D/G/pi", "base-deleted", NO_COPY_FROM},
+ {2, "A/D/G/rho", "base-deleted", NO_COPY_FROM},
+ {2, "A/D/G/tau", "base-deleted", NO_COPY_FROM},
+ {2, "A/D/gamma", "base-deleted", NO_COPY_FROM},
+ {2, "A/D/H", "base-deleted", NO_COPY_FROM},
+ {2, "A/D/H/chi", "base-deleted", NO_COPY_FROM},
+ {2, "A/D/H/omega", "base-deleted", NO_COPY_FROM},
+ {2, "A/D/H/psi", "base-deleted", NO_COPY_FROM},
+ {2, "A/D_mv", "normal", 1, "A/D", MOVED_HERE},
+ {2, "A/D_mv/G", "normal", 1, "A/D/G", MOVED_HERE},
+ {2, "A/D_mv/G/pi", "normal", 1, "A/D/G/pi", MOVED_HERE},
+ {2, "A/D_mv/G/rho", "normal", 1, "A/D/G/rho", MOVED_HERE},
+ {2, "A/D_mv/G/tau", "normal", 1, "A/D/G/tau", MOVED_HERE},
+ {2, "A/D_mv/gamma", "normal", 1, "A/D/gamma", MOVED_HERE},
+ {2, "A/D_mv/H", "normal", 1, "A/D/H", MOVED_HERE},
+ {2, "A/D_mv/H/chi", "normal", 1, "A/D/H/chi", MOVED_HERE},
+ {2, "A/D_mv/H/omega", "normal", 1, "A/D/H/omega", MOVED_HERE},
+ {2, "A/D_mv/H/psi", "normal", 1, "A/D/H/psi", MOVED_HERE},
+ {0}
+ };
+
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Mixed rev move... breaks recordings "A/D" -> "A/D_mv" */
+ SVN_ERR(sbox_wc_move(&b, "A", "A_mv"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 0, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/E", "normal", 2, "A/B/E"},
+ {0, "A/B/E/alpha", "normal", 2, "A/B/E/alpha"},
+ {0, "A/B/E/beta", "normal", 2, "A/B/E/beta"},
+ {0, "A/B/F", "normal", 1, "A/B/F"},
+ {0, "A/B/lambda", "normal", 1, "A/B/lambda"},
+ {0, "A/C", "normal", 1, "A/C"},
+ {0, "A/D", "normal", 1, "A/D"},
+ {0, "A/D/G", "normal", 1, "A/D/G"},
+ {0, "A/D/G/pi", "normal", 1, "A/D/G/pi"},
+ {0, "A/D/G/rho", "normal", 1, "A/D/G/rho"},
+ {0, "A/D/G/tau", "normal", 1, "A/D/G/tau"},
+ {0, "A/D/gamma", "normal", 1, "A/D/gamma"},
+ {0, "A/D/H", "normal", 1, "A/D/H"},
+ {0, "A/D/H/chi", "normal", 1, "A/D/H/chi"},
+ {0, "A/D/H/omega", "normal", 1, "A/D/H/omega"},
+ {0, "A/D/H/psi", "normal", 1, "A/D/H/psi"},
+ {0, "A/mu", "normal", 1, "A/mu"},
+ {0, "iota", "not-present", 2, "iota"},
+ {1, "A", "base-deleted", NO_COPY_FROM },
+ {1, "A/B", "base-deleted", NO_COPY_FROM },
+ {1, "A/B/E", "base-deleted", NO_COPY_FROM },
+ {1, "A/B/E/alpha", "base-deleted", NO_COPY_FROM },
+ {1, "A/B/E/beta", "base-deleted", NO_COPY_FROM },
+ {1, "A/B/F", "base-deleted", NO_COPY_FROM },
+ {1, "A/B/lambda", "base-deleted", NO_COPY_FROM },
+ {1, "A/C", "base-deleted", NO_COPY_FROM, "C_mv"},
+ {1, "A/D", "base-deleted", NO_COPY_FROM, "A/D_mv" },
+ {1, "A/D/G", "base-deleted", NO_COPY_FROM },
+ {1, "A/D/G/pi", "base-deleted", NO_COPY_FROM },
+ {1, "A/D/G/rho", "base-deleted", NO_COPY_FROM },
+ {1, "A/D/G/tau", "base-deleted", NO_COPY_FROM },
+ {1, "A/D/gamma", "base-deleted", NO_COPY_FROM },
+ {1, "A/D/H", "base-deleted", NO_COPY_FROM },
+ {1, "A/D/H/chi", "base-deleted", NO_COPY_FROM },
+ {1, "A/D/H/omega", "base-deleted", NO_COPY_FROM },
+ {1, "A/D/H/psi", "base-deleted", NO_COPY_FROM },
+ {1, "A/mu", "base-deleted", NO_COPY_FROM },
+ {1, "A_mv", "normal", 1, "A"},
+ {1, "A_mv/B", "normal", 1, "A/B"},
+ {1, "A_mv/B/E", "not-present", 2, "A/B/E"},
+ {1, "A_mv/B/F", "normal", 1, "A/B/F"},
+ {1, "A_mv/B/lambda", "normal", 1, "A/B/lambda"},
+ {1, "A_mv/C", "normal", 1, "A/C"},
+ {1, "A_mv/D", "normal", 1, "A/D"},
+ {1, "A_mv/D/G", "normal", 1, "A/D/G"},
+ {1, "A_mv/D/G/pi", "normal", 1, "A/D/G/pi"},
+ {1, "A_mv/D/G/rho", "normal", 1, "A/D/G/rho"},
+ {1, "A_mv/D/G/tau", "normal", 1, "A/D/G/tau"},
+ {1, "A_mv/D/gamma", "normal", 1, "A/D/gamma"},
+ {1, "A_mv/D/H", "normal", 1, "A/D/H"},
+ {1, "A_mv/D/H/chi", "normal", 1, "A/D/H/chi"},
+ {1, "A_mv/D/H/omega", "normal", 1, "A/D/H/omega"},
+ {1, "A_mv/D/H/psi", "normal", 1, "A/D/H/psi"},
+ {1, "A_mv/mu", "normal", 1, "A/mu"},
+ {1, "C_mv", "normal", 1, "A/C", MOVED_HERE},
+ {2, "A_mv/C", "base-deleted", NO_COPY_FROM },
+ {2, "A_mv/D", "base-deleted", NO_COPY_FROM },
+ {2, "A_mv/D/G", "base-deleted", NO_COPY_FROM },
+ {2, "A_mv/D/G/pi", "base-deleted", NO_COPY_FROM },
+ {2, "A_mv/D/G/rho", "base-deleted", NO_COPY_FROM },
+ {2, "A_mv/D/G/tau", "base-deleted", NO_COPY_FROM },
+ {2, "A_mv/D/gamma", "base-deleted", NO_COPY_FROM },
+ {2, "A_mv/D/H", "base-deleted", NO_COPY_FROM },
+ {2, "A_mv/D/H/chi", "base-deleted", NO_COPY_FROM },
+ {2, "A_mv/D/H/omega", "base-deleted", NO_COPY_FROM },
+ {2, "A_mv/D/H/psi", "base-deleted", NO_COPY_FROM },
+ {2, "A_mv/D_mv", "normal", 1, "A/D", MOVED_HERE},
+ {2, "A_mv/D_mv/G", "normal", 1, "A/D/G", MOVED_HERE},
+ {2, "A_mv/D_mv/G/pi", "normal", 1, "A/D/G/pi", MOVED_HERE},
+ {2, "A_mv/D_mv/G/rho", "normal", 1, "A/D/G/rho", MOVED_HERE},
+ {2, "A_mv/D_mv/G/tau", "normal", 1, "A/D/G/tau", MOVED_HERE},
+ {2, "A_mv/D_mv/gamma", "normal", 1, "A/D/gamma", MOVED_HERE},
+ {2, "A_mv/D_mv/H", "normal", 1, "A/D/H", MOVED_HERE},
+ {2, "A_mv/D_mv/H/chi", "normal", 1, "A/D/H/chi", MOVED_HERE},
+ {2, "A_mv/D_mv/H/omega","normal", 1, "A/D/H/omega", MOVED_HERE},
+ {2, "A_mv/D_mv/H/psi", "normal", 1, "A/D/H/psi", MOVED_HERE},
+ {3, "A_mv/B/E", "normal", 2, "A/B/E"},
+ {3, "A_mv/B/E/alpha", "normal", 2, "A/B/E/alpha"},
+ {3, "A_mv/B/E/beta", "normal", 2, "A/B/E/beta"},
+
+ {0}
+ };
+
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_edit_obstruction(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_edit_obstruction", opts, pool));
+
+ SVN_ERR(sbox_add_and_commit_greek_tree(&b));
+
+ SVN_ERR(sbox_file_write(&b, "A/B/E/alpha", "Update alpha"));
+ SVN_ERR(sbox_wc_propset(&b, "a", "b", "A/B/F"));
+ SVN_ERR(sbox_wc_commit(&b, "")); /* r2 */
+
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ /* Simple move */
+ SVN_ERR(sbox_wc_move(&b, "A", "A_mv"));
+ 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[] = {
+ {1, "A_mv", "normal", 2, "A", MOVED_HERE},
+ {1, "A_mv/B", "normal", 2, "A/B", MOVED_HERE},
+ {1, "A_mv/B/E", "normal", 2, "A/B/E", MOVED_HERE},
+ {1, "A_mv/B/E/alpha", "normal", 2, "A/B/E/alpha", MOVED_HERE},
+ {1, "A_mv/B/E/beta", "normal", 2, "A/B/E/beta", MOVED_HERE},
+ {1, "A_mv/B/F", "normal", 2, "A/B/F", MOVED_HERE, "a"},
+ {1, "A_mv/B/lambda", "normal", 2, "A/B/lambda", MOVED_HERE},
+ {1, "A_mv/C", "normal", 2, "A/C", MOVED_HERE},
+ {1, "A_mv/D", "normal", 2, "A/D", MOVED_HERE},
+ {1, "A_mv/D/G", "normal", 2, "A/D/G", MOVED_HERE},
+ {1, "A_mv/D/G/pi", "normal", 2, "A/D/G/pi", MOVED_HERE},
+ {1, "A_mv/D/G/rho", "normal", 2, "A/D/G/rho", MOVED_HERE},
+ {1, "A_mv/D/G/tau", "normal", 2, "A/D/G/tau", MOVED_HERE},
+ {1, "A_mv/D/gamma", "normal", 2, "A/D/gamma", MOVED_HERE},
+ {1, "A_mv/D/H", "normal", 2, "A/D/H", MOVED_HERE},
+ {1, "A_mv/D/H/chi", "normal", 2, "A/D/H/chi", MOVED_HERE},
+ {1, "A_mv/D/H/omega", "normal", 2, "A/D/H/omega", MOVED_HERE},
+ {1, "A_mv/D/H/psi", "normal", 2, "A/D/H/psi", MOVED_HERE},
+ {1, "A_mv/mu", "normal", 2, "A/mu", MOVED_HERE},
+ {0}
+ };
+
+ SVN_ERR(check_db_rows(&b, "A_mv", nodes));
+ SVN_ERR(check_db_conflicts(&b, "", NULL));
+ }
+
+ /* Now do the same thing with local obstructions on the edited nodes */
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_revert(&b, "", svn_depth_infinity));
+ SVN_ERR(sbox_wc_move(&b, "A", "A_mv"));
+
+ SVN_ERR(svn_io_remove_file2(sbox_wc_path(&b, "A_mv/B/E/alpha"), FALSE, pool));
+ SVN_ERR(svn_io_dir_make(sbox_wc_path(&b, "A_mv/B/E/alpha"), APR_OS_DEFAULT,
+ pool));
+ SVN_ERR(svn_io_dir_remove_nonrecursive(sbox_wc_path(&b, "A_mv/B/F"), pool));
+ SVN_ERR(sbox_file_write(&b, "A_mv/B/F", "F file"));
+
+ 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[] = {
+ {1, "A_mv", "normal", 2, "A", MOVED_HERE},
+ {1, "A_mv/B", "normal", 2, "A/B", MOVED_HERE},
+ {1, "A_mv/B/E", "normal", 2, "A/B/E", MOVED_HERE},
+ {1, "A_mv/B/E/alpha", "normal", 2, "A/B/E/alpha", MOVED_HERE},
+ {1, "A_mv/B/E/beta", "normal", 2, "A/B/E/beta", MOVED_HERE},
+ {1, "A_mv/B/F", "normal", 2, "A/B/F", MOVED_HERE, "a"},
+ {1, "A_mv/B/lambda", "normal", 2, "A/B/lambda", MOVED_HERE},
+ {1, "A_mv/C", "normal", 2, "A/C", MOVED_HERE},
+ {1, "A_mv/D", "normal", 2, "A/D", MOVED_HERE},
+ {1, "A_mv/D/G", "normal", 2, "A/D/G", MOVED_HERE},
+ {1, "A_mv/D/G/pi", "normal", 2, "A/D/G/pi", MOVED_HERE},
+ {1, "A_mv/D/G/rho", "normal", 2, "A/D/G/rho", MOVED_HERE},
+ {1, "A_mv/D/G/tau", "normal", 2, "A/D/G/tau", MOVED_HERE},
+ {1, "A_mv/D/gamma", "normal", 2, "A/D/gamma", MOVED_HERE},
+ {1, "A_mv/D/H", "normal", 2, "A/D/H", MOVED_HERE},
+ {1, "A_mv/D/H/chi", "normal", 2, "A/D/H/chi", MOVED_HERE},
+ {1, "A_mv/D/H/omega", "normal", 2, "A/D/H/omega", MOVED_HERE},
+ {1, "A_mv/D/H/psi", "normal", 2, "A/D/H/psi", MOVED_HERE},
+ {1, "A_mv/mu", "normal", 2, "A/mu", MOVED_HERE},
+ {0}
+ };
+ conflict_info_t conflicts[] = {
+ {"A_mv/B/E/alpha", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_obstructed}},
+ {"A_mv/B/F", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_obstructed}},
+ {0}
+ };
+
+ SVN_ERR(check_db_rows(&b, "A_mv", nodes));
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_deep_bump(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "move_deep_bump", opts, pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "B/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "B/B/A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "B/B/A/A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "B/B/A/A/A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "C"));
+ SVN_ERR(sbox_wc_mkdir(&b, "C/C"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "Z"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "B/B/A/A/A/A"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ SVN_ERR(sbox_wc_move(&b, "B/B/A", "B/B/B"));
+ SVN_ERR(sbox_wc_move(&b, "B/B/B/A", "C/C/A"));
+
+ /* This can't bump C/C/A as that is outside the lock range
+ so we expect a tree conflict.
+
+ This used to cause a node not found during bumping
+ because B/B/B/A doesn't have a BASE node */
+ SVN_ERR(sbox_wc_update(&b, "B/B", 2));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "B", "normal", 1, "B"},
+ {0, "B/B", "normal", 2, "B/B"},
+ {0, "B/B/A", "normal", 2, "B/B/A"},
+ {0, "B/B/A/A", "normal", 2, "B/B/A/A"},
+ {0, "B/B/A/A/A", "normal", 2, "B/B/A/A/A"},
+ {0, "C", "normal", 1, "C"},
+ {0, "C/C", "normal", 1, "C/C"},
+ {3, "B/B/A", "base-deleted", NO_COPY_FROM, "B/B/B"},
+ {3, "B/B/A/A", "base-deleted", NO_COPY_FROM},
+ {3, "B/B/A/A/A", "base-deleted", NO_COPY_FROM},
+ {3, "B/B/B", "normal", 2, "B/B/A", MOVED_HERE},
+ {3, "B/B/B/A", "normal", 2, "B/B/A/A", MOVED_HERE},
+ {3, "B/B/B/A/A", "normal", 2, "B/B/A/A/A", MOVED_HERE},
+ {3, "C/C/A", "normal", 1, "B/B/A/A", MOVED_HERE},
+ {3, "C/C/A/A", "normal", 1, "B/B/A/A/A", MOVED_HERE},
+ {4, "B/B/B/A", "base-deleted", NO_COPY_FROM, "C/C/A"},
+ {4, "B/B/B/A/A", "base-deleted", NO_COPY_FROM},
+ {0}
+ };
+ conflict_info_t conflicts[] = {
+ {"B/B/B/A", FALSE, FALSE, {svn_wc_conflict_action_edit,
+ svn_wc_conflict_reason_moved_away, "B/B/B/A"}},
+ {0}
+ };
+
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ SVN_ERR(check_db_conflicts(&b, "", conflicts));
+ }
+
+ SVN_ERR(sbox_wc_resolve(&b, "B/B/B/A", svn_depth_empty,
+ svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(check_db_conflicts(&b, "", NULL));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+make_copy_mixed(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "make_copy_mixed", 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/E"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C/F"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/G"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/G/H"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/G/I"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/G/J"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/K"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/K/L"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/K/M"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/N"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/N/O"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/N/P"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/N/Q"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/R"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/R/S"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/R/S/T"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_propset(&b, "k", "r2", ""));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_propset(&b, "k", "r3", ""));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_propset(&b, "k", "r4", ""));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_propset(&b, "k", "r5", ""));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ SVN_ERR(sbox_wc_update(&b, "", 5));
+ SVN_ERR(sbox_wc_update(&b, "A", 4));
+ SVN_ERR(sbox_wc_update(&b, "A/B", 3));
+ SVN_ERR(sbox_wc_update(&b, "A/B/C", 2));
+ SVN_ERR(sbox_wc_update(&b, "A/B/K", 1));
+ SVN_ERR(sbox_wc_update(&b, "A/N/O", 3));
+
+ SVN_ERR(sbox_wc_delete(&b, "A/B/C/F"));
+ SVN_ERR(sbox_wc_delete(&b, "A/B/G/J"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/G/J"));
+
+ SVN_ERR(sbox_wc_update(&b, "A/N/P", 1));
+ SVN_ERR(sbox_wc_update(&b, "A/N/Q", 1));
+ SVN_ERR(sbox_wc_delete(&b, "A/N/P"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/N/P"));
+ SVN_ERR(sbox_wc_move(&b, "A/N/Q", "Q"));
+ SVN_ERR(sbox_wc_move(&b, "A/B/G/H", "H"));
+
+ /* And something that can't be represented */
+ SVN_ERR(sbox_wc_update(&b, "A/B/C/E", 1));
+ SVN_ERR(sbox_wc_move(&b, "A/B/C/E", "E"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 5, "", NOT_MOVED, "k"},
+ {0, "A", "normal", 4, "A"},
+ {0, "A/B", "normal", 3, "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/E", "normal", 1, "A/B/C/E"},
+ {0, "A/B/C/F", "normal", 2, "A/B/C/F"},
+ {0, "A/B/G", "normal", 3, "A/B/G"},
+ {0, "A/B/G/H", "normal", 3, "A/B/G/H"},
+ {0, "A/B/G/I", "normal", 3, "A/B/G/I"},
+ {0, "A/B/G/J", "normal", 3, "A/B/G/J"},
+ {0, "A/B/K", "normal", 1, "A/B/K"},
+ {0, "A/B/K/L", "normal", 1, "A/B/K/L"},
+ {0, "A/B/K/M", "normal", 1, "A/B/K/M"},
+ {0, "A/N", "normal", 4, "A/N"},
+ {0, "A/N/O", "normal", 3, "A/N/O"},
+ {0, "A/N/P", "normal", 1, "A/N/P"},
+ {0, "A/N/Q", "normal", 1, "A/N/Q"},
+ {0, "A/R", "normal", 4, "A/R"},
+ {0, "A/R/S", "normal", 4, "A/R/S"},
+ {0, "A/R/S/T", "normal", 4, "A/R/S/T"},
+ {1, "E", "normal", 1, "A/B/C/E", MOVED_HERE},
+ {1, "H", "normal", 3, "A/B/G/H", MOVED_HERE},
+ {1, "Q", "normal", 1, "A/N/Q", MOVED_HERE},
+ {3, "A/N/P", "normal", NO_COPY_FROM},
+ {3, "A/N/Q", "base-deleted", NO_COPY_FROM, "Q"},
+ {4, "A/B/C/E", "base-deleted", NO_COPY_FROM, "E"},
+ {4, "A/B/C/F", "base-deleted", NO_COPY_FROM},
+ {4, "A/B/G/H", "base-deleted", NO_COPY_FROM, "H"},
+ {4, "A/B/G/J", "normal", NO_COPY_FROM},
+
+ {0}
+ };
+
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(svn_wc__db_op_make_copy(b.wc_ctx->db, sbox_wc_path(&b, "A"),
+ NULL, NULL, pool));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 5, "", NOT_MOVED, "k"},
+ {0, "A", "normal", 4, "A"},
+ {0, "A/B", "normal", 3, "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/E", "normal", 1, "A/B/C/E"},
+ {0, "A/B/C/F", "normal", 2, "A/B/C/F"},
+ {0, "A/B/G", "normal", 3, "A/B/G"},
+ {0, "A/B/G/H", "normal", 3, "A/B/G/H"},
+ {0, "A/B/G/I", "normal", 3, "A/B/G/I"},
+ {0, "A/B/G/J", "normal", 3, "A/B/G/J"},
+ {0, "A/B/K", "normal", 1, "A/B/K"},
+ {0, "A/B/K/L", "normal", 1, "A/B/K/L"},
+ {0, "A/B/K/M", "normal", 1, "A/B/K/M"},
+ {0, "A/N", "normal", 4, "A/N"},
+ {0, "A/N/O", "normal", 3, "A/N/O"},
+ {0, "A/N/P", "normal", 1, "A/N/P"},
+ {0, "A/N/Q", "normal", 1, "A/N/Q"},
+ {0, "A/R", "normal", 4, "A/R"},
+ {0, "A/R/S", "normal", 4, "A/R/S"},
+ {0, "A/R/S/T", "normal", 4, "A/R/S/T"},
+ {1, "A", "normal", 4, "A"},
+ {1, "A/B", "not-present", 3, "A/B"},
+ {1, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C/D", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C/E", "base-deleted", NO_COPY_FROM, "E"},
+ {1, "A/B/C/F", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/G", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/G/H", "base-deleted", NO_COPY_FROM, "H"},
+ {1, "A/B/G/I", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/G/J", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/K", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/K/L", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/K/M", "base-deleted", NO_COPY_FROM},
+ {1, "A/N", "normal", 4, "A/N"},
+ {1, "A/N/O", "not-present", 3, "A/N/O"},
+ {1, "A/N/P", "not-present", 1, "A/N/P"},
+ {1, "A/N/Q", "not-present", 1, "A/N/Q", FALSE, "Q"},
+ {1, "A/R", "normal", 4, "A/R"},
+ {1, "A/R/S", "normal", 4, "A/R/S"},
+ {1, "A/R/S/T", "normal", 4, "A/R/S/T"},
+ {1, "E", "normal", 1, "A/B/C/E", MOVED_HERE},
+ {1, "H", "normal", 3, "A/B/G/H", MOVED_HERE},
+ {1, "Q", "normal", 1, "A/N/Q", MOVED_HERE},
+ {2, "A/B", "normal", 3, "A/B"},
+ {2, "A/B/C", "not-present", 2, "A/B/C"},
+ {2, "A/B/G", "normal", 3, "A/B/G"},
+ {2, "A/B/G/H", "normal", 3, "A/B/G/H"},
+ {2, "A/B/G/I", "normal", 3, "A/B/G/I"},
+ {2, "A/B/G/J", "normal", 3, "A/B/G/J"},
+ {2, "A/B/K", "not-present", 1, "A/B/K"},
+ {3, "A/B/C", "normal", 2, "A/B/C"},
+ {3, "A/B/C/D", "normal", 2, "A/B/C/D"},
+ {3, "A/B/C/E", "not-present", 1, "A/B/C/E"},
+ {3, "A/B/C/F", "normal", 2, "A/B/C/F"},
+ {3, "A/B/K", "normal", 1, "A/B/K"},
+ {3, "A/B/K/L", "normal", 1, "A/B/K/L"},
+ {3, "A/B/K/M", "normal", 1, "A/B/K/M"},
+ {3, "A/N/O", "normal", 3, "A/N/O"},
+ {3, "A/N/P", "normal", NO_COPY_FROM},
+ {4, "A/B/C/F", "base-deleted", NO_COPY_FROM},
+ {4, "A/B/G/H", "base-deleted", NO_COPY_FROM},
+ {4, "A/B/G/J", "normal", NO_COPY_FROM},
+
+ {0}
+ };
+
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(verify_db(&b));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+make_copy_and_delete_mixed(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "make_copy_and_del_mixed", 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/E"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C/F"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/G"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/G/H"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/G/I"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/G/J"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/K"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/K/L"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/K/M"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/N"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/N/O"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/N/P"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/N/Q"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/R"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/R/S"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/R/S/T"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_propset(&b, "k", "r2", ""));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_propset(&b, "k", "r3", ""));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_propset(&b, "k", "r4", ""));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_propset(&b, "k", "r5", ""));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ SVN_ERR(sbox_wc_update(&b, "", 5));
+ SVN_ERR(sbox_wc_update(&b, "A", 4));
+ SVN_ERR(sbox_wc_update(&b, "A/B", 3));
+ SVN_ERR(sbox_wc_update(&b, "A/B/C", 2));
+ SVN_ERR(sbox_wc_update(&b, "A/B/K", 1));
+ SVN_ERR(sbox_wc_update(&b, "A/N/O", 3));
+
+ SVN_ERR(sbox_wc_delete(&b, "A/B/C/F"));
+ SVN_ERR(sbox_wc_delete(&b, "A/B/G/J"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/G/J"));
+
+ SVN_ERR(sbox_wc_update(&b, "A/N/P", 1));
+ SVN_ERR(sbox_wc_update(&b, "A/N/Q", 1));
+ SVN_ERR(sbox_wc_delete(&b, "A/N/P"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/N/P"));
+ SVN_ERR(sbox_wc_move(&b, "A/N/Q", "Q"));
+ SVN_ERR(sbox_wc_move(&b, "A/B/G/H", "H"));
+
+ /* And something that can't be represented */
+ SVN_ERR(sbox_wc_update(&b, "A/B/C/E", 1));
+ SVN_ERR(sbox_wc_move(&b, "A/B/C/E", "E"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 5, "", NOT_MOVED, "k"},
+ {0, "A", "normal", 4, "A"},
+ {0, "A/B", "normal", 3, "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/E", "normal", 1, "A/B/C/E"},
+ {0, "A/B/C/F", "normal", 2, "A/B/C/F"},
+ {0, "A/B/G", "normal", 3, "A/B/G"},
+ {0, "A/B/G/H", "normal", 3, "A/B/G/H"},
+ {0, "A/B/G/I", "normal", 3, "A/B/G/I"},
+ {0, "A/B/G/J", "normal", 3, "A/B/G/J"},
+ {0, "A/B/K", "normal", 1, "A/B/K"},
+ {0, "A/B/K/L", "normal", 1, "A/B/K/L"},
+ {0, "A/B/K/M", "normal", 1, "A/B/K/M"},
+ {0, "A/N", "normal", 4, "A/N"},
+ {0, "A/N/O", "normal", 3, "A/N/O"},
+ {0, "A/N/P", "normal", 1, "A/N/P"},
+ {0, "A/N/Q", "normal", 1, "A/N/Q"},
+ {0, "A/R", "normal", 4, "A/R"},
+ {0, "A/R/S", "normal", 4, "A/R/S"},
+ {0, "A/R/S/T", "normal", 4, "A/R/S/T"},
+ {1, "E", "normal", 1, "A/B/C/E", MOVED_HERE},
+ {1, "H", "normal", 3, "A/B/G/H", MOVED_HERE},
+ {1, "Q", "normal", 1, "A/N/Q", MOVED_HERE},
+ {3, "A/N/P", "normal", NO_COPY_FROM},
+ {3, "A/N/Q", "base-deleted", NO_COPY_FROM, "Q"},
+ {4, "A/B/C/E", "base-deleted", NO_COPY_FROM, "E"},
+ {4, "A/B/C/F", "base-deleted", NO_COPY_FROM},
+ {4, "A/B/G/H", "base-deleted", NO_COPY_FROM, "H"},
+ {4, "A/B/G/J", "normal", NO_COPY_FROM},
+
+ {0}
+ };
+
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(svn_wc__db_base_remove(b.wc_ctx->db, sbox_wc_path(&b, "A"),
+ TRUE, TRUE, FALSE, 99,
+ NULL, NULL, pool));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 5, "", NOT_MOVED, "k"},
+ {0, "A", "not-present", 99, "A"},
+ {1, "A", "normal", 4, "A"},
+ {1, "A/B", "not-present", 3, "A/B"},
+ {1, "A/N", "normal", 4, "A/N"},
+ {1, "A/N/O", "not-present", 3, "A/N/O"},
+ {1, "A/N/P", "not-present", 1, "A/N/P"},
+ {1, "A/N/Q", "not-present", 1, "A/N/Q", FALSE},
+ {1, "A/R", "normal", 4, "A/R"},
+ {1, "A/R/S", "normal", 4, "A/R/S"},
+ {1, "A/R/S/T", "normal", 4, "A/R/S/T"},
+ {1, "E", "normal", 1, "A/B/C/E"},
+ {1, "H", "normal", 3, "A/B/G/H", MOVED_HERE},
+ {1, "Q", "normal", 1, "A/N/Q"},
+ {2, "A/B", "normal", 3, "A/B"},
+ {2, "A/B/C", "not-present", 2, "A/B/C"},
+ {2, "A/B/G", "normal", 3, "A/B/G"},
+ {2, "A/B/G/H", "normal", 3, "A/B/G/H"},
+ {2, "A/B/G/I", "normal", 3, "A/B/G/I"},
+ {2, "A/B/G/J", "normal", 3, "A/B/G/J"},
+ {3, "A/B/C", "normal", 2, "A/B/C"},
+ {3, "A/B/C/D", "normal", 2, "A/B/C/D"},
+ {3, "A/B/C/E", "not-present", 1, "A/B/C/E"},
+ {3, "A/B/C/F", "normal", 2, "A/B/C/F"},
+ {2, "A/B/K", "not-present", 1, "A/B/K"},
+ {3, "A/B/K", "normal", 1, "A/B/K"},
+ {3, "A/B/K/L", "normal", 1, "A/B/K/L"},
+ {3, "A/B/K/M", "normal", 1, "A/B/K/M"},
+ {3, "A/N/O", "normal", 3, "A/N/O"},
+ {3, "A/N/P", "normal", NO_COPY_FROM},
+ {4, "A/B/C/F", "base-deleted", NO_COPY_FROM},
+ {4, "A/B/G/H", "base-deleted", NO_COPY_FROM, "H"},
+ {4, "A/B/G/J", "normal", NO_COPY_FROM},
+
+ {0}
+ };
+
+ /* This currently fails because Q and E are still marked as moved,
+ while there is nothing to be moved. */
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(verify_db(&b));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_global_commit(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "global_commit", opts, pool));
+
+ {
+ nodes_row_t before[] = {
+ { 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/D", "normal", 2, "A/B/D" },
+ { 0, "A/B/D/E", "normal", 2, "A/B/D/E" },
+ { 0, "A/F", "normal", 2, "A/F" },
+ { 0, "A/F/G", "normal", 2, "A/F/G" },
+ { 0, "A/F/H", "normal", 2, "A/F/H" },
+ { 0, "A/F/E", "normal", 2, "A/F/E" },
+ { 0, "A/X", "normal", 2, "A/X" },
+ { 0, "A/X/Y", "incomplete", 2, "A/X/Y" },
+ { 1, "C", "normal", 2, "A/B/C", MOVED_HERE},
+ { 1, "E", "normal", 2, "A/B/D/E", MOVED_HERE},
+ { 2, "A/B", "normal", 3, "some", MOVED_HERE },
+ { 2, "A/B/C", "base-deleted", NO_COPY_FROM, "C" },
+ { 2, "A/B/D", "normal", 3, "some/D", MOVED_HERE},
+ { 2, "A/B/D/E", "not-present", 3, "some/D/E", FALSE, "E", TRUE},
+ { 3, "A/B/C", "normal", NO_COPY_FROM},
+ { 2, "A/F", "normal", 1, "S2" },
+ { 2, "A/F/G", "normal", 1, "S2/G" },
+ { 2, "A/F/H", "not-present", 1, "S2/H" },
+ { 2, "A/F/E", "base-deleted", NO_COPY_FROM },
+ { 1, "some", "normal", 3, "some", FALSE, "A/B"},
+ { 0 }
+ };
+ SVN_ERR(insert_dirs(&b, before));
+ SVN_ERR(check_db_rows(&b, "", before)); /* Check move insertion logic */
+ SVN_ERR(verify_db(&b));
+ }
+
+ /* This should break the moves */
+ SVN_ERR(svn_wc__db_global_commit(b.wc_ctx->db,
+ sbox_wc_path(&b, "A/B"),
+ 5, 5, 700, "me", NULL, NULL,
+ FALSE, FALSE, NULL, pool));
+ {
+ nodes_row_t after[] = {
+ { 0, "", "normal", 2, "" },
+ { 0, "A", "normal", 2, "A" },
+ { 0, "A/B", "normal", 5, "A/B" },
+ { 0, "A/B/D", "normal", 5, "A/B/D"},
+ { 0, "A/B/D/E", "not-present", 5, "A/B/D/E"},
+ { 0, "A/F", "normal", 2, "A/F" },
+ { 0, "A/F/G", "normal", 2, "A/F/G" },
+ { 0, "A/F/H", "normal", 2, "A/F/H" },
+ { 0, "A/F/E", "normal", 2, "A/F/E" },
+ { 0, "A/X", "normal", 2, "A/X" },
+ { 0, "A/X/Y", "incomplete", 2, "A/X/Y" },
+ { 1, "C", "normal", 2, "A/B/C"},
+ { 1, "E", "normal", 2, "A/B/D/E"},
+ { 1, "some", "normal", 3, "some"},
+ { 3, "A/B/C", "normal", NO_COPY_FROM},
+ { 2, "A/F", "normal", 1, "S2" },
+ { 2, "A/F/G", "normal", 1, "S2/G" },
+ { 2, "A/F/H", "not-present", 1, "S2/H" },
+ { 2, "A/F/E", "base-deleted", NO_COPY_FROM },
+ { 0 }
+ };
+
+ SVN_ERR(check_db_rows(&b, "", after));
+ SVN_ERR(verify_db(&b));
+ }
+
+ SVN_ERR(svn_wc__db_global_commit(b.wc_ctx->db,
+ sbox_wc_path(&b, "A/F"),
+ 6, 6, 800, "me", NULL, NULL,
+ FALSE, FALSE, NULL, pool));
+
+ {
+ nodes_row_t after[] = {
+ { 0, "", "normal", 2, "" },
+ { 0, "A", "normal", 2, "A" },
+ { 0, "A/B", "normal", 5, "A/B" },
+ { 0, "A/B/D", "normal", 5, "A/B/D"},
+ { 0, "A/B/D/E", "not-present", 5, "A/B/D/E"},
+ { 0, "A/F", "normal", 6, "A/F" },
+ { 0, "A/F/G", "normal", 6, "A/F/G" },
+ { 0, "A/F/H", "not-present", 6, "A/F/H" },
+ { 0, "A/X", "normal", 2, "A/X" },
+ { 0, "A/X/Y", "incomplete", 2, "A/X/Y" },
+ { 1, "C", "normal", 2, "A/B/C"},
+ { 1, "E", "normal", 2, "A/B/D/E"},
+ { 1, "some", "normal", 3, "some"},
+ { 3, "A/B/C", "normal", NO_COPY_FROM },
+ { 0 }
+ };
+
+ SVN_ERR(check_db_rows(&b, "", after));
+ SVN_ERR(verify_db(&b));
+ }
+
+ SVN_ERR(svn_wc__db_global_commit(b.wc_ctx->db,
+ sbox_wc_path(&b, "A/B/C"),
+ 7, 7, 900, "me", NULL, NULL,
+ FALSE, FALSE, NULL, pool));
+
+ {
+ nodes_row_t after[] = {
+ { 0, "", "normal", 2, "" },
+ { 0, "A", "normal", 2, "A" },
+ { 0, "A/B", "normal", 5, "A/B" },
+ { 0, "A/B/C", "normal", 7, "A/B/C"},
+ { 0, "A/B/D", "normal", 5, "A/B/D"},
+ { 0, "A/B/D/E", "not-present", 5, "A/B/D/E"},
+ { 0, "A/F", "normal", 6, "A/F" },
+ { 0, "A/F/G", "normal", 6, "A/F/G" },
+ { 0, "A/F/H", "not-present", 6, "A/F/H" },
+ { 0, "A/X", "normal", 2, "A/X" },
+ { 0, "A/X/Y", "incomplete", 2, "A/X/Y" },
+ { 1, "some", "normal", 3, "some"},
+ { 1, "E", "normal", 2, "A/B/D/E"},
+ { 1, "C", "normal", 2, "A/B/C"},
+ { 0 }
+ };
+
+ SVN_ERR(check_db_rows(&b, "", after));
+ SVN_ERR(verify_db(&b));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_global_commit_switched(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "global_commit_switched", opts, pool));
+ {
+ nodes_row_t before[] = {
+ { 0, "", "normal", 2, "" },
+ { 0, "A", "normal", 2, "A" },
+ /* A/B is switched... The libsvn_client layer tries to prevent this,
+ because it has such an unexpected behavior. */
+ { 0, "A/B", "normal", 2, "N/B" },
+ { 0, "A/B/C", "normal", 2, "N/B/C" },
+ { 0, "A/B/C/D", "normal", 2, "N/B/C/D" },
+ { 0, "A/B/C/E", "normal", 2, "N/B/C/E" },
+ { 2, "A/B", "normal", 3, "Z/B" },
+ { 2, "A/B/C", "normal", 3, "Z/B/C" },
+ { 2, "A/B/C/D", "normal", 3, "Z/B/C/D" },
+ { 2, "A/B/C/E", "base-deleted", NO_COPY_FROM },
+ /* not-present nodes have an 'uninteresting path',
+ which doesn't have to be as implied by ancestor at same depth */
+ { 2, "A/B/C/F", "not-present", 3, "ZZ-Z-Z_ZZ_Z_Z" },
+ { 2, "A/B/C/G", "normal", 3, "Z/B/C/G" },
+ { 2, "A/B/C/G/H", "normal", 3, "Z/B/C/G/H" },
+
+ { 3, "A/B/C", "normal", 4, "Q/C" },
+ { 3, "A/B/C/D", "base-deleted", NO_COPY_FROM },
+ { 3, "A/B/C/G", "normal", 4, "Q/C/G" },
+ { 3, "A/B/C/G/H", "base-deleted", NO_COPY_FROM },
+
+ { 4, "A/B/C/F", "normal", NO_COPY_FROM },
+ { 5, "A/B/C/G/H", "normal", NO_COPY_FROM },
+ { 0 }
+ };
+ SVN_ERR(insert_dirs(&b, before));
+ SVN_ERR(verify_db(&b));
+ }
+
+ SVN_ERR(svn_wc__db_global_commit(b.wc_ctx->db,
+ sbox_wc_path(&b, "A/B"),
+ 7, 7, 12, "me", NULL, NULL,
+ FALSE, FALSE, NULL, pool));
+
+ {
+ nodes_row_t after[] = {
+ { 0, "", "normal", 2, "" },
+ { 0, "A", "normal", 2, "A" },
+ /* The commit is applied as A/B, because the path is calculated from A,
+ and not the shadowed node at A/B. (Fixed in r1663991) */
+ { 0, "A/B", "normal", 7, "A/B" },
+ { 0, "A/B/C", "normal", 7, "A/B/C" },
+ { 0, "A/B/C/D", "normal", 7, "A/B/C/D" },
+ /* Even calculated path of not-present is fixed */
+ { 0, "A/B/C/F", "not-present", 7, "A/B/C/F" },
+ { 0, "A/B/C/G", "normal", 7, "A/B/C/G" },
+ { 0, "A/B/C/G/H", "normal", 7, "A/B/C/G/H" },
+
+ /* The higher layers are unaffected */
+ { 3, "A/B/C", "normal", 4, "Q/C" },
+ { 3, "A/B/C/D", "base-deleted", NO_COPY_FROM },
+ { 3, "A/B/C/G", "normal", 4, "Q/C/G" },
+ { 3, "A/B/C/G/H", "base-deleted", NO_COPY_FROM },
+
+ { 4, "A/B/C/F", "normal", NO_COPY_FROM },
+ { 5, "A/B/C/G/H", "normal", NO_COPY_FROM },
+ { 0 }
+ };
+ SVN_ERR(verify_db(&b));
+ SVN_ERR(check_db_rows(&b, "", after));
+ }
+
+ SVN_ERR(svn_wc__db_global_commit(b.wc_ctx->db,
+ sbox_wc_path(&b, "A/B/C"),
+ 8, 8, 12, "me", NULL, NULL,
+ FALSE, FALSE, NULL, pool));
+
+ {
+ nodes_row_t after[] = {
+ { 0, "", "normal", 2, "" },
+ { 0, "A", "normal", 2, "A" },
+ { 0, "A/B", "normal", 7, "A/B" },
+ /* Base deleted and not-present are now gone */
+ { 0, "A/B/C", "normal", 8, "A/B/C" },
+ { 0, "A/B/C/G", "normal", 8, "A/B/C/G" },
+
+ { 4, "A/B/C/F", "normal", NO_COPY_FROM },
+ { 5, "A/B/C/G/H", "normal", NO_COPY_FROM },
+ { 0 }
+ };
+ SVN_ERR(verify_db(&b));
+ SVN_ERR(check_db_rows(&b, "", after));
+ }
+
+ return SVN_NO_ERROR;
+}
+
/* ---------------------------------------------------------------------- */
/* The list of test functions */
-struct svn_test_descriptor_t test_funcs[] =
+static int max_threads = 4;
+
+static struct svn_test_descriptor_t test_funcs[] =
{
SVN_TEST_NULL,
SVN_TEST_OPTS_PASS(test_wc_wc_copies,
@@ -9047,8 +11898,8 @@ struct svn_test_descriptor_t test_funcs[] =
"test_adds_change_kind"),
SVN_TEST_OPTS_PASS(test_base_dir_insert_remove,
"test_base_dir_insert_remove"),
- SVN_TEST_OPTS_PASS(test_temp_op_make_copy,
- "test_temp_op_make_copy"),
+ SVN_TEST_OPTS_PASS(test_db_make_copy,
+ "test_db_make_copy"),
SVN_TEST_OPTS_PASS(test_wc_move,
"test_wc_move"),
SVN_TEST_OPTS_PASS(test_mixed_rev_copy,
@@ -9168,12 +12019,16 @@ struct svn_test_descriptor_t test_funcs[] =
"move_parent_into_child (issue 4333)"),
SVN_TEST_OPTS_PASS(move_depth_expand,
"move depth expansion"),
- SVN_TEST_OPTS_PASS(move_retract,
+ SVN_TEST_OPTS_XFAIL(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_update_parent_replace,
+ "move update with replaced parent (issue 4388)"),
+ SVN_TEST_OPTS_PASS(copy_mixed_rev_mods,
+ "copy mixed-rev with mods"),
SVN_TEST_OPTS_PASS(move_child_to_parent_revert,
"move child to parent and revert (issue 4436)"),
SVN_TEST_OPTS_PASS(move_delete_intermediate,
@@ -9184,13 +12039,55 @@ struct svn_test_descriptor_t test_funcs[] =
"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(del4_update_edit_AAA,
+ "del4: edit AAA"),
+ SVN_TEST_OPTS_XFAIL(del4_update_delete_AAA,
+ "del4: delete AAA"),
+ SVN_TEST_OPTS_XFAIL(del4_update_add_AAA,
+ "del4: add AAA"),
+ SVN_TEST_OPTS_XFAIL(del4_update_replace_AAA,
+ "del4: replace AAA"),
+ SVN_TEST_OPTS_PASS(del4_update_delself_AAA,
+ "del4: delete self AAA"),
+ SVN_TEST_OPTS_XFAIL(del4_update_replaceself_AAA,
+ "del4: replace self AAA"),
+ SVN_TEST_OPTS_PASS(move4_update_edit_AAA,
+ "move4: edit AAA"),
+ SVN_TEST_OPTS_XFAIL(move4_update_delete_AAA,
+ "move4: delete AAA"),
+ SVN_TEST_OPTS_XFAIL(move4_update_add_AAA,
+ "move4: add AAA"),
+ SVN_TEST_OPTS_XFAIL(move4_update_replace_AAA,
+ "move4: replace AAA"),
+ SVN_TEST_OPTS_PASS(move4_update_delself_AAA,
+ "move4: delete self AAA"),
+ SVN_TEST_OPTS_XFAIL(move4_update_replaceself_AAA,
+ "move4: replace self AAA"),
+ SVN_TEST_OPTS_PASS(simple_move_bump,
+ "simple move bump"),
SVN_TEST_OPTS_PASS(movedhere_extract_retract,
"movedhere extract retract"),
+ SVN_TEST_OPTS_PASS(repo_wc_copy,
+ "repo_wc_copy"),
+ SVN_TEST_OPTS_PASS(break_move_in_delete,
+ "break move in delete (issue 4491)"),
SVN_TEST_OPTS_PASS(nested_move_delete,
"nested move delete"),
+ SVN_TEST_OPTS_XFAIL(move_within_mixed_move,
+ "move within mixed move"),
+ SVN_TEST_OPTS_PASS(move_edit_obstruction,
+ "move edit obstruction"),
+ SVN_TEST_OPTS_PASS(move_deep_bump,
+ "move deep bump"),
+ SVN_TEST_OPTS_PASS(make_copy_mixed,
+ "make a copy of a mixed revision tree"),
+ SVN_TEST_OPTS_PASS(make_copy_and_delete_mixed,
+ "make a copy of a mixed revision tree and del"),
+ SVN_TEST_OPTS_PASS(test_global_commit,
+ "test global commit"),
+ SVN_TEST_OPTS_PASS(test_global_commit_switched,
+ "test global commit switched"),
SVN_TEST_NULL
};
+
+SVN_TEST_MAIN