summaryrefslogtreecommitdiff
path: root/subversion/tests/libsvn_wc
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/tests/libsvn_wc')
-rw-r--r--subversion/tests/libsvn_wc/conflict-data-test.c178
-rw-r--r--subversion/tests/libsvn_wc/db-test.c634
-rw-r--r--subversion/tests/libsvn_wc/entries-compat.c388
-rw-r--r--subversion/tests/libsvn_wc/op-depth-test.c3547
-rw-r--r--subversion/tests/libsvn_wc/pristine-store-test.c138
-rw-r--r--subversion/tests/libsvn_wc/utils.c265
-rw-r--r--subversion/tests/libsvn_wc/utils.h55
-rw-r--r--subversion/tests/libsvn_wc/wc-lock-tester.c33
-rw-r--r--subversion/tests/libsvn_wc/wc-queries-test.c223
-rw-r--r--subversion/tests/libsvn_wc/wc-test-queries.h112
-rw-r--r--subversion/tests/libsvn_wc/wc-test-queries.sql78
-rw-r--r--subversion/tests/libsvn_wc/wc-test.c143
12 files changed, 4790 insertions, 1004 deletions
diff --git a/subversion/tests/libsvn_wc/conflict-data-test.c b/subversion/tests/libsvn_wc/conflict-data-test.c
index 97d22ea..7d89825 100644
--- a/subversion/tests/libsvn_wc/conflict-data-test.c
+++ b/subversion/tests/libsvn_wc/conflict-data-test.c
@@ -134,7 +134,7 @@ compare_file_content(const char *file_abspath,
* conflict, or are both NULL. Return an error if not.
*
* Compare the property values found in files named by
- * ACTUAL->base_abspath, ACTUAL->my_abspath, ACTUAL->merged_abspath
+ * ACTUAL->base_abspath, ACTUAL->my_abspath, ACTUAL->merged_file
* with EXPECTED_BASE_VAL, EXPECTED_MY_VAL, EXPECTED_THEIR_VAL
* respectively, ignoring the corresponding fields in EXPECTED. */
static svn_error_t *
@@ -236,8 +236,8 @@ test_deserialize_tree_conflict(apr_pool_t *pool)
SVN_ERR(svn_wc__deserialize_conflict(&conflict, skel, "", pool, pool));
if ((conflict->node_kind != exp_conflict->node_kind) ||
- (conflict->action != exp_conflict->action) ||
- (conflict->reason != exp_conflict->reason) ||
+ (conflict->action != exp_conflict->action) ||
+ (conflict->reason != exp_conflict->reason) ||
(conflict->operation != exp_conflict->operation) ||
(strcmp(conflict->local_abspath, exp_conflict->local_abspath) != 0))
return fail(pool, "Unexpected tree conflict");
@@ -289,10 +289,12 @@ test_read_write_tree_conflicts(const svn_test_opts_t *opts,
SVN_ERR(svn_test__sandbox_create(&sbox, "read_write_tree_conflicts", opts, pool));
parent_abspath = svn_dirent_join(sbox.wc_abspath, "A", pool);
- SVN_ERR(svn_wc__db_op_add_directory(sbox.wc_ctx->db, parent_abspath,
- NULL /*props*/, NULL, pool));
child1_abspath = svn_dirent_join(parent_abspath, "foo", pool);
child2_abspath = svn_dirent_join(parent_abspath, "bar", pool);
+ SVN_ERR(sbox_wc_mkdir(&sbox, "A"));
+ SVN_ERR(sbox_wc_mkdir(&sbox, "A/bar"));
+ SVN_ERR(sbox_file_write(&sbox, "A/foo", ""));
+ SVN_ERR(sbox_wc_add(&sbox, "A/foo"));
conflict1 = tree_conflict_create(child1_abspath, svn_node_file,
svn_wc_operation_merge,
@@ -606,22 +608,22 @@ test_serialize_tree_conflict(const svn_test_opts_t *opts,
SVN_TEST_ASSERT(complete); /* Everything available */
{
- svn_wc_conflict_reason_t local_change;
- svn_wc_conflict_action_t incoming_change;
+ svn_wc_conflict_reason_t reason;
+ svn_wc_conflict_action_t action;
const char *moved_away_op_root_abspath;
- SVN_ERR(svn_wc__conflict_read_tree_conflict(&local_change,
- &incoming_change,
+ SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason,
+ &action,
&moved_away_op_root_abspath,
sbox.wc_ctx->db,
sbox.wc_abspath,
conflict_skel,
pool, pool));
- SVN_TEST_ASSERT(local_change == svn_wc_conflict_reason_moved_away);
- SVN_TEST_ASSERT(incoming_change == svn_wc_conflict_action_delete);
- SVN_TEST_ASSERT(!strcmp(moved_away_op_root_abspath,
- sbox_wc_path(&sbox, "A/B")));
+ SVN_TEST_ASSERT(reason == svn_wc_conflict_reason_moved_away);
+ SVN_TEST_ASSERT(action == svn_wc_conflict_action_delete);
+ SVN_TEST_STRING_ASSERT(moved_away_op_root_abspath,
+ sbox_wc_path(&sbox, "A/B"));
}
return SVN_NO_ERROR;
@@ -807,9 +809,152 @@ test_prop_conflicts(const svn_test_opts_t *opts,
return SVN_NO_ERROR;
}
+static svn_error_t *
+test_prop_conflict_resolving(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+ svn_skel_t *conflict;
+ const char *A_abspath;
+ const char *marker_abspath;
+ apr_hash_t *conflicted_props;
+ apr_hash_t *props;
+ const char *value;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "test_prop_resolving", opts, pool));
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+
+ SVN_ERR(sbox_wc_propset(&b, "prop-1", "r1", "A"));
+ SVN_ERR(sbox_wc_propset(&b, "prop-2", "r1", "A"));
+ SVN_ERR(sbox_wc_propset(&b, "prop-3", "r1", "A"));
+ SVN_ERR(sbox_wc_propset(&b, "prop-4", "r1", "A"));
+ SVN_ERR(sbox_wc_propset(&b, "prop-5", "r1", "A"));
+ SVN_ERR(sbox_wc_propset(&b, "prop-6", "r1", "A"));
+
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_propset(&b, "prop-1", "r2", "A"));
+ SVN_ERR(sbox_wc_propset(&b, "prop-2", "r2", "A"));
+ SVN_ERR(sbox_wc_propset(&b, "prop-3", "r2", "A"));
+ SVN_ERR(sbox_wc_propset(&b, "prop-4", NULL, "A"));
+ SVN_ERR(sbox_wc_propset(&b, "prop-5", NULL, "A"));
+ SVN_ERR(sbox_wc_propset(&b, "prop-7", "r2", "A"));
+ SVN_ERR(sbox_wc_propset(&b, "prop-8", "r2", "A"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ SVN_ERR(sbox_wc_propset(&b, "prop-1", "mod", "A"));
+ SVN_ERR(sbox_wc_propset(&b, "prop-2", "mod", "A"));
+ SVN_ERR(sbox_wc_propset(&b, "prop-3", "mod", "A"));
+ SVN_ERR(sbox_wc_propset(&b, "prop-4", "mod", "A"));
+ SVN_ERR(sbox_wc_propset(&b, "prop-5", "mod", "A"));
+ SVN_ERR(sbox_wc_propset(&b, "prop-6", "mod", "A"));
+ SVN_ERR(sbox_wc_propset(&b, "prop-7", "mod", "A"));
+ SVN_ERR(sbox_wc_propset(&b, "prop-8", "mod", "A"));
+
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+
+ A_abspath = sbox_wc_path(&b, "A");
+ SVN_ERR(svn_wc__db_read_conflict(&conflict, NULL, NULL,
+ b.wc_ctx->db, A_abspath,
+ pool, pool));
+
+ /* We have tree conflicts... */
+ SVN_TEST_ASSERT(conflict != NULL);
+
+ SVN_ERR(svn_wc__conflict_read_prop_conflict(&marker_abspath,
+ NULL, NULL, NULL,
+ &conflicted_props,
+ b.wc_ctx->db, A_abspath,
+ conflict,
+ pool, pool));
+
+ SVN_TEST_ASSERT(conflicted_props != NULL);
+ /* All properties but r6 are conflicted */
+ SVN_TEST_ASSERT(apr_hash_count(conflicted_props) == 7);
+ SVN_TEST_ASSERT(! svn_hash_gets(conflicted_props, "prop-6"));
+
+ /* Let's resolve a few conflicts */
+ SVN_ERR(sbox_wc_resolve_prop(&b, "A", "prop-1",
+ svn_wc_conflict_choose_mine_conflict));
+ SVN_ERR(sbox_wc_resolve_prop(&b, "A", "prop-2",
+ svn_wc_conflict_choose_theirs_conflict));
+ SVN_ERR(sbox_wc_resolve_prop(&b, "A", "prop-3",
+ svn_wc_conflict_choose_merged));
+
+ SVN_ERR(svn_wc__db_read_conflict(&conflict, NULL, NULL,
+ b.wc_ctx->db, A_abspath,
+ pool, pool));
+
+ /* We have tree conflicts... */
+ SVN_TEST_ASSERT(conflict != NULL);
+
+ SVN_ERR(svn_wc__conflict_read_prop_conflict(&marker_abspath,
+ NULL, NULL, NULL,
+ &conflicted_props,
+ b.wc_ctx->db, A_abspath,
+ conflict,
+ pool, pool));
+
+ SVN_TEST_ASSERT(conflicted_props != NULL);
+ SVN_TEST_ASSERT(apr_hash_count(conflicted_props) == 4);
+
+ SVN_ERR(svn_wc__db_read_props(&props, b.wc_ctx->db, A_abspath,
+ pool, pool));
+
+ value = svn_prop_get_value(props, "prop-1");
+ SVN_TEST_STRING_ASSERT(value, "mod");
+ value = svn_prop_get_value(props, "prop-2");
+ SVN_TEST_STRING_ASSERT(value, "r1");
+ value = svn_prop_get_value(props, "prop-3");
+ SVN_TEST_STRING_ASSERT(value, "mod");
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_binary_file_conflict(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_test__sandbox_t sbox;
+ const apr_array_header_t *conflicts;
+ svn_wc_conflict_description2_t *desc;
+
+ SVN_ERR(svn_test__sandbox_create(&sbox, "test_binary_file_conflict", opts, pool));
+
+ /* Create and add a binary file. */
+ SVN_ERR(sbox_file_write(&sbox, "binary-file", "\xff\xff"));
+ SVN_ERR(sbox_wc_add(&sbox, "binary-file"));
+ SVN_ERR(sbox_wc_propset(&sbox, SVN_PROP_MIME_TYPE,
+ "application/octet-stream", "binary-file"));
+ SVN_ERR(sbox_wc_commit(&sbox, "binary-file")); /* r1 */
+
+ /* Make a change to the binary file. */
+ SVN_ERR(sbox_file_write(&sbox, "binary-file", "\xfc\xfc\xfc\xfc\xfc\xfc"));
+ SVN_ERR(sbox_wc_commit(&sbox, "binary-file")); /* r2 */
+
+ /* Update back to r1, make a conflicting change to binary file. */
+ SVN_ERR(sbox_wc_update(&sbox, "binary-file", 1));
+ SVN_ERR(sbox_file_write(&sbox, "binary-file", "\xfd\xfd\xfd\xfd"));
+
+ /* Update to HEAD and ensure the conflict is marked as binary. */
+ SVN_ERR(sbox_wc_update(&sbox, "binary-file", 2));
+ SVN_ERR(svn_wc__read_conflicts(&conflicts, NULL, sbox.wc_ctx->db,
+ sbox_wc_path(&sbox, "binary-file"),
+ FALSE /* create_tempfiles */,
+ FALSE /* only_tree_conflict */,
+ pool, pool));
+ SVN_TEST_ASSERT(conflicts->nelts == 1);
+ desc = APR_ARRAY_IDX(conflicts, 0, svn_wc_conflict_description2_t *);
+ SVN_TEST_ASSERT(desc->is_binary);
+
+ return SVN_NO_ERROR;
+}
+
+
/* The test table. */
-struct svn_test_descriptor_t test_funcs[] =
+static int max_threads = 1;
+
+static struct svn_test_descriptor_t test_funcs[] =
{
SVN_TEST_NULL,
SVN_TEST_PASS2(test_deserialize_tree_conflict,
@@ -826,6 +971,11 @@ struct svn_test_descriptor_t test_funcs[] =
"read and write a tree conflict"),
SVN_TEST_OPTS_PASS(test_prop_conflicts,
"test prop conflicts"),
+ SVN_TEST_OPTS_PASS(test_prop_conflict_resolving,
+ "test property conflict resolving"),
+ SVN_TEST_OPTS_PASS(test_binary_file_conflict,
+ "test binary file conflict"),
SVN_TEST_NULL
};
+SVN_TEST_MAIN
diff --git a/subversion/tests/libsvn_wc/db-test.c b/subversion/tests/libsvn_wc/db-test.c
index 45e9c4d..76ec893 100644
--- a/subversion/tests/libsvn_wc/db-test.c
+++ b/subversion/tests/libsvn_wc/db-test.c
@@ -88,248 +88,205 @@ static const char * const TESTING_DATA = (
"insert into wcroot values (1, null); "
"insert into pristine values ('$sha1$" SHA1_1 "', NULL, 15, 1, '$md5 $" MD5_1 "'); "
+);
- /* ### The file_externals column in NODES is temporary, and will be
- ### removed. However, to keep the tests passing, we need to add it
- ### to the following insert statements. *Be sure to remove it*. */
+#define NOT_MOVED FALSE, NULL
+#define NO_COPY_FROM 0, NULL, SVN_INVALID_REVNUM
+static const svn_test__nodes_data_t nodes_init_data[] = {
/* load the base nodes into the nodes table */
- "insert into nodes values ("
- " 1, '', 0, null, 1, '', 1, 'normal',"
- " null, null, 'dir', '()', 'infinity', null, null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'A', 0, '', 1, 'A', 1, 'normal',"
- " null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " 10, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'B', 0, '', 1, 'B', null, 'excluded',"
- " null, null, 'symlink', null, null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'C', 0, '', 1, 'C', null, 'server-excluded',"
- " null, null, 'unknown', null, null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'D', 0, '', 1, 'D', null, 'not-present',"
- " null, null, 'unknown', null, null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'E', 0, '', 1, 'E', null, 'incomplete',"
- " null, null, 'unknown', null, null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'F', 0, '', 1, 'F', 1, 'normal',"
- " null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " 15, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'G', 0, '', 2, 'G-alt', 1, 'normal',"
- " null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 2, " TIME_2s ", '" AUTHOR_2 "',"
- " 15, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'H', 0, '', 1, 'H', 1, 'normal',"
- " null, null, 'symlink', '()', null, null, 'H-target', 1, " TIME_1s ", '" AUTHOR_1 "',"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'I', 0, '', 1, 'I', 1, 'normal',"
- " null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J', 0, '', 1, 'J', 1, 'normal',"
- " null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-e', 0, 'J', 1, 'J/J-e', 1, 'normal',"
- " null, 'other/place', 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-e/J-e-a', 0, 'J/J-e', 1, 'J/J-e/J-e-a', 1, 'normal',"
- " null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " 15, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-e/J-e-b', 0, 'J/J-e', 1, 'J/J-e/J-e-b', 1, 'normal',"
- " null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-e/J-e-b/Jeba', 0, 'J/J-e/J-e-b', 1, 'J/J-e/J-e-b/Jeba', 1, 'normal',"
- " null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " 15, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-f', 0, 'J', 1, 'J/J-f', 1, 'normal',"
- " null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-f/J-f-a', 0, 'J/J-f', 1, 'J/J-f/J-f-a', 1, 'normal',"
- " null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'K', 0, '', 1, 'K', 1, 'normal',"
- " null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'K/K-a', 0, 'K', 1, 'K/K-a', 1, 'normal',"
- " null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " 15, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'K/K-b', 0, 'K', 1, 'K/K-b', 1, 'normal',"
- " null, 'moved/away', 'file', '()', null, '$sha1$" SHA1_1 "', null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " 15, null, null, null, null);"
- ""
- /* Load data into NODES table;
- ### op_depths have not been calculated by me yet;
- the value 1 is just 'good enough' to make the nodes WORKING nodes. */
- "insert into nodes values ("
- " 1, 'I', 1, '', 2, 'some/dir', 2, 'normal',"
- " null, null, 'dir', '()', 'immediates', null, null, 2, " TIME_2s ", '" AUTHOR_2 "',"
- " null, null, null, null, null);"
-
- /* I'm not sure what the working J is supposed to represent. It
- replaces the base J, but is it a copy or not? It has no
- copyfrom, but nodes like J/J-e appear to be deleted which
- implies they are children of a copied J. */
- "insert into nodes values ("
- " 1, 'J', 1, '', null, null, null, 'normal',"
- " null, null, 'dir', '()', 'immediates', null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-a', 1, 'J', null, null, null, 'normal',"
- " null, null, 'file', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-b', 2, 'J', 2, 'some/dir', 2, 'normal',"
- " null, null, 'dir', '()', 'infinity', null, null, 2, " TIME_2s ", '" AUTHOR_2 "',"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-b/J-b-a', 3, 'J/J-b', 2, 'another/dir', 2, 'normal',"
- " null, null, 'dir', '()', 'infinity', null, null, 2, " TIME_2s ", '" AUTHOR_2 "',"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-b/J-b-b', 2, 'J/J-b', null, null, 2, 'normal',"
- " null, null, 'file', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-c', 1, 'J', null, null, null, 'normal',"
- " null, null, 'dir', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-c/J-c-a', 1, 'J/J-c', null, null, null, 'normal',"
- " null, null, 'dir', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-c', 2, 'J', null, null, null, 'base-deleted',"
- " null, null, 'dir', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-c/J-c-a', 2, 'J/J-c', null, null, null, 'base-deleted',"
- " null, null, 'dir', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-d', 2, 'J', 2, 'moved/file', 2, 'normal',"
- " 1, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 2, " TIME_2s ", '" AUTHOR_2 "',"
- " 10, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'moved/file', 0, 'moved', 2, 'moved/file', 2, 'normal',"
- " null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 2, " TIME_2s ", '" AUTHOR_2 "',"
- " 10, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'moved/file', 2, 'moved', 2, 'moved/file', 2, 'base-deleted',"
- " null, 'J/J-d', 'file', '()', null, null, null, null, null, null,"
- " 10, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-e', 1, 'J', null, null, null, 'normal',"
- " null, null, 'dir', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-e/J-e-a', 1, 'J/J-e', null, null, null, 'normal',"
- " null, null, 'file', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-e/J-e-b', 1, 'J/J-e', null, null, null, 'normal',"
- " null, null, 'dir', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-e', 2, 'J', null, null, null, 'base-deleted',"
- " null, null, 'dir', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-e/J-e-a', 2, 'J/J-e', null, null, null, 'base-deleted',"
- " null, null, 'file', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-e/J-e-b', 2, 'J/J-e', null, null, null, 'base-deleted',"
- " null, null, 'dir', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-e/J-e-b/Jeba', 1, 'J/J-e/J-e-b', null, null, null, 'base-deleted',"
- " null, null, 'file', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-f', 1, 'J', null, null, null, 'normal',"
- " null, null, 'dir', '()', 'immediates', null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-f/J-f-a', 1, 'J/J-f', null, null, null, 'base-deleted',"
- " null, null, 'dir', '()', 'immediates', null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'K', 1, '', null, null, null, 'base-deleted',"
- " null, null, 'dir', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'K/K-a', 1, 'K', null, null, null, 'base-deleted',"
- " null, null, 'file', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'K/K-b', 1, 'K', null, null, null, 'base-deleted',"
- " null, null, 'file', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'L', 1, '', null, null, null, 'normal',"
- " null, null, 'dir', '()', 'immediates', null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'L/L-a', 1, 'L', null, null, null, 'normal',"
- " null, null, 'dir', '()', 'immediates', null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'L/L-a/L-a-a', 1, 'L/L-a', null, null, null, 'normal',"
- " null, null, 'dir', '()', 'immediates', null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'L/L-a', 2, 'L', null, null, null, 'base-deleted',"
- " null, null, 'dir', '()', 'immediates', null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'L/L-a/L-a-a', 2, 'L/L-a', null, null, null, 'base-deleted',"
- " null, null, 'dir', '()', 'immediates', null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'other/place', 2, 'other', null, null, null, 'normal',"
- " 1, null, 'dir', '()', 'immediates', null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'other/place/J-e-a', 2, 'other/place', null, null, null, 'normal',"
- " null, null, 'dir', '()', 'immediates', null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'other/place/J-e-b', 2, 'other/place', null, null, null, 'normal',"
- " null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'other/place/J-e-b/Jeba', 0, 'other/place/J-e-b', null, null, null, 'normal',"
- " null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " 15, null, null, null, null);"
- "insert into actual_node values ("
- " 1, 'I', '', null, null, null, null, null, 'changelist', null, "
- " null, null, null, null, null);"
- "insert into actual_node values ("
- " 1, 'F', '', null, null, null, null, null, null, null, "
- " '" F_TC_DATA "', null, null, null, null);"
- "insert into actual_node values ("
- " 1, 'G', '', null, null, null, null, null, null, null, "
- " '" G_TC_DATA "', null, null, null, null);"
- );
+ { 0, "", "normal", 1, "", 1, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1 },
+ { 0, "A", "normal", 1, "A", 1, NOT_MOVED,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 1, TIME_1a, AUTHOR_1,
+ FALSE, NULL, 10, 10 },
+
+ { 0, "B", "excluded", 1, "B", SVN_INVALID_REVNUM, NOT_MOVED,
+ svn_node_symlink},
+
+ { 0, "C", "server-excluded", 1, "C", 0, NOT_MOVED,
+ svn_node_unknown},
+
+ { 0, "D", "not-present", 1, "D", 0, NOT_MOVED,
+ svn_node_unknown},
+
+ { 0, "E", "incomplete", 1, "E", 1, NOT_MOVED,
+ svn_node_unknown},
+
+ { 0, "F", "normal", 1, "F", 1, NOT_MOVED,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 2, TIME_2a, AUTHOR_2},
+
+ { 0, "G", "normal", 2, "G-alt", 1, NOT_MOVED,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 2, TIME_2a, AUTHOR_2 },
+
+ { 0, "H", "normal", 1, "H", 1, NOT_MOVED,
+ svn_node_symlink, "()", NULL, NULL, "H-target", 1, TIME_1a, AUTHOR_1 },
+
+ { 0, "I", "normal", 1, "I", 1, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1 },
+
+ { 0, "J", "normal", 1, "J", 1, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1 },
+
+ { 0, "J/J-e", "normal", 1, "J/J-e", 1, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1 },
+
+ { 0, "J/J-e/J-e-a", "normal", 1, "J/J-e/J-e-a", 1, NOT_MOVED,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 1, TIME_1a, AUTHOR_1 },
+
+ { 0, "J/J-e/J-e-b", "normal", 1, "J/J-e/J-e-b", 1, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1 },
+
+ { 0, "J/J-e/J-e-b/Jeba", "normal", 1, "J/J-e/J-e-b/Jeba", 1, NOT_MOVED,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 1, TIME_1a, AUTHOR_1 },
+
+ { 0, "J/J-f", "normal", 1, "J/J-f", 1, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1 },
+
+ { 0, "J/J-f/J-f-a", "normal", 1, "J/J-f/J-f-a", 1, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1 },
+
+ { 0, "J", "normal", 1, "J", 1, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1 },
+
+ { 0, "K", "normal", 1, "K", 1, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1 },
+
+ { 0, "K/K-a", "normal", 2, "K/K-a", 1, NOT_MOVED,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 2, TIME_2a, AUTHOR_2,
+ FALSE, NULL, 15, 14},
+
+ { 0, "K/K-b", "normal", 2, "K/K-b", 1, NOT_MOVED,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 2, TIME_2a, AUTHOR_2,
+ FALSE, NULL, 15, 14},
+
+ /* Load data into the working layers of NODES */
+
+ { 1, "I", "normal", 2, "some/dir", 2, NOT_MOVED,
+ svn_node_dir, "()", "immediates", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+ /* J was originally a local addition, but its descendants are replaced,
+ so let's turn J in a copy */
+ { 1, "J", "normal", 2, "q", 2, NOT_MOVED,
+ svn_node_dir, "()", "immediates", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+ { 1, "J/J-a", "normal", 2, "q/J-a", 2, NOT_MOVED,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 2, TIME_2a, AUTHOR_2 },
+
+ { 1, "J/J-b", "normal", 2, "q/J-b", 2, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+ { 3, "J/J-b/J-b-a", "normal", 2, "another/dir", 2, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+ { 1, "J/J-b/J-b-b", "normal", 2, "q/J-b/J-b-b", 2, NOT_MOVED,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 2, TIME_2a, AUTHOR_2 },
+
+ { 1, "J/J-c", "normal", 2, "q/J-c", 2, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+ { 1, "J/J-c/J-c-a", "normal", 2, "q/J-c/J-c-a", 2, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+ { 2, "J/J-c", "base-deleted", NO_COPY_FROM, NOT_MOVED,
+ svn_node_dir},
+
+ { 2, "J/J-c/J-c-a", "base-deleted", NO_COPY_FROM, NOT_MOVED,
+ svn_node_dir},
+
+ { 2, "J/J-d", "normal", 2, "moved/file", 2, TRUE, NULL,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 2, TIME_2a, AUTHOR_2 },
+
+ { 0, "moved", "normal", 2, "moved", 2, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1 },
+
+ { 0, "moved/file", "normal", 2, "moved/file", 2, NOT_MOVED,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 2, TIME_2a, AUTHOR_2 },
+
+ { 2, "moved/file", "base-deleted", NO_COPY_FROM, FALSE, "J/J-d",
+ svn_node_file},
+
+ { 1, "J/J-e", "normal", 2, "q/J-e", 2, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+ { 1, "J/J-e/J-e-a", "normal", 2, "q/J-e/J-e-a", 2, NOT_MOVED,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 2, TIME_2a, AUTHOR_2 },
+
+ { 1, "J/J-e/J-e-b", "normal", 2, "q/J-e/J-e-b", 2, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+ { 2, "J/J-e", "base-deleted", NO_COPY_FROM, FALSE, "other/place",
+ svn_node_dir},
+
+ { 2, "J/J-e/J-e-a", "base-deleted", NO_COPY_FROM, NOT_MOVED,
+ svn_node_file},
+
+ { 2, "J/J-e/J-e-b", "base-deleted", NO_COPY_FROM, NOT_MOVED,
+ svn_node_dir},
+
+ { 1, "J/J-e/J-e-b/Jeba", "base-deleted", NO_COPY_FROM, NOT_MOVED,
+ svn_node_file},
+
+ { 1, "J/J-f", "normal", 2, "q/J-f", 2, NOT_MOVED,
+ svn_node_dir, "()", "immediates", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+ { 1, "J/J-f/J-f-a", "base-deleted", NO_COPY_FROM, NOT_MOVED,
+ svn_node_dir},
+
+ { 1, "K", "base-deleted", NO_COPY_FROM, NOT_MOVED,
+ svn_node_dir},
+
+ { 1, "K/K-a", "base-deleted", NO_COPY_FROM, NOT_MOVED,
+ svn_node_file},
+
+ { 1, "K/K-b", "base-deleted", NO_COPY_FROM, FALSE, "moved/away",
+ svn_node_file},
+
+ { 1, "L", "normal", 2, "from", 2, NOT_MOVED,
+ svn_node_dir, "()", "immediates", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+ { 1, "L/L-a", "normal", 2, "from/L-a", 2, NOT_MOVED,
+ svn_node_dir, "()", "immediates", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+ { 1, "L/L-a/L-a-a", "normal", 2, "from/L-a/L-a-a", 2, NOT_MOVED,
+ svn_node_dir, "()", "immediates", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+ { 2, "L/L-a", "base-deleted", NO_COPY_FROM, NOT_MOVED,
+ svn_node_dir},
+
+ { 2, "L/L-a/L-a-a", "base-deleted", NO_COPY_FROM, NOT_MOVED,
+ svn_node_dir},
+
+ { 0, "other", "normal", 2, "other", 2, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+ { 2, "other/place", "normal", 2, "q/J-e", 2, TRUE, NULL,
+ svn_node_dir, "()", "immediates", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+ { 2, "other/place/J-e-a", "normal", 2, "q/J-e/J-e-a", 2, TRUE, NULL,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 2, TIME_2a, AUTHOR_2 },
+
+ { 2, "other/place/J-e-b", "normal", 2, "q/J-e/J-e-b", 2, TRUE, NULL,
+ svn_node_dir, "()", "infinity", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+ { 2, "other/place/J-e-b/Jeba", "normal", 2, "q/J-e/J-e-b/Jeba", 2, TRUE, NULL,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 1, TIME_1a, AUTHOR_1 },
+
+ /*** NEW ****/
+ { 2, "moved/away", "normal", 2, "K/K-b", 1, TRUE, NULL,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 2, TIME_2a, AUTHOR_2,
+ FALSE, NULL, 15, 14},
+ { 0 }
+};
+
+static const svn_test__actual_data_t actual_init_data[] = {
+ { "A", NULL, "changelist", NULL },
+ { "F", NULL, NULL, F_TC_DATA },
+ { "G", NULL, NULL, F_TC_DATA },
+
+ { 0 }
+};
static svn_error_t *
create_open(svn_wc__db_t **db,
@@ -338,10 +295,16 @@ create_open(svn_wc__db_t **db,
apr_pool_t *pool)
{
SVN_ERR(svn_dirent_get_absolute(local_abspath,
- svn_dirent_join("fake-wc", subdir, pool),
+ svn_dirent_join(
+ svn_test_data_path("db-test", pool),
+ subdir, pool),
pool));
+
+ SVN_ERR(svn_io_remove_dir2(*local_abspath, TRUE, NULL, NULL, pool));
+
SVN_ERR(svn_wc__db_open(db, NULL, FALSE, TRUE, pool, pool));
- SVN_ERR(svn_test__create_fake_wc(*local_abspath, TESTING_DATA, pool, pool));
+ SVN_ERR(svn_test__create_fake_wc(*local_abspath, TESTING_DATA,
+ nodes_init_data, actual_init_data, pool));
svn_test_add_dir_cleanup(*local_abspath);
@@ -361,18 +324,17 @@ set_prop(apr_hash_t *props, const char *name, const char *value,
}
-static svn_boolean_t
+static svn_error_t *
validate_abspath(const char *wcroot_abspath,
const char *expected_relpath,
const char *actual_abspath,
apr_pool_t *scratch_pool)
{
- if (actual_abspath == NULL)
- return FALSE;
- return strcmp(svn_dirent_join(wcroot_abspath,
+ SVN_TEST_STRING_ASSERT(actual_abspath,
+ svn_dirent_join(wcroot_abspath,
expected_relpath,
- scratch_pool),
- actual_abspath) == 0;
+ scratch_pool));
+ return SVN_NO_ERROR;
}
@@ -660,7 +622,7 @@ test_inserting_nodes(apr_pool_t *pool)
props,
1, TIME_1a, AUTHOR_1,
children, svn_depth_infinity,
- NULL, NULL, FALSE, NULL, NULL, NULL,
+ NULL, FALSE, NULL, NULL, NULL, NULL,
pool));
/* Replace an incomplete node with a file node. */
@@ -771,11 +733,17 @@ test_children(apr_pool_t *pool)
SVN_ERR(svn_wc__db_base_get_children(&children,
db, local_abspath,
pool, pool));
- SVN_TEST_ASSERT(children->nelts == 11);
+ SVN_TEST_ASSERT(children->nelts == 13);
for (i = children->nelts; i--; )
{
const char *name = APR_ARRAY_IDX(children, i, const char *);
+ if (strcmp(name, "moved") == 0
+ || strcmp(name, "other") == 0)
+ {
+ continue;
+ }
+
SVN_TEST_ASSERT(strlen(name) == 1);
/* ### check the actual values */
}
@@ -783,11 +751,17 @@ test_children(apr_pool_t *pool)
SVN_ERR(svn_wc__db_read_children(&children,
db, local_abspath,
pool, pool));
- SVN_TEST_ASSERT(children->nelts == 12);
+ SVN_TEST_ASSERT(children->nelts == 14);
for (i = children->nelts; i--; )
{
const char *name = APR_ARRAY_IDX(children, i, const char *);
+ if (strcmp(name, "moved") == 0
+ || strcmp(name, "other") == 0)
+ {
+ continue;
+ }
+
SVN_TEST_ASSERT(strlen(name) == 1);
/* ### check the actual values */
}
@@ -858,7 +832,7 @@ test_working_info(apr_pool_t *pool)
SVN_TEST_ASSERT(checksum == NULL);
SVN_TEST_ASSERT(recorded_size == SVN_INVALID_FILESIZE);
SVN_TEST_ASSERT(target == NULL);
- SVN_TEST_STRING_ASSERT(changelist, "changelist");
+ SVN_TEST_STRING_ASSERT(changelist, NULL);
SVN_TEST_STRING_ASSERT(original_repos_relpath, "some/dir");
SVN_TEST_STRING_ASSERT(original_root_url, ROOT_TWO);
SVN_TEST_STRING_ASSERT(original_uuid, UUID_TWO);
@@ -876,8 +850,31 @@ test_working_info(apr_pool_t *pool)
/* ### we need a hojillion more tests in here. I just want to get this
### round checked in, so I'm skipping more tests at this point. */
-
-
+ SVN_ERR(svn_wc__db_read_info(
+ &status, &kind, &revision,
+ &repos_relpath, &repos_root_url, &repos_uuid,
+ &changed_rev, &changed_date, &changed_author,
+ &depth, &checksum, &target, &original_repos_relpath,
+ &original_root_url, &original_uuid, &original_revnum,
+ &lock, &recorded_size, &recorded_time, &changelist,
+ &conflicted, &op_root, &had_props, &props_mod,
+ &have_base, &have_more_work, &have_work,
+ db, svn_dirent_join(local_abspath, "A", pool),
+ pool, pool));
+ SVN_TEST_ASSERT(status == svn_wc__db_status_normal);
+ SVN_TEST_ASSERT(kind == svn_node_file);
+ SVN_TEST_STRING_ASSERT(changelist, "changelist");
+ SVN_TEST_ASSERT(revision == 1);
+ SVN_TEST_STRING_ASSERT(repos_relpath, "A");
+ SVN_TEST_STRING_ASSERT(repos_root_url, "http://example.com/one");
+ SVN_TEST_STRING_ASSERT(repos_uuid, "uuid1");
+ SVN_TEST_ASSERT(changed_rev == 1);
+ SVN_TEST_ASSERT(changed_date == TIME_1a);
+ SVN_TEST_STRING_ASSERT(changed_author, AUTHOR_1);
+ SVN_TEST_ASSERT(depth == svn_depth_unknown);
+ SVN_TEST_ASSERT(checksum != NULL);
+ SVN_TEST_ASSERT(recorded_size == 10);
+ SVN_TEST_ASSERT(target == NULL);
return SVN_NO_ERROR;
}
@@ -901,9 +898,16 @@ test_pdh(apr_pool_t *pool)
NULL, NULL,
pool));
+ SVN_ERR(svn_wc__db_base_add_directory(
+ db, svn_dirent_join(local_abspath, "sub2", pool),
+ local_abspath, "sub2", ROOT_ONE, UUID_ONE, 1,
+ apr_hash_make(pool), 1, 1, "me", NULL,
+ svn_depth_infinity, NULL, FALSE, NULL, NULL,
+ NULL, NULL, pool));
+
SVN_ERR(svn_wc__db_base_add_excluded_node(
- db, svn_dirent_join(local_abspath, "sub/A", pool),
- "sub/A", ROOT_ONE, UUID_ONE, 1,
+ db, svn_dirent_join(local_abspath, "sub2/A", pool),
+ "sub2/A", ROOT_ONE, UUID_ONE, 1,
svn_node_file, svn_wc__db_status_server_excluded,
NULL, NULL,
pool));
@@ -941,17 +945,17 @@ test_scan_addition(apr_pool_t *pool)
&original_revision,
db, svn_dirent_join(local_abspath, "J", pool),
pool, pool));
- SVN_TEST_ASSERT(status == svn_wc__db_status_added);
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "J", op_root_abspath, pool));
+ SVN_TEST_ASSERT(status == svn_wc__db_status_copied);
+ SVN_ERR(validate_abspath(local_abspath, "J", op_root_abspath, pool));
SVN_TEST_STRING_ASSERT(repos_relpath, "J");
SVN_TEST_STRING_ASSERT(repos_root_url, ROOT_ONE);
SVN_TEST_STRING_ASSERT(repos_uuid, UUID_ONE);
- SVN_TEST_ASSERT(original_repos_relpath == NULL);
- SVN_TEST_ASSERT(original_root_url == NULL);
- SVN_TEST_ASSERT(original_uuid == NULL);
- SVN_TEST_ASSERT(original_revision == SVN_INVALID_REVNUM);
+ SVN_TEST_STRING_ASSERT(original_repos_relpath, "q");
+ SVN_TEST_STRING_ASSERT(original_root_url, ROOT_TWO);
+ SVN_TEST_STRING_ASSERT(original_uuid, UUID_TWO);
+ SVN_TEST_ASSERT(original_revision == 2);
- /* Simple addition of a file (affects how scan-up is started). */
+ /* Simple copy (affects how scan-up is started). */
SVN_ERR(svn_wc__db_scan_addition(
&status, &op_root_abspath,
&repos_relpath, &repos_root_url, &repos_uuid,
@@ -959,15 +963,15 @@ test_scan_addition(apr_pool_t *pool)
&original_revision,
db, svn_dirent_join(local_abspath, "J/J-a", pool),
pool, pool));
- SVN_TEST_ASSERT(status == svn_wc__db_status_added);
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "J", op_root_abspath, pool));
+ SVN_TEST_ASSERT(status == svn_wc__db_status_copied);
+ SVN_ERR(validate_abspath(local_abspath, "J", op_root_abspath, pool));
SVN_TEST_STRING_ASSERT(repos_relpath, "J/J-a");
SVN_TEST_STRING_ASSERT(repos_root_url, ROOT_ONE);
SVN_TEST_STRING_ASSERT(repos_uuid, UUID_ONE);
- SVN_TEST_ASSERT(original_repos_relpath == NULL);
- SVN_TEST_ASSERT(original_root_url == NULL);
- SVN_TEST_ASSERT(original_uuid == NULL);
- SVN_TEST_ASSERT(original_revision == SVN_INVALID_REVNUM);
+ SVN_TEST_STRING_ASSERT(original_repos_relpath, "q");
+ SVN_TEST_STRING_ASSERT(original_root_url, ROOT_TWO);
+ SVN_TEST_STRING_ASSERT(original_uuid, UUID_TWO);
+ SVN_TEST_ASSERT(original_revision == 2);
/* Node was moved here. */
SVN_ERR(svn_wc__db_scan_addition(
@@ -985,15 +989,15 @@ test_scan_addition(apr_pool_t *pool)
db, svn_dirent_join(local_abspath, "J/J-d", pool),
pool, pool));
SVN_TEST_ASSERT(status == svn_wc__db_status_moved_here);
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-d",
+ SVN_ERR(validate_abspath(local_abspath, "J/J-d",
op_root_abspath, pool));
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "moved/file",
+ SVN_ERR(validate_abspath(local_abspath, "moved/file",
moved_from_abspath, pool));
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-d",
+ SVN_ERR(validate_abspath(local_abspath, "J/J-d",
move_op_root_abspath, pool));
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "moved/file",
+ SVN_ERR(validate_abspath(local_abspath, "moved/file",
move_op_root_src, pool));
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "moved/file",
+ SVN_ERR(validate_abspath(local_abspath, "moved/file",
delete_op_root_abspath, pool));
SVN_TEST_STRING_ASSERT(repos_relpath, "J/J-d");
SVN_TEST_STRING_ASSERT(repos_root_url, ROOT_ONE);
@@ -1012,12 +1016,12 @@ test_scan_addition(apr_pool_t *pool)
db, svn_dirent_join(local_abspath, "J/J-b", pool),
pool, pool));
SVN_TEST_ASSERT(status == svn_wc__db_status_copied);
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-b",
+ SVN_ERR(validate_abspath(local_abspath, "J",
op_root_abspath, pool));
SVN_TEST_STRING_ASSERT(repos_relpath, "J/J-b");
SVN_TEST_STRING_ASSERT(repos_root_url, ROOT_ONE);
SVN_TEST_STRING_ASSERT(repos_uuid, UUID_ONE);
- SVN_TEST_STRING_ASSERT(original_repos_relpath, "some/dir");
+ SVN_TEST_STRING_ASSERT(original_repos_relpath, "q");
SVN_TEST_STRING_ASSERT(original_root_url, ROOT_TWO);
SVN_TEST_STRING_ASSERT(original_uuid, UUID_TWO);
SVN_TEST_ASSERT(original_revision == 2);
@@ -1031,7 +1035,7 @@ test_scan_addition(apr_pool_t *pool)
db, svn_dirent_join(local_abspath, "J/J-b/J-b-a", pool),
pool, pool));
SVN_TEST_ASSERT(status == svn_wc__db_status_copied);
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-b/J-b-a",
+ SVN_ERR(validate_abspath(local_abspath, "J/J-b/J-b-a",
op_root_abspath, pool));
SVN_TEST_STRING_ASSERT(repos_relpath, "J/J-b/J-b-a");
SVN_TEST_STRING_ASSERT(repos_root_url, ROOT_ONE);
@@ -1050,12 +1054,12 @@ test_scan_addition(apr_pool_t *pool)
db, svn_dirent_join(local_abspath, "J/J-b/J-b-b", pool),
pool, pool));
SVN_TEST_ASSERT(status == svn_wc__db_status_copied);
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-b",
+ SVN_ERR(validate_abspath(local_abspath, "J",
op_root_abspath, pool));
SVN_TEST_STRING_ASSERT(repos_relpath, "J/J-b/J-b-b");
SVN_TEST_STRING_ASSERT(repos_root_url, ROOT_ONE);
SVN_TEST_STRING_ASSERT(repos_uuid, UUID_ONE);
- SVN_TEST_STRING_ASSERT(original_repos_relpath, "some/dir");
+ SVN_TEST_STRING_ASSERT(original_repos_relpath, "q");
SVN_TEST_STRING_ASSERT(original_root_url, ROOT_TWO);
SVN_TEST_STRING_ASSERT(original_uuid, UUID_TWO);
SVN_TEST_ASSERT(original_revision == 2);
@@ -1084,13 +1088,13 @@ test_scan_deletion(apr_pool_t *pool)
&copy_op_root_abspath,
db, svn_dirent_join(local_abspath, "J/J-e", pool),
pool, pool));
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "J",
+ SVN_ERR(validate_abspath(local_abspath, "J",
base_del_abspath, pool));
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "other/place",
+ SVN_ERR(validate_abspath(local_abspath, "other/place",
moved_to_abspath, pool));
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-e",
+ SVN_ERR(validate_abspath(local_abspath, "J/J-e",
work_del_abspath, pool));
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "other/place",
+ SVN_ERR(validate_abspath(local_abspath, "other/place",
copy_op_root_abspath, pool));
/* Node was moved elsewhere (child of operation root). */
@@ -1101,13 +1105,13 @@ test_scan_deletion(apr_pool_t *pool)
&copy_op_root_abspath,
db, svn_dirent_join(local_abspath, "J/J-e/J-e-a", pool),
pool, pool));
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "J",
+ SVN_ERR(validate_abspath(local_abspath, "J",
base_del_abspath, pool));
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "other/place/J-e-a",
+ SVN_ERR(validate_abspath(local_abspath, "other/place/J-e-a",
moved_to_abspath, pool));
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-e",
+ SVN_ERR(validate_abspath(local_abspath, "J/J-e",
work_del_abspath, pool));
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "other/place",
+ SVN_ERR(validate_abspath(local_abspath, "other/place",
copy_op_root_abspath, pool));
/* Root of delete. Parent is a WORKING node. */
@@ -1119,10 +1123,10 @@ test_scan_deletion(apr_pool_t *pool)
db, svn_dirent_join(local_abspath, "J/J-c", pool),
pool, pool));
/* Implicit delete of "J" (via replacement). */
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "J",
+ SVN_ERR(validate_abspath(local_abspath, "J",
base_del_abspath, pool));
SVN_TEST_ASSERT(moved_to_abspath == NULL);
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-c",
+ SVN_ERR(validate_abspath(local_abspath, "J/J-c",
work_del_abspath, pool));
/* Child of a deleted root. */
@@ -1134,10 +1138,10 @@ test_scan_deletion(apr_pool_t *pool)
db, svn_dirent_join(local_abspath, "J/J-c/J-c-a", pool),
pool, pool));
/* Implicit delete of "J" (via replacement). */
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "J",
+ SVN_ERR(validate_abspath(local_abspath, "J",
base_del_abspath, pool));
SVN_TEST_ASSERT(moved_to_abspath == NULL);
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-c",
+ SVN_ERR(validate_abspath(local_abspath, "J/J-c",
work_del_abspath, pool));
/* Base-deleted tree extending past deleted WORKING subtree. */
@@ -1151,11 +1155,11 @@ test_scan_deletion(apr_pool_t *pool)
/* ### I don't understand this. "J/J-e/J-e-b/Jeba" is a deleted
base node that is not overlayed by the replacement rooted at "J".
Why does base_del_abspath refer to "J-e"? */
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "J",
+ SVN_ERR(validate_abspath(local_abspath, "J",
base_del_abspath, pool));
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "other/place/J-e-b/Jeba",
+ SVN_ERR(validate_abspath(local_abspath, "other/place/J-e-b/Jeba",
moved_to_abspath, pool));
- SVN_TEST_ASSERT(work_del_abspath == NULL);
+ SVN_TEST_STRING_ASSERT(work_del_abspath, NULL);
/* Base-deleted tree extending past added WORKING tree. */
SVN_ERR(svn_wc__db_scan_deletion(
@@ -1166,10 +1170,10 @@ test_scan_deletion(apr_pool_t *pool)
db, svn_dirent_join(local_abspath, "J/J-f/J-f-a", pool),
pool, pool));
/* Implicit delete of "J" (via replacement). */
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "J",
+ SVN_ERR(validate_abspath(local_abspath, "J",
base_del_abspath, pool));
- SVN_TEST_ASSERT(moved_to_abspath == NULL);
- SVN_TEST_ASSERT(work_del_abspath == NULL);
+ SVN_TEST_STRING_ASSERT(moved_to_abspath, NULL);
+ SVN_TEST_STRING_ASSERT(work_del_abspath, NULL);
/* Root of delete. Parent is a BASE node. */
SVN_ERR(svn_wc__db_scan_deletion(
@@ -1179,10 +1183,10 @@ test_scan_deletion(apr_pool_t *pool)
NULL,
db, svn_dirent_join(local_abspath, "K", pool),
pool, pool));
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "K",
+ SVN_ERR(validate_abspath(local_abspath, "K",
base_del_abspath, pool));
- SVN_TEST_ASSERT(moved_to_abspath == NULL);
- SVN_TEST_ASSERT(work_del_abspath == NULL);
+ SVN_TEST_STRING_ASSERT(moved_to_abspath, NULL);
+ SVN_TEST_STRING_ASSERT(work_del_abspath, NULL);
/* Base-deleted tree. Start below root. */
SVN_ERR(svn_wc__db_scan_deletion(
@@ -1192,10 +1196,10 @@ test_scan_deletion(apr_pool_t *pool)
NULL,
db, svn_dirent_join(local_abspath, "K/K-a", pool),
pool, pool));
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "K",
+ SVN_ERR(validate_abspath(local_abspath, "K",
base_del_abspath, pool));
- SVN_TEST_ASSERT(moved_to_abspath == NULL);
- SVN_TEST_ASSERT(work_del_abspath == NULL);
+ SVN_TEST_STRING_ASSERT(moved_to_abspath, NULL);
+ SVN_TEST_STRING_ASSERT(work_del_abspath, NULL);
/* Base-deleted tree via move. */
SVN_ERR(svn_wc__db_scan_deletion(
@@ -1205,13 +1209,13 @@ test_scan_deletion(apr_pool_t *pool)
&copy_op_root_abspath,
db, svn_dirent_join(local_abspath, "K/K-b", pool),
pool, pool));
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "K",
+ SVN_ERR(validate_abspath(local_abspath, "K",
base_del_abspath, pool));
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "moved/away",
+ SVN_ERR(validate_abspath(local_abspath, "moved/away",
moved_to_abspath, pool));
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "moved/away",
+ SVN_ERR(validate_abspath(local_abspath, "moved/away",
copy_op_root_abspath, pool));
- SVN_TEST_ASSERT(work_del_abspath == NULL);
+ SVN_TEST_STRING_ASSERT(work_del_abspath, NULL);
/* Subtree deletion of added tree. Start at child. */
SVN_ERR(svn_wc__db_scan_deletion(
@@ -1221,9 +1225,9 @@ test_scan_deletion(apr_pool_t *pool)
NULL,
db, svn_dirent_join(local_abspath, "L/L-a/L-a-a", pool),
pool, pool));
- SVN_TEST_ASSERT(base_del_abspath == NULL);
- SVN_TEST_ASSERT(moved_to_abspath == NULL);
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "L/L-a",
+ SVN_TEST_STRING_ASSERT(base_del_abspath, NULL);
+ SVN_TEST_STRING_ASSERT(moved_to_abspath, NULL);
+ SVN_ERR(validate_abspath(local_abspath, "L/L-a",
work_del_abspath, pool));
/* Subtree deletion of added tree. Start at root. */
@@ -1234,9 +1238,9 @@ test_scan_deletion(apr_pool_t *pool)
NULL,
db, svn_dirent_join(local_abspath, "L/L-a", pool),
pool, pool));
- SVN_TEST_ASSERT(base_del_abspath == NULL);
- SVN_TEST_ASSERT(moved_to_abspath == NULL);
- SVN_TEST_ASSERT(validate_abspath(local_abspath, "L/L-a",
+ SVN_TEST_STRING_ASSERT(base_del_abspath, NULL);
+ SVN_TEST_STRING_ASSERT(moved_to_abspath, NULL);
+ SVN_ERR(validate_abspath(local_abspath, "L/L-a",
work_del_abspath, pool));
return SVN_NO_ERROR;
@@ -1269,7 +1273,7 @@ test_global_relocate(apr_pool_t *pool)
SVN_TEST_STRING_ASSERT(repos_root_url, ROOT_ONE);
SVN_TEST_STRING_ASSERT(repos_uuid, UUID_ONE);
- /* Test relocating to a repos not existant in the db */
+ /* Test relocating to a repos not existent in the db */
SVN_ERR(svn_wc__db_global_relocate(db, local_abspath, ROOT_THREE, pool));
SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL,
&repos_relpath, &repos_root_url, &repos_uuid,
@@ -1521,7 +1525,9 @@ test_externals_store(apr_pool_t *pool)
return SVN_NO_ERROR;
}
-struct svn_test_descriptor_t test_funcs[] =
+static int max_threads = 2;
+
+static struct svn_test_descriptor_t test_funcs[] =
{
SVN_TEST_NULL,
SVN_TEST_PASS2(test_getting_info,
@@ -1546,3 +1552,5 @@ struct svn_test_descriptor_t test_funcs[] =
"externals store"),
SVN_TEST_NULL
};
+
+SVN_TEST_MAIN
diff --git a/subversion/tests/libsvn_wc/entries-compat.c b/subversion/tests/libsvn_wc/entries-compat.c
index 34ad425..3470c06 100644
--- a/subversion/tests/libsvn_wc/entries-compat.c
+++ b/subversion/tests/libsvn_wc/entries-compat.c
@@ -87,199 +87,186 @@ static const char * const TESTING_DATA = (
"insert into wcroot values (1, null); "
"insert into pristine values ('$sha1$" SHA1_1 "', NULL, 15, 1, '$md5 $" MD5_1 "'); "
+ );
- /* ### The file_externals column in NODES is temporary, and will be
- ### removed. However, to keep the tests passing, we need to add it
- ### to the following insert statements. *Be sure to remove it*. */
+#define NOT_MOVED FALSE, NULL
+#define NO_COPY_FROM 0, NULL, SVN_INVALID_REVNUM
+static const svn_test__nodes_data_t nodes[] =
+{
/* load the base nodes into the nodes table */
- "insert into nodes values ("
- " 1, '', 0, null, 1, '', 1, 'normal',"
- " null, null, 'dir', '()', 'infinity', null, null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'A', 0, '', 1, 'A', 1, 'normal',"
- " null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " 10, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'B', 0, '', 1, 'B', null, 'excluded',"
- " null, null, 'symlink', null, null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'C', 0, '', 1, 'C', null, 'server-excluded',"
- " null, null, 'unknown', null, null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'D', 0, '', 1, 'D', null, 'not-present',"
- " null, null, 'unknown', null, null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'E', 0, '', 1, 'E', null, 'incomplete',"
- " null, null, 'unknown', null, null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'F', 0, '', 1, 'F', 1, 'normal',"
- " null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " 15, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'G', 0, '', 2, 'G-alt', 1, 'normal',"
- " null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 2, " TIME_2s ", '" AUTHOR_2 "',"
- " 15, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'H', 0, '', 1, 'H', 1, 'normal',"
- " null, null, 'symlink', '()', null, null, 'H-target', 1, " TIME_1s ", '" AUTHOR_1 "',"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'I', 0, '', 1, 'I', 1, 'normal',"
- " null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J', 0, '', 1, 'J', 1, 'normal',"
- " null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-e', 0, 'J', 1, 'J/J-e', 1, 'normal',"
- " null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-e/J-e-a', 0, 'J/J-e', 1, 'J/J-e/J-e-a', 1, 'normal',"
- " null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " 15, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-e/J-e-b', 0, 'J/J-e', 1, 'J/J-e/J-e-b', 1, 'normal',"
- " null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-e/J-e-b/Jeba', 0, 'J/J-e/J-e-b', 1, 'J/J-e/J-e-b/Jeba', 1, 'normal',"
- " null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " 15, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-f', 0, 'J', 1, 'J/J-f', 1, 'normal',"
- " null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-f/J-f-a', 0, 'J/J-f', 1, 'J/J-f/J-f-a', 1, 'normal',"
- " null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'K', 0, '', 1, 'K', 1, 'normal',"
- " null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'K/K-a', 0, 'K', 1, 'K/K-a', 1, 'normal',"
- " null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " 15, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'K/K-b', 0, 'K', 1, 'K/K-b', 1, 'normal',"
- " null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 1, " TIME_1s ", '" AUTHOR_1 "',"
- " 15, null, null, null, null);"
- ""
+ { 0, "", "normal", 1, "", 1, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1},
+
+ { 0, "A", "normal", 1, "A", 1, NOT_MOVED,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 1, TIME_1a, AUTHOR_1},
+
+ { 0, "B", "excluded", 1, "B", 1, NOT_MOVED,
+ svn_node_symlink},
+
+ { 0, "C", "server-excluded",1, "C", 0, NOT_MOVED,
+ svn_node_unknown},
+
+ { 0, "D", "not-present", 1, "D", 0, NOT_MOVED,
+ svn_node_unknown},
+
+ { 0, "E", "incomplete", 1, "E", SVN_INVALID_REVNUM, NOT_MOVED,
+ svn_node_unknown},
+
+ { 0, "F", "normal", 1, "G-alt", 1, NOT_MOVED,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 1, TIME_1a, AUTHOR_1},
+
+ { 0, "G", "normal", 1, "G-alt", 1, NOT_MOVED,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 1, TIME_1a, AUTHOR_1},
+
+ { 0, "H", "normal", 1, "I", 1, NOT_MOVED,
+ svn_node_symlink, NULL, NULL, NULL, "H-target", 1, TIME_1a, AUTHOR_1},
+
+ { 0, "I", "normal", 1, "I", 1, NOT_MOVED,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 1, TIME_1a, AUTHOR_1},
+
+ { 0, "J", "normal", 1, "J", 1, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1},
+
+ { 0, "J/J-c", "normal", 1, "J/J-c", 1, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1},
+
+ { 0, "J/J-c/J-c-a", "not-present", 1, "J/J-c/J-c-a", 1, NOT_MOVED,
+ svn_node_dir},
+
+ { 0, "J/J-e", "normal", 1, "J/J-e", 1, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1},
+
+ { 0, "J/J-e/J-e-a", "normal", 1, "J/J-e/J-e-a", 1, NOT_MOVED,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 1, TIME_1a, AUTHOR_1},
+
+ { 0, "J/J-e/J-e-b", "normal", 1, "J/J-e/J-e-b", 1, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1},
+
+ { 0, "J/J-e/J-e-b/Jeba", "normal", 1, "J/J-e/J-e-b/Jeba", 1, NOT_MOVED,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 1, TIME_1a, AUTHOR_1},
+
+ { 0, "J/J-f", "normal", 1, "J/J-f", 1, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1},
+
+ { 0, "J/J-f/J-f-a", "normal", 1, "J/J-f/J-f-a", 1, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1},
+
+ { 0, "K", "normal", 1, "K", 1, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1},
+
+ { 0, "K/K-a", "normal", 1, "K/K-a", 1, NOT_MOVED,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 1, TIME_1a, AUTHOR_1},
+
+ { 0, "K/K-b", "normal", 1, "K/K-b", 1, NOT_MOVED,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 1, TIME_1a, AUTHOR_1},
+
+ { 0, "L", "normal", 1, "switched", 1, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1},
+
+ { 0, "L/L-a", "normal", 1, "switched/L-a", 1, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1},
+
+ { 0, "L/L-a/L-a-a", "normal", 1, "switched/L-a/L-a-a", 1, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1},
+
/* Load data into NODES table;
### op_depths have not been calculated by me yet;
the value 1 is just 'good enough' to make the nodes WORKING nodes. */
- "insert into nodes values ("
- " 1, 'I', 1, '', 2, 'some/dir', 2, 'normal',"
- " null, null, 'dir', '()', 'immediates', null, null, 2, " TIME_2s ", '" AUTHOR_2 "',"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J', 1, '', null, null, null, 'normal',"
- " null, null, 'dir', '()', 'immediates', null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-a', 1, 'J', null, null, null, 'normal',"
- " null, null, 'file', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-b', 1, 'J', 2, 'some/dir', 2, 'normal',"
- " null, null, 'dir', '()', 'infinity', null, null, 2, " TIME_2s ", '" AUTHOR_2 "',"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-b/J-b-a', 1, 'J/J-b', 2, 'another/dir', 2, 'normal',"
- " null, null, 'dir', '()', 'infinity', null, null, 2, " TIME_2s ", '" AUTHOR_2 "',"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-b/J-b-b', 1, 'J/J-b', null, null, null, 'normal',"
- " null, null, 'file', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-c', 1, 'J', null, null, null, 'not-present',"
- " null, null, 'dir', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-c/J-c-a', 1, 'J/J-c', null, null, null, 'not-present',"
- " null, null, 'dir', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-d', 1, 'J', 2, 'moved/file', 2, 'normal',"
- " 1, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 2, " TIME_2s ", '" AUTHOR_2 "',"
- " 10, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-e', 1, 'J', null, null, null, 'not-present',"
- " null, 'other/place', 'dir', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-e/J-e-a', 1, 'J/J-e', null, null, null, 'not-present',"
- " null, null, 'file', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-e/J-e-b', 1, 'J/J-e', null, null, null, 'not-present',"
- " null, null, 'dir', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-e/J-e-b/Jeba', 1, 'J/J-e/J-e-b', null, null, null, 'base-deleted',"
- " null, null, 'file', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-f', 1, 'J', null, null, null, 'normal',"
- " null, null, 'dir', '()', 'immediates', null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'J/J-f/J-f-a', 1, 'J/J-f', null, null, null, 'base-deleted',"
- " null, null, 'dir', '()', 'immediates', null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'K', 1, '', null, null, null, 'base-deleted',"
- " null, null, 'dir', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'K/K-a', 1, 'K', null, null, null, 'base-deleted',"
- " null, null, 'file', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'K/K-b', 1, 'K', null, null, null, 'base-deleted',"
- " null, 'moved/away', 'file', '()', null, null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'L', 1, '', null, null, null, 'normal',"
- " null, null, 'dir', '()', 'immediates', null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'L/L-a', 1, 'L', null, null, null, 'not-present',"
- " null, null, 'dir', '()', 'immediates', null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'L/L-a/L-a-a', 1, 'L/L-a', null, null, null, 'not-present',"
- " null, null, 'dir', '()', 'immediates', null, null, null, null, null,"
- " null, null, null, null, null);"
- "insert into actual_node values ("
- " 1, 'I', '', null, null, null, null, null, 'changelist', null, "
- " null, null, null, null, null);"
- "insert into actual_node values ("
- " 1, 'F', '', null, null, null, null, null, null, null, "
- " '" F_TC_DATA "', null, null, null, null);"
- "insert into actual_node values ("
- " 1, 'G', '', null, null, null, null, null, null, null, "
- " '" G_TC_DATA "', null, null, null, null);"
- " "
- "insert into nodes values ("
- " 1, 'M', 0, '', 1, 'M', 1, 'normal', "
- " null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 "', "
- " null, null, null, null, null);"
- "insert into nodes values ("
- " 1, 'M/M-a', 0, 'M', 1, 'M/M-a', 1, 'not-present', "
- " null, null, 'file', '()', null, null, null, 1, null, null, "
- " null, null, null, null, null);"
- );
+
+ { 1, "I", "normal", 2, "some/file", 2, NOT_MOVED,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 2, TIME_2a, AUTHOR_2},
+
+ { 1, "J", "normal", NO_COPY_FROM, NOT_MOVED,
+ svn_node_dir, NULL, "immediates"},
+
+ { 2, "J/J-a", "normal", NO_COPY_FROM, NOT_MOVED,
+ svn_node_file},
+
+ { 2, "J/J-b", "normal", 2, "some/dir", 2, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 2, TIME_2a, AUTHOR_2},
+
+ { 3, "J/J-b/J-b-a", "normal", 2, "another/dir", 2, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 2, TIME_2a, AUTHOR_2},
+
+ { 3, "J/J-b/J-b-b", "normal", NO_COPY_FROM, NOT_MOVED,
+ svn_node_file},
+
+ /* This triggers a validation warning: bad delete */
+ { 1, "J/J-c", "base-deleted", NO_COPY_FROM, NOT_MOVED,
+ svn_node_dir},
+
+ { 1, "J/J-d", "normal", 2, "moved/file", 2, NOT_MOVED,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 2, TIME_2a, AUTHOR_2},
+
+ { 1, "J/J-e", "base-deleted", NO_COPY_FROM, FALSE, "other/place",
+ svn_node_dir},
+
+ { 1, "J/J-e/J-e-a", "base-deleted", NO_COPY_FROM, NOT_MOVED,
+ svn_node_file},
+
+ { 1, "J/J-e/J-e-b", "base-deleted", NO_COPY_FROM, NOT_MOVED,
+ svn_node_dir},
+
+ { 1, "J/J-e/J-e-b/Jeba", "base-deleted", NO_COPY_FROM, NOT_MOVED,
+ svn_node_file},
+
+ { 1, "J/J-f", "base-deleted", NO_COPY_FROM, NOT_MOVED,
+ svn_node_dir},
+
+ { 2, "J/J-f", "normal", NO_COPY_FROM, NOT_MOVED,
+ svn_node_dir, NULL, "immediates"},
+
+ { 1, "J/J-f/J-f-a", "base-deleted", NO_COPY_FROM, NOT_MOVED,
+ svn_node_dir},
+
+ { 1, "K", "base-deleted", NO_COPY_FROM, NOT_MOVED,
+ svn_node_dir},
+
+ { 1, "K/K-a", "base-deleted", NO_COPY_FROM, NOT_MOVED,
+ svn_node_file},
+
+ { 1, "K/K-b", "base-deleted", NO_COPY_FROM, FALSE, "moved/away",
+ svn_node_file},
+
+ { 1, "L", "normal", NO_COPY_FROM, NOT_MOVED,
+ svn_node_dir, NULL, "immediates"},
+
+ { 1, "L/L-a", "base-deleted", NO_COPY_FROM, NOT_MOVED,
+ svn_node_dir},
+
+ { 1, "L/L-a/L-a-a", "base-deleted", NO_COPY_FROM, NOT_MOVED,
+ svn_node_dir},
+
+ { 1, "M", "normal", 1, "M", 1, NOT_MOVED,
+ svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1},
+
+ { 1, "M/M-a", "not-present", 1, "M/M-a", 1, NOT_MOVED,
+ svn_node_file},
+
+ /**** Move target of K/K-b ****/
+ { 1, "moved", "normal", NO_COPY_FROM, NOT_MOVED,
+ svn_node_dir, NULL, "infinity" },
+ { 2, "moved/away", "normal", 1, "??", 1, TRUE, NULL,
+ svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 1, TIME_1a, AUTHOR_1},
+
+ /**** Move target of J/J-e ****/
+ { 1, "other", "normal", NO_COPY_FROM, NOT_MOVED,
+ svn_node_dir, NULL, "empty"},
+
+ { 2, "other/place", "normal", 1, "??", 1, TRUE, NULL,
+ svn_node_dir, "()", "infinity"},
+
+ { 0 },
+};
+
+static const svn_test__actual_data_t actuals[] =
+{
+ { "I", NULL, "changelist", NULL },
+ { "F", NULL, NULL, NULL /* TC-DATA */ },
+ { "G", NULL, NULL, NULL /* TC-DATA */ },
+ { 0 },
+};
static const char * const M_TESTING_DATA = (
@@ -310,10 +297,8 @@ create_fake_wc(const char *subdir, apr_pool_t *pool)
SVN_ERR(svn_io_remove_dir2(root, TRUE, NULL, NULL, pool));
SVN_ERR(svn_dirent_get_absolute(&wc_abspath, root, pool));
- SVN_ERR(svn_test__create_fake_wc(wc_abspath, TESTING_DATA, pool, pool));
-
- wc_abspath = svn_dirent_join(wc_abspath, "M", pool);
- SVN_ERR(svn_test__create_fake_wc(wc_abspath, M_TESTING_DATA, pool, pool));
+ SVN_ERR(svn_test__create_fake_wc(wc_abspath, TESTING_DATA, nodes, actuals,
+ pool));
return SVN_NO_ERROR;
}
@@ -368,8 +353,8 @@ test_entries_alloc(apr_pool_t *pool)
SVN_ERR(svn_wc_entries_read(&entries, adm_access, TRUE /* show_hidden */,
pool));
- /* The wcroot has 12 BASE children + 1 WORKING child + "this dir". */
- SVN_TEST_ASSERT(apr_hash_count(entries) == 14);
+ /* The wcroot has 12 BASE children + 3 WORKING child + "this dir". */
+ SVN_TEST_ASSERT(apr_hash_count(entries) == 16);
/* The "D" entry in the entries hash should be what we get from the
svn_wc_entry() entrypoint. */
@@ -377,7 +362,7 @@ test_entries_alloc(apr_pool_t *pool)
"fake-wc",
WC_NAME,
"D",
- NULL);
+ SVN_VA_NULL);
SVN_ERR(svn_wc_entry(&entry, local_relpath, adm_access, TRUE, pool));
SVN_TEST_ASSERT(entry == apr_hash_get(entries, "D", APR_HASH_KEY_STRING));
@@ -400,6 +385,7 @@ test_stubs(apr_pool_t *pool)
const svn_wc_entry_t *stub_entry;
const svn_wc_entry_t *entry;
const svn_wc_entry_t *test_entry;
+ const char *M_dir;
apr_hash_t *entries;
#undef WC_NAME
@@ -407,13 +393,16 @@ test_stubs(apr_pool_t *pool)
SVN_ERR(create_open(&db, &local_abspath, WC_NAME, pool));
+ M_dir = svn_dirent_join(local_abspath, "M", pool);
+ SVN_ERR(svn_test__create_fake_wc(M_dir, M_TESTING_DATA, NULL, NULL, pool));
+
/* The "M" entry is a subdir. Let's ensure we can reach its stub,
and the actual contents. */
local_relpath = svn_dirent_join_many(pool,
"fake-wc",
WC_NAME,
"M",
- NULL);
+ SVN_VA_NULL);
SVN_ERR(svn_wc_adm_open3(&adm_access,
NULL /* associated */,
@@ -428,6 +417,8 @@ test_stubs(apr_pool_t *pool)
subdir baton with ADM_ACCESS. */
SVN_ERR(svn_wc_entry(&stub_entry, local_relpath, adm_access, TRUE, pool));
SVN_TEST_STRING_ASSERT(stub_entry->name, "M");
+ /* Schedule add in parent-wc. Schedule normal in obstructing working copy */
+ SVN_TEST_ASSERT(stub_entry->schedule == svn_wc_schedule_add);
SVN_ERR(svn_wc_adm_open3(&subdir_access,
adm_access,
@@ -441,6 +432,7 @@ test_stubs(apr_pool_t *pool)
/* Ensure we get the real entry. */
SVN_ERR(svn_wc_entry(&entry, local_relpath, subdir_access, TRUE, pool));
SVN_TEST_STRING_ASSERT(entry->name, "");
+ SVN_TEST_ASSERT(entry->schedule == svn_wc_schedule_normal);
/* Ensure that we get the SAME entry, even using the parent baton. */
SVN_ERR(svn_wc_entry(&test_entry, local_relpath, adm_access, TRUE, pool));
@@ -638,7 +630,9 @@ test_access_baton_like_locking(apr_pool_t *pool)
}
-struct svn_test_descriptor_t test_funcs[] =
+static int max_threads = -1;
+
+static struct svn_test_descriptor_t test_funcs[] =
{
SVN_TEST_NULL,
SVN_TEST_PASS2(test_entries_alloc,
@@ -649,3 +643,5 @@ struct svn_test_descriptor_t test_funcs[] =
"access baton like locks must work with wc-ng"),
SVN_TEST_NULL
};
+
+SVN_TEST_MAIN
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
diff --git a/subversion/tests/libsvn_wc/pristine-store-test.c b/subversion/tests/libsvn_wc/pristine-store-test.c
index 6df96fc..d9ed077 100644
--- a/subversion/tests/libsvn_wc/pristine-store-test.c
+++ b/subversion/tests/libsvn_wc/pristine-store-test.c
@@ -70,40 +70,6 @@ create_repos_and_wc(const char **wc_abspath,
return SVN_NO_ERROR;
}
-
-/* Write the string DATA into a new unique-named file in the directory
- * DIR_ABSPATH. Set *FILE_ABSPATH to its absolute path and *CHECKSUM_SHA1
- * and *CHECKSUM_MD5 to its SHA-1 and MD-5 checksums.
- *
- * CHECKSUM_SHA1 and/or CHECKSUM_MD5 may be null if not required. */
-static svn_error_t *
-write_and_checksum_temp_file(const char **file_abspath,
- svn_checksum_t **sha1_checksum,
- svn_checksum_t **md5_checksum,
- const char *data,
- const char *dir_abspath,
- apr_pool_t *pool)
-{
- apr_file_t *file;
-
- SVN_ERR(svn_io_open_unique_file3(&file, file_abspath,
- dir_abspath, svn_io_file_del_none,
- pool, pool));
-
- SVN_ERR(svn_io_file_write_full(file, data, strlen(data), NULL, pool));
- SVN_ERR(svn_io_file_close(file, pool));
-
- if (sha1_checksum)
- SVN_ERR(svn_io_file_checksum2(sha1_checksum, *file_abspath,
- svn_checksum_sha1, pool));
- if (md5_checksum)
- SVN_ERR(svn_io_file_checksum2(md5_checksum, *file_abspath,
- svn_checksum_md5, pool));
-
- return SVN_NO_ERROR;
-}
-
-
/* Exercise the pristine text API with a simple write and read. */
static svn_error_t *
pristine_write_read(const svn_test_opts_t *opts,
@@ -112,7 +78,9 @@ pristine_write_read(const svn_test_opts_t *opts,
svn_wc__db_t *db;
const char *wc_abspath;
- const char *pristine_tmp_abspath;
+ svn_wc__db_install_data_t *install_data;
+ svn_stream_t *pristine_stream;
+ apr_size_t sz;
const char data[] = "Blah";
svn_string_t *data_string = svn_string_create(data, pool);
@@ -123,15 +91,15 @@ pristine_write_read(const svn_test_opts_t *opts,
/* Write DATA into a new temporary pristine file, set PRISTINE_TMP_ABSPATH
* to its path and set DATA_SHA1 and DATA_MD5 to its checksums. */
- {
- const char *pristine_tmp_dir;
+ SVN_ERR(svn_wc__db_pristine_prepare_install(&pristine_stream,
+ &install_data,
+ &data_sha1, &data_md5,
+ db, wc_abspath,
+ pool, pool));
- SVN_ERR(svn_wc__db_pristine_get_tempdir(&pristine_tmp_dir, db,
- wc_abspath, pool, pool));
- SVN_ERR(write_and_checksum_temp_file(&pristine_tmp_abspath,
- &data_sha1, &data_md5,
- data, pristine_tmp_dir, pool));
- }
+ sz = strlen(data);
+ SVN_ERR(svn_stream_write(pristine_stream, data, &sz));
+ SVN_ERR(svn_stream_close(pristine_stream));
/* Ensure it's not already in the store. */
{
@@ -143,7 +111,7 @@ pristine_write_read(const svn_test_opts_t *opts,
}
/* Install the new pristine file, referenced by its checksum. */
- SVN_ERR(svn_wc__db_pristine_install(db, pristine_tmp_abspath,
+ SVN_ERR(svn_wc__db_pristine_install(install_data,
data_sha1, data_md5, pool));
/* Ensure it is now found in the store. */
@@ -209,8 +177,10 @@ pristine_delete_while_open(const svn_test_opts_t *opts,
{
svn_wc__db_t *db;
const char *wc_abspath;
- const char *pristine_tmp_dir;
+ svn_wc__db_install_data_t *install_data;
+ svn_stream_t *pristine_stream;
svn_stream_t *contents;
+ apr_size_t sz;
const char data[] = "Blah";
svn_checksum_t *data_sha1, *data_md5;
@@ -218,17 +188,17 @@ pristine_delete_while_open(const svn_test_opts_t *opts,
SVN_ERR(create_repos_and_wc(&wc_abspath, &db,
"pristine_delete_while_open", opts, pool));
- SVN_ERR(svn_wc__db_pristine_get_tempdir(&pristine_tmp_dir, db,
- wc_abspath, pool, pool));
+ SVN_ERR(svn_wc__db_pristine_prepare_install(&pristine_stream,
+ &install_data,
+ &data_sha1, &data_md5,
+ db, wc_abspath,
+ pool, pool));
- /* Install a pristine text. */
- {
- const char *path;
-
- SVN_ERR(write_and_checksum_temp_file(&path, &data_sha1, &data_md5,
- data, pristine_tmp_dir, pool));
- SVN_ERR(svn_wc__db_pristine_install(db, path, data_sha1, data_md5, pool));
- }
+ sz = strlen(data);
+ SVN_ERR(svn_stream_write(pristine_stream, data, &sz));
+ SVN_ERR(svn_stream_close(pristine_stream));
+ SVN_ERR(svn_wc__db_pristine_install(install_data,
+ data_sha1, data_md5, pool));
/* Open it for reading */
SVN_ERR(svn_wc__db_pristine_read(&contents, NULL, db, wc_abspath, data_sha1,
@@ -242,7 +212,7 @@ pristine_delete_while_open(const svn_test_opts_t *opts,
char buffer[4];
apr_size_t len = 4;
- SVN_ERR(svn_stream_read(contents, buffer, &len));
+ SVN_ERR(svn_stream_read_full(contents, buffer, &len));
SVN_TEST_ASSERT(len == 4);
SVN_TEST_ASSERT(memcmp(buffer, data, len) == 0);
}
@@ -276,7 +246,6 @@ reject_mismatching_text(const svn_test_opts_t *opts,
#ifdef SVN_DEBUG /* The pristine store only checks this in debug mode. */
svn_wc__db_t *db;
const char *wc_abspath;
- const char *pristine_tmp_dir;
const char data[] = "Blah";
svn_checksum_t *data_sha1, *data_md5;
@@ -286,28 +255,47 @@ reject_mismatching_text(const svn_test_opts_t *opts,
SVN_ERR(create_repos_and_wc(&wc_abspath, &db,
"reject_mismatching_text", opts, pool));
- SVN_ERR(svn_wc__db_pristine_get_tempdir(&pristine_tmp_dir, db,
- wc_abspath, pool, pool));
-
/* Install a pristine text. */
{
- const char *path;
-
- SVN_ERR(write_and_checksum_temp_file(&path, &data_sha1, &data_md5,
- data, pristine_tmp_dir, pool));
- SVN_ERR(svn_wc__db_pristine_install(db, path, data_sha1, data_md5, pool));
+ svn_wc__db_install_data_t *install_data;
+ svn_stream_t *pristine_stream;
+ apr_size_t sz;
+
+ SVN_ERR(svn_wc__db_pristine_prepare_install(&pristine_stream,
+ &install_data,
+ &data_sha1, &data_md5,
+ db, wc_abspath,
+ pool, pool));
+
+ sz = strlen(data);
+ SVN_ERR(svn_stream_write(pristine_stream, data, &sz));
+ SVN_ERR(svn_stream_close(pristine_stream));
+
+ SVN_ERR(svn_wc__db_pristine_install(install_data,
+ data_sha1, data_md5,
+ pool));
}
/* Try to install the wrong pristine text against the same checksum.
* Should fail. */
{
- svn_error_t *err;
- const char *path;
-
- SVN_ERR(write_and_checksum_temp_file(&path, NULL, NULL,
- data2, pristine_tmp_dir, pool));
- err = svn_wc__db_pristine_install(db, path, data_sha1, data_md5, pool);
- SVN_TEST_ASSERT_ERROR(err, SVN_ERR_WC_CORRUPT_TEXT_BASE);
+ svn_wc__db_install_data_t *install_data;
+ svn_stream_t *pristine_stream;
+ apr_size_t sz;
+
+ SVN_ERR(svn_wc__db_pristine_prepare_install(&pristine_stream,
+ &install_data,
+ &data_sha1, &data_md5,
+ db, wc_abspath,
+ pool, pool));
+
+ sz = strlen(data2);
+ SVN_ERR(svn_stream_write(pristine_stream, data2, &sz));
+ SVN_ERR(svn_stream_close(pristine_stream));
+
+ SVN_ERR(svn_wc__db_pristine_install(install_data,
+ data_sha1, data_md5,
+ pool));
}
return SVN_NO_ERROR;
@@ -319,7 +307,9 @@ reject_mismatching_text(const svn_test_opts_t *opts,
}
-struct svn_test_descriptor_t test_funcs[] =
+static int max_threads = -1;
+
+static struct svn_test_descriptor_t test_funcs[] =
{
SVN_TEST_NULL,
SVN_TEST_OPTS_PASS(pristine_write_read,
@@ -330,3 +320,5 @@ struct svn_test_descriptor_t test_funcs[] =
"reject_mismatching_text"),
SVN_TEST_NULL
};
+
+SVN_TEST_MAIN
diff --git a/subversion/tests/libsvn_wc/utils.c b/subversion/tests/libsvn_wc/utils.c
index 1682b98..bebfc8a 100644
--- a/subversion/tests/libsvn_wc/utils.c
+++ b/subversion/tests/libsvn_wc/utils.c
@@ -22,8 +22,8 @@
#include "svn_error.h"
#include "svn_client.h"
+#include "svn_cmdline.h"
#include "svn_pools.h"
-#include "private/svn_dep_compat.h"
#include "utils.h"
@@ -33,10 +33,26 @@
#include "../../libsvn_wc/wc-queries.h"
#define SVN_WC__I_AM_WC_DB
#include "../../libsvn_wc/wc_db_private.h"
+#include "../../libsvn_wc/token-map.h"
+svn_error_t *
+svn_test__create_client_ctx(svn_client_ctx_t **ctx,
+ svn_test__sandbox_t *sbox,
+ apr_pool_t *result_pool)
+{
+ SVN_ERR(svn_client_create_context2(ctx, NULL, result_pool));
+
+ SVN_ERR(svn_test__init_auth_baton(&(*ctx)->auth_baton,
+ result_pool));
+
+ if (sbox)
+ (*ctx)->wc_ctx = sbox->wc_ctx;
+ return SVN_NO_ERROR;
+}
/* Create an empty repository and WC for the test TEST_NAME. Set *REPOS_URL
- * to the URL of the new repository and *WC_ABSPATH to the root path of the
+ * to the URL of the new repository, *REPOS_DIR to its local path and
+ * *WC_ABSPATH to the root path of the
* new WC.
*
* Create the repository and WC in subdirectories called
@@ -46,6 +62,7 @@
* Register the repo and WC to be cleaned up when the test suite exits. */
static svn_error_t *
create_repos_and_wc(const char **repos_url,
+ const char **repos_dir,
const char **wc_abspath,
const char *test_name,
const svn_test_opts_t *opts,
@@ -66,8 +83,6 @@ create_repos_and_wc(const char **repos_url,
/* Create a repos. Register it for clean-up. Set *REPOS_URL to its path. */
{
- svn_repos_t *repos;
-
/* Use a subpool to create the repository and then destroy the subpool
so the repository's underlying filesystem is closed. If opts->fs_type
is BDB this prevents any attempt to open a second environment handle
@@ -75,8 +90,8 @@ create_repos_and_wc(const char **repos_url,
only a single environment handle to be open per process. */
apr_pool_t *subpool = svn_pool_create(pool);
- SVN_ERR(svn_test__create_repos(&repos, repos_path, opts, subpool));
- SVN_ERR(svn_uri_get_file_url_from_dirent(repos_url, repos_path, pool));
+ SVN_ERR(svn_test__create_repos2(NULL, repos_url, repos_dir, repos_path,
+ opts, pool, subpool));
svn_pool_destroy(subpool);
}
@@ -86,7 +101,7 @@ create_repos_and_wc(const char **repos_url,
svn_client_ctx_t *ctx;
svn_opt_revision_t head_rev = { svn_opt_revision_head, {0} };
- SVN_ERR(svn_client_create_context2(&ctx, NULL, subpool));
+ SVN_ERR(svn_test__create_client_ctx(&ctx, NULL, subpool));
SVN_ERR(svn_dirent_get_absolute(wc_abspath, wc_path, pool));
SVN_ERR(svn_client_checkout3(NULL, *repos_url, *wc_abspath,
&head_rev, &head_rev, svn_depth_infinity,
@@ -102,44 +117,151 @@ create_repos_and_wc(const char **repos_url,
return SVN_NO_ERROR;
}
-
WC_QUERIES_SQL_DECLARE_STATEMENTS(statements);
svn_error_t *
svn_test__create_fake_wc(const char *wc_abspath,
const char *extra_statements,
- apr_pool_t *result_pool,
+ const svn_test__nodes_data_t nodes[],
+ const svn_test__actual_data_t actuals[],
+
apr_pool_t *scratch_pool)
{
const char *dotsvn_abspath = svn_dirent_join(wc_abspath, ".svn",
scratch_pool);
- const char *db_abspath = svn_dirent_join(dotsvn_abspath, "wc.db",
- scratch_pool);
svn_sqlite__db_t *sdb;
const char **my_statements;
int i;
+ svn_sqlite__stmt_t *stmt;
+ const apr_int64_t wc_id = 1;
/* Allocate MY_STATEMENTS in RESULT_POOL because the SDB will continue to
* refer to it over its lifetime. */
- my_statements = apr_palloc(result_pool, 6 * sizeof(const char *));
+ my_statements = apr_palloc(scratch_pool, 7 * sizeof(const char *));
my_statements[0] = statements[STMT_CREATE_SCHEMA];
my_statements[1] = statements[STMT_CREATE_NODES];
my_statements[2] = statements[STMT_CREATE_NODES_TRIGGERS];
my_statements[3] = statements[STMT_CREATE_EXTERNALS];
- my_statements[4] = extra_statements;
- my_statements[5] = NULL;
+ my_statements[4] = statements[STMT_INSTALL_SCHEMA_STATISTICS];
+ my_statements[5] = extra_statements;
+ my_statements[6] = NULL;
/* Create fake-wc/SUBDIR/.svn/ for placing the metadata. */
SVN_ERR(svn_io_make_dir_recursively(dotsvn_abspath, scratch_pool));
-
- svn_error_clear(svn_io_remove_file2(db_abspath, FALSE, scratch_pool));
SVN_ERR(svn_wc__db_util_open_db(&sdb, wc_abspath, "wc.db",
svn_sqlite__mode_rwcreate,
- FALSE /* exclusive */, my_statements,
- result_pool, scratch_pool));
+ FALSE /* exclusive */, 0 /* timeout */,
+ my_statements,
+ scratch_pool, scratch_pool));
for (i = 0; my_statements[i] != NULL; i++)
SVN_ERR(svn_sqlite__exec_statements(sdb, /* my_statements[] */ i));
+ SVN_ERR(svn_sqlite__close(sdb));
+
+ if (!nodes && !actuals)
+ return SVN_NO_ERROR;
+
+ /* Re-open with normal set of statements */
+ SVN_ERR(svn_wc__db_util_open_db(&sdb, wc_abspath, "wc.db",
+ svn_sqlite__mode_readwrite,
+ FALSE /* exclusive */, 0 /* timeout */,
+ statements,
+ scratch_pool, scratch_pool));
+
+ if (nodes)
+ {
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+ STMT_INSERT_NODE));
+
+ for (i = 0; nodes[i].local_relpath; i++)
+ {
+ SVN_ERR(svn_sqlite__bindf(stmt, "isdsnnns",
+ wc_id,
+ nodes[i].local_relpath,
+ nodes[i].op_depth,
+ nodes[i].local_relpath[0]
+ ? svn_relpath_dirname(nodes[i].local_relpath,
+ scratch_pool)
+ : NULL,
+ nodes[i].presence));
+
+ if (nodes[i].repos_relpath)
+ {
+ SVN_ERR(svn_sqlite__bind_int64(stmt, 5, nodes[i].repos_id));
+ SVN_ERR(svn_sqlite__bind_text(stmt, 6, nodes[i].repos_relpath));
+ SVN_ERR(svn_sqlite__bind_revnum(stmt, 7, nodes[i].revision));
+ }
+
+ if (nodes[i].depth)
+ SVN_ERR(svn_sqlite__bind_text(stmt, 9, nodes[i].depth));
+
+ if (nodes[i].kind != 0)
+ SVN_ERR(svn_sqlite__bind_token(stmt, 10, kind_map, nodes[i].kind));
+
+ if (nodes[i].last_author || nodes[i].last_date)
+ {
+ SVN_ERR(svn_sqlite__bind_revnum(stmt, 11, nodes[i].last_revision));
+ SVN_ERR(svn_sqlite__bind_int64(stmt, 12, nodes[i].last_date));
+ SVN_ERR(svn_sqlite__bind_text(stmt, 13, nodes[i].last_author));
+ }
+
+ if (nodes[i].checksum)
+ SVN_ERR(svn_sqlite__bind_text(stmt, 14, nodes[i].checksum));
+
+ if (nodes[i].properties)
+ SVN_ERR(svn_sqlite__bind_text(stmt, 15, nodes[i].properties));
+
+ if (nodes[i].recorded_size || nodes[i].recorded_time)
+ {
+ SVN_ERR(svn_sqlite__bind_int64(stmt, 16, nodes[i].recorded_size));
+ SVN_ERR(svn_sqlite__bind_int64(stmt, 17, nodes[i].recorded_time));
+ }
+
+ /* 18 is DAV cache */
+
+ if (nodes[i].symlink_target)
+ SVN_ERR(svn_sqlite__bind_text(stmt, 19, nodes[i].symlink_target));
+
+ if (nodes[i].file_external)
+ SVN_ERR(svn_sqlite__bind_int(stmt, 20, 1));
+
+ if (nodes[i].moved_to)
+ SVN_ERR(svn_sqlite__bind_text(stmt, 21, nodes[i].moved_to));
+
+ if (nodes[i].moved_here)
+ SVN_ERR(svn_sqlite__bind_int(stmt, 22, 1));
+
+ if (nodes[i].inherited_props)
+ SVN_ERR(svn_sqlite__bind_text(stmt, 23, nodes[i].inherited_props));
+
+ SVN_ERR(svn_sqlite__step_done(stmt));
+ }
+ }
+
+ if (actuals)
+ {
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+ STMT_INSERT_ACTUAL_NODE));
+
+ for (i = 0; actuals[i].local_relpath; i++)
+ {
+ SVN_ERR(svn_sqlite__bindf(stmt, "isssss",
+ wc_id,
+ actuals[i].local_relpath,
+ actuals[i].local_relpath[0]
+ ? svn_relpath_dirname(actuals[i].local_relpath,
+ scratch_pool)
+ : NULL,
+ actuals[i].properties,
+ actuals[i].changelist,
+ actuals[i].conflict_data));
+
+ SVN_ERR(svn_sqlite__step_done(stmt));
+ }
+ }
+
+ SVN_ERR(svn_sqlite__close(sdb));
+
return SVN_NO_ERROR;
}
@@ -151,19 +273,28 @@ svn_test__sandbox_create(svn_test__sandbox_t *sandbox,
apr_pool_t *pool)
{
sandbox->pool = pool;
- SVN_ERR(create_repos_and_wc(&sandbox->repos_url, &sandbox->wc_abspath,
+ SVN_ERR(create_repos_and_wc(&sandbox->repos_url, &sandbox->repos_dir,
+ &sandbox->wc_abspath,
test_name, opts, pool));
SVN_ERR(svn_wc_context_create(&sandbox->wc_ctx, NULL, pool, pool));
return SVN_NO_ERROR;
}
-void
+svn_error_t *
sbox_file_write(svn_test__sandbox_t *b, const char *path, const char *text)
{
- FILE *f = fopen(sbox_wc_path(b, path), "w");
+ apr_file_t *f;
- fputs(text, f);
- fclose(f);
+ SVN_ERR(svn_io_file_open(&f, sbox_wc_path(b, path),
+ (APR_WRITE | APR_CREATE | APR_TRUNCATE),
+ APR_OS_DEFAULT,
+ b->pool));
+
+ SVN_ERR(svn_io_file_write_full(f, text, strlen(text), NULL, b->pool));
+
+ SVN_ERR(svn_io_file_close(f, b->pool));
+
+ return SVN_NO_ERROR;
}
svn_error_t *
@@ -175,7 +306,8 @@ sbox_wc_add(svn_test__sandbox_t *b, const char *path)
parent_abspath = svn_dirent_dirname(path, b->pool);
SVN_ERR(svn_wc__acquire_write_lock(NULL, b->wc_ctx, parent_abspath, FALSE,
b->pool, b->pool));
- SVN_ERR(svn_wc_add_from_disk2(b->wc_ctx, path, NULL /*props*/,
+ SVN_ERR(svn_wc_add_from_disk3(b->wc_ctx, path, NULL /*props*/,
+ FALSE /* skip checks */,
NULL, NULL, b->pool));
SVN_ERR(svn_wc__release_write_lock(b->wc_ctx, parent_abspath, b->pool));
return SVN_NO_ERROR;
@@ -241,8 +373,7 @@ sbox_wc_copy_url(svn_test__sandbox_t *b, const char *from_url,
scratch_pool, 1,
sizeof(svn_client_copy_source_t *));
- SVN_ERR(svn_client_create_context2(&ctx, NULL, scratch_pool));
- ctx->wc_ctx = b->wc_ctx;
+ SVN_ERR(svn_test__create_client_ctx(&ctx, b, scratch_pool));
if (SVN_IS_VALID_REVNUM(revision))
{
@@ -258,8 +389,14 @@ sbox_wc_copy_url(svn_test__sandbox_t *b, const char *from_url,
APR_ARRAY_PUSH(sources, svn_client_copy_source_t *) = src;
- SVN_ERR(svn_client_copy6(sources, sbox_wc_path(b, to_path),
- FALSE, FALSE, FALSE, NULL, NULL, NULL,
+ SVN_ERR(svn_client_copy7(sources, sbox_wc_path(b, to_path),
+ FALSE /* copy_as_child */,
+ FALSE /* make_parents */,
+ FALSE /* ignore_externals */,
+ FALSE /* metadata_only */,
+ FALSE, NULL /* pin_external */,
+ NULL /* revprops */,
+ NULL, NULL, /* commit_callback */
ctx, scratch_pool));
ctx->wc_ctx = NULL;
@@ -283,7 +420,11 @@ sbox_wc_revert(svn_test__sandbox_t *b, const char *path, svn_depth_t depth)
SVN_ERR(svn_wc__acquire_write_lock(&lock_root_abspath, b->wc_ctx,
dir_abspath, FALSE /* lock_anchor */,
b->pool, b->pool));
- SVN_ERR(svn_wc_revert4(b->wc_ctx, abspath, depth, FALSE, NULL,
+ SVN_ERR(svn_wc_revert5(b->wc_ctx, abspath, depth,
+ FALSE /* use_commit_times */,
+ NULL /* changelist_filter */,
+ FALSE /* clear_changelists */,
+ FALSE /* metadata_only */,
NULL, NULL, /* cancel baton + func */
NULL, NULL, /* notify baton + func */
b->pool));
@@ -335,8 +476,7 @@ sbox_wc_commit_ex(svn_test__sandbox_t *b,
apr_pool_t *scratch_pool = svn_pool_create(b->pool);
svn_error_t *err;
- SVN_ERR(svn_client_create_context2(&ctx, NULL, scratch_pool));
- ctx->wc_ctx = b->wc_ctx;
+ SVN_ERR(svn_test__create_client_ctx(&ctx, b, scratch_pool));
/* A successfull commit doesn't close the ra session, but leaves that
to the caller. This leaves the BDB handle open, which might cause
@@ -377,12 +517,19 @@ sbox_wc_update_depth(svn_test__sandbox_t *b,
sizeof(const char *));
svn_opt_revision_t revision;
- revision.kind = svn_opt_revision_number;
- revision.value.number = revnum;
+ if (SVN_IS_VALID_REVNUM(revnum))
+ {
+ revision.kind = svn_opt_revision_number;
+ revision.value.number = revnum;
+ }
+ else
+ {
+ revision.kind = svn_opt_revision_head;
+ }
APR_ARRAY_PUSH(paths, const char *) = sbox_wc_path(b, path);
- SVN_ERR(svn_client_create_context2(&ctx, NULL, b->pool));
- ctx->wc_ctx = b->wc_ctx;
+ SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
+
return svn_client_update4(&result_revs, paths, &revision, depth,
sticky, FALSE, FALSE, FALSE, FALSE,
ctx, b->pool);
@@ -405,9 +552,9 @@ sbox_wc_switch(svn_test__sandbox_t *b,
svn_revnum_t result_rev;
svn_opt_revision_t head_rev = { svn_opt_revision_head, {0} };
- url = apr_pstrcat(b->pool, b->repos_url, url, (char*)NULL);
- SVN_ERR(svn_client_create_context2(&ctx, NULL, b->pool));
- ctx->wc_ctx = b->wc_ctx;
+ url = apr_pstrcat(b->pool, b->repos_url, url, SVN_VA_NULL);
+ SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
+
return svn_client_switch3(&result_rev, sbox_wc_path(b, path), url,
&head_rev, &head_rev, depth,
FALSE /* depth_is_sticky */,
@@ -452,14 +599,43 @@ sbox_wc_resolve(svn_test__sandbox_t *b, const char *path, svn_depth_t depth,
}
svn_error_t *
+sbox_wc_resolve_prop(svn_test__sandbox_t *b, const char *path,
+ const char *propname,
+ svn_wc_conflict_choice_t conflict_choice)
+{
+ const char *lock_abspath;
+ svn_error_t *err;
+
+ SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, b->wc_ctx,
+ sbox_wc_path(b, path),
+ b->pool, b->pool));
+ err = svn_wc__resolve_conflicts(b->wc_ctx, sbox_wc_path(b, path),
+ svn_depth_empty,
+ FALSE,
+ propname,
+ FALSE,
+ conflict_choice,
+ NULL, NULL, /* conflict func */
+ NULL, NULL, /* cancellation */
+ NULL, NULL, /* notification */
+ b->pool);
+
+ err = svn_error_compose_create(err, svn_wc__release_write_lock(b->wc_ctx,
+ lock_abspath,
+ b->pool));
+ return err;
+}
+
+
+svn_error_t *
sbox_wc_move(svn_test__sandbox_t *b, const char *src, const char *dst)
{
svn_client_ctx_t *ctx;
apr_array_header_t *paths = apr_array_make(b->pool, 1,
sizeof(const char *));
- SVN_ERR(svn_client_create_context2(&ctx, NULL, b->pool));
- ctx->wc_ctx = b->wc_ctx;
+ SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
+
APR_ARRAY_PUSH(paths, const char *) = sbox_wc_path(b, src);
return svn_client_move7(paths, sbox_wc_path(b, dst),
FALSE /* move_as_child */,
@@ -482,8 +658,8 @@ sbox_wc_propset(svn_test__sandbox_t *b,
sizeof(const char *));
svn_string_t *pval = value ? svn_string_create(value, b->pool) : NULL;
- SVN_ERR(svn_client_create_context2(&ctx, NULL, b->pool));
- ctx->wc_ctx = b->wc_ctx;
+ SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
+
APR_ARRAY_PUSH(paths, const char *) = sbox_wc_path(b, path);
return svn_client_propset_local(name, pval, paths, svn_depth_empty,
TRUE /* skip_checks */,
@@ -497,8 +673,7 @@ sbox_wc_relocate(svn_test__sandbox_t *b,
apr_pool_t *scratch_pool = b->pool;
svn_client_ctx_t *ctx;
- SVN_ERR(svn_client_create_context2(&ctx, NULL, scratch_pool));
- ctx->wc_ctx = b->wc_ctx;
+ SVN_ERR(svn_test__create_client_ctx(&ctx, b, scratch_pool));
SVN_ERR(svn_client_relocate2(b->wc_abspath, b->repos_url,
new_repos_url, FALSE, ctx,scratch_pool));
@@ -517,7 +692,7 @@ sbox_add_and_commit_greek_tree(svn_test__sandbox_t *b)
{
if (node->contents)
{
- sbox_file_write(b, node->path, node->contents);
+ SVN_ERR(sbox_file_write(b, node->path, node->contents));
SVN_ERR(sbox_wc_add(b, node->path));
}
else
diff --git a/subversion/tests/libsvn_wc/utils.h b/subversion/tests/libsvn_wc/utils.h
index 3004634..260139d 100644
--- a/subversion/tests/libsvn_wc/utils.h
+++ b/subversion/tests/libsvn_wc/utils.h
@@ -25,6 +25,8 @@
#include <apr_pools.h>
#include "svn_error.h"
+#include "svn_client.h"
+
#include "../svn_test.h"
#ifdef __cplusplus
@@ -53,6 +55,8 @@ typedef struct svn_test__sandbox_t
svn_wc_context_t *wc_ctx;
/* The repository URL. */
const char *repos_url;
+ /* Local path to the repository */
+ const char *repos_dir;
/* The absolute local path of the WC root. */
const char *wc_abspath;
/* A pool that can be used for all allocations. */
@@ -83,7 +87,7 @@ svn_test__sandbox_create(svn_test__sandbox_t *sandbox,
(svn_dirent_join((b)->wc_abspath, (path), (b)->pool))
/* Create a file on disk at PATH, with TEXT as its content. */
-void
+svn_error_t *
sbox_file_write(svn_test__sandbox_t *b, const char *path, const char *text);
/* Schedule for addition the single node that exists on disk at PATH,
@@ -162,6 +166,12 @@ sbox_wc_resolve(svn_test__sandbox_t *b, const char *path, svn_depth_t depth,
/* */
svn_error_t *
+sbox_wc_resolve_prop(svn_test__sandbox_t *b, const char *path,
+ const char *propname,
+ svn_wc_conflict_choice_t conflict_choice);
+
+/* */
+svn_error_t *
sbox_wc_move(svn_test__sandbox_t *b, const char *src, const char *dst);
/* Set property NAME to VALUE on PATH. If VALUE=NULL, delete the property. */
@@ -175,6 +185,39 @@ sbox_wc_propset(svn_test__sandbox_t *b,
svn_error_t *
sbox_add_and_commit_greek_tree(svn_test__sandbox_t *b);
+/* Initial data to store in NODES */
+typedef struct svn_test__nodes_data_t
+{
+ int op_depth;
+ const char *local_relpath;
+ const char *presence;
+ int repos_id;
+ const char *repos_relpath;
+ svn_revnum_t revision;
+ svn_boolean_t moved_here;
+ const char *moved_to;
+ svn_node_kind_t kind;
+ const char *properties;
+ const char *depth;
+ const char *checksum;
+ const char *symlink_target;
+ svn_revnum_t last_revision;
+ apr_time_t last_date;
+ const char *last_author;
+ svn_boolean_t file_external;
+ const char *inherited_props;
+ svn_filesize_t recorded_size;
+ apr_time_t recorded_time;
+} svn_test__nodes_data_t;
+
+/* Initial data to store in ACTUAL */
+typedef struct svn_test__actual_data_t
+{
+ const char *local_relpath;
+ const char *properties;
+ const char *changelist;
+ const char *conflict_data;
+} svn_test__actual_data_t;
/* Create a WC directory at WC_ABSPATH containing a fake WC DB, generated by
* executing the SQL statements EXTRA_STATEMENTS in addition to the standard
@@ -182,10 +225,18 @@ sbox_add_and_commit_greek_tree(svn_test__sandbox_t *b);
svn_error_t *
svn_test__create_fake_wc(const char *wc_abspath,
const char *extra_statements,
- apr_pool_t *result_pool,
+ const svn_test__nodes_data_t nodes[],
+ const svn_test__actual_data_t actuals[],
apr_pool_t *scratch_pool);
+/* Create a client context for the specified sandbox */
+svn_error_t *
+svn_test__create_client_ctx(svn_client_ctx_t **ctx,
+ svn_test__sandbox_t *sbox,
+ apr_pool_t *result_pool);
+
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/subversion/tests/libsvn_wc/wc-lock-tester.c b/subversion/tests/libsvn_wc/wc-lock-tester.c
index d72c536..1daee66 100644
--- a/subversion/tests/libsvn_wc/wc-lock-tester.c
+++ b/subversion/tests/libsvn_wc/wc-lock-tester.c
@@ -35,16 +35,19 @@
#include "private/svn_wc_private.h"
#include "../../libsvn_wc/wc.h"
#include "../../libsvn_wc/wc_db.h"
+#include "../../libsvn_wc/workqueue.h"
#include "svn_private_config.h"
#define USAGE_MSG \
- "Usage: %s [-r|-1] DIRNAME\n" \
+ "Usage: %s [-1|-r|-w] DIRNAME\n" \
"\n" \
- "Locks one directory (-1), or a tree recursively (-r)\n"
+ "Locks one directory (-1), or a tree recursively (-r), or locks\n" \
+ "recursively and creates an outstanding work queue item (-w)\n"
static svn_error_t *
obtain_lock(const char *path, svn_boolean_t recursive,
+ svn_boolean_t populate_work_queue,
apr_pool_t *scratch_pool)
{
const char *local_abspath;
@@ -52,9 +55,7 @@ obtain_lock(const char *path, svn_boolean_t recursive,
SVN_ERR(svn_path_cstring_to_utf8(&path, path, scratch_pool));
SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
-
- SVN_ERR(svn_wc_context_create(&wc_ctx, NULL, scratch_pool,
- scratch_pool));
+ SVN_ERR(svn_wc_context_create(&wc_ctx, NULL, scratch_pool, scratch_pool));
if (recursive)
{
@@ -68,6 +69,19 @@ obtain_lock(const char *path, svn_boolean_t recursive,
scratch_pool));
}
+ if (populate_work_queue)
+ {
+ svn_skel_t *work_item;
+
+ /* Add an arbitrary work item to the work queue for DB, but don't
+ * run the work queue. */
+ SVN_ERR(svn_wc__wq_build_sync_file_flags(&work_item, wc_ctx->db,
+ local_abspath, scratch_pool,
+ scratch_pool));
+ SVN_ERR(svn_wc__db_wq_add(wc_ctx->db, local_abspath, work_item,
+ scratch_pool));
+ }
+
SVN_ERR(svn_cmdline_printf(scratch_pool, "Lock on '%s' obtained, and we "
"are not going to release it.\n",
svn_dirent_local_style(local_abspath,
@@ -83,9 +97,11 @@ main(int argc, const char *argv[])
int exit_code = EXIT_SUCCESS;
svn_error_t *err;
svn_boolean_t recursive;
+ svn_boolean_t populate_work_queue;
if (argc != 3
- || (strcmp(argv[1], "-1") && apr_strnatcmp(argv[1], "-r")))
+ || (strcmp(argv[1], "-1") && apr_strnatcmp(argv[1], "-r") &&
+ apr_strnatcmp(argv[1], "-w")))
{
fprintf(stderr, USAGE_MSG, argv[0]);
exit(EXIT_FAILURE);
@@ -100,9 +116,10 @@ main(int argc, const char *argv[])
/* set up the global pool */
pool = svn_pool_create(NULL);
- recursive = (strcmp(argv[1], "-1") != 0);
+ populate_work_queue = (strcmp(argv[1], "-w") == 0);
+ recursive = ((strcmp(argv[1], "-1") != 0) || populate_work_queue);
- err = obtain_lock(argv[2], recursive, pool);
+ err = obtain_lock(argv[2], recursive, populate_work_queue, pool);
if (err)
{
diff --git a/subversion/tests/libsvn_wc/wc-queries-test.c b/subversion/tests/libsvn_wc/wc-queries-test.c
index 0621720..d63aa57 100644
--- a/subversion/tests/libsvn_wc/wc-queries-test.c
+++ b/subversion/tests/libsvn_wc/wc-queries-test.c
@@ -22,6 +22,7 @@
*/
#include "svn_pools.h"
+#include "svn_hash.h"
#include "svn_ctype.h"
#include "private/svn_dep_compat.h"
@@ -30,22 +31,17 @@
#include "../svn_test.h"
#ifdef SVN_SQLITE_INLINE
-/* Include sqlite3 inline, making all symbols private. */
- #define SQLITE_API static
- #ifdef __APPLE__
- #include <Availability.h>
- #if __MAC_OS_X_VERSION_MIN_REQUIRED < 1060
- /* <libkern/OSAtomic.h> is included on OS X by sqlite3.c, and
- on old systems (Leopard or older), it cannot be compiled
- with -std=c89 because it uses inline. This is a work-around. */
- #define inline __inline__
- #include <libkern/OSAtomic.h>
- #undef inline
- #endif
- #endif
- #include <sqlite3.c>
+/* Import the sqlite3 API vtable from sqlite3wrapper.c */
+# define SQLITE_OMIT_DEPRECATED
+# include <sqlite3ext.h>
+extern const sqlite3_api_routines *const svn_sqlite3__api_funcs;
+extern int (*const svn_sqlite3__api_initialize)(void);
+extern int (*const svn_sqlite3__api_config)(int, ...);
+# define sqlite3_api svn_sqlite3__api_funcs
+# define sqlite3_initialize svn_sqlite3__api_initialize
+# define sqlite3_config svn_sqlite3__api_config
#else
- #include <sqlite3.h>
+# include <sqlite3.h>
#endif
#include "../../libsvn_wc/wc-queries.h"
@@ -56,7 +52,7 @@ WC_QUERIES_SQL_DECLARE_STATEMENT_INFO(wc_query_info);
/* The first query after the normal wc queries */
#define STMT_SCHEMA_FIRST STMT_CREATE_SCHEMA
-#define SQLITE_ERR(x) \
+#define SQLITE_ERR(x) do \
{ \
int sqlite_err__temp = (x); \
if (sqlite_err__temp != SQLITE_OK) \
@@ -101,6 +97,7 @@ static const int slow_statements[] =
/* Full temporary table read */
STMT_INSERT_ACTUAL_EMPTIES,
+ STMT_INSERT_ACTUAL_EMPTIES_FILES,
STMT_SELECT_REVERT_LIST_RECURSIVE,
STMT_SELECT_DELETE_LIST,
STMT_SELECT_UPDATE_MOVE_LIST,
@@ -177,15 +174,15 @@ create_memory_db(sqlite3 **db,
static svn_error_t *
test_sqlite_version(apr_pool_t *scratch_pool)
{
- printf("DBG: Using Sqlite %s\n", sqlite3_version);
+ printf("DBG: Using Sqlite %s\n", sqlite3_libversion());
if (sqlite3_libversion_number() != SQLITE_VERSION_NUMBER)
- printf("DBG: Compiled against Sqlite %s", SQLITE_VERSION);
+ printf("DBG: Compiled against Sqlite %s\n", SQLITE_VERSION);
if (sqlite3_libversion_number() < SQLITE_VERSION_NUMBER)
return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
"Compiled against Sqlite %s (at runtime we have Sqlite %s)",
- SQLITE_VERSION, sqlite3_version);
+ SQLITE_VERSION, sqlite3_libversion());
#if !SQLITE_VERSION_AT_LEAST(3, 7, 9)
return svn_error_create(SVN_ERR_TEST_FAILED, NULL,
@@ -307,14 +304,21 @@ parse_explanation_item(struct explanation_item **parsed_item,
item->search = TRUE; /* Search or scan */
token = apr_strtok(NULL, " ", &last);
- if (!MATCH_TOKEN(token, "TABLE"))
+ if (MATCH_TOKEN(token, "TABLE"))
+ {
+ item->table = apr_strtok(NULL, " ", &last);
+ }
+ else if (MATCH_TOKEN(token, "SUBQUERY"))
+ {
+ item->table = apr_psprintf(result_pool, "SUBQUERY-%s",
+ apr_strtok(NULL, " ", &last));
+ }
+ else
{
printf("DBG: Expected 'TABLE', got '%s' in '%s'\n", token, text);
return SVN_NO_ERROR; /* Nothing to parse */
}
- item->table = apr_strtok(NULL, " ", &last);
-
token = apr_strtok(NULL, " ", &last);
/* Skip alias */
@@ -418,7 +422,7 @@ parse_explanation_item(struct explanation_item **parsed_item,
return SVN_NO_ERROR;
}
- /* Parsing successfull */
+ /* Parsing successful */
}
else if (MATCH_TOKEN(item->operation, "EXECUTE"))
{
@@ -606,7 +610,7 @@ test_query_expectations(apr_pool_t *scratch_pool)
apr_pstrcat(iterpool,
"EXPLAIN QUERY PLAN ",
wc_queries[i],
- NULL),
+ SVN_VA_NULL),
-1, &stmt, &tail);
if (r != SQLITE_OK)
@@ -744,6 +748,105 @@ test_query_expectations(apr_pool_t *scratch_pool)
return warnings;
}
+static svn_error_t *
+test_query_duplicates(apr_pool_t *scratch_pool)
+{
+ sqlite3 *sdb;
+ int i;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+ svn_error_t *warnings = NULL;
+ svn_boolean_t supports_query_info;
+ apr_hash_t *sha_to_query = apr_hash_make(scratch_pool);
+
+ SVN_ERR(create_memory_db(&sdb, scratch_pool));
+
+ SVN_ERR(supported_explain_query_plan(&supports_query_info, sdb,
+ scratch_pool));
+ if (!supports_query_info)
+ {
+ SQLITE_ERR(sqlite3_close(sdb));
+ return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL,
+ "Sqlite doesn't support EXPLAIN QUERY PLAN");
+ }
+
+ for (i = 0; i < STMT_SCHEMA_FIRST; i++)
+ {
+ sqlite3_stmt *stmt;
+ const char *tail;
+ int r;
+ svn_stringbuf_t *result;
+ svn_checksum_t *checksum;
+
+ if (is_schema_statement(i))
+ continue;
+
+ /* Prepare statement to find if it is a single statement. */
+ r = sqlite3_prepare_v2(sdb, wc_queries[i], -1, &stmt, &tail);
+
+ if (r != SQLITE_OK)
+ continue; /* Parse failure is already reported by 'test_parable' */
+
+ SQLITE_ERR(sqlite3_finalize(stmt));
+ if (tail[0] != '\0')
+ continue; /* Multi-queries are currently not testable */
+
+ svn_pool_clear(iterpool);
+
+ r = sqlite3_prepare_v2(sdb,
+ apr_pstrcat(iterpool,
+ "EXPLAIN ",
+ wc_queries[i],
+ SVN_VA_NULL),
+ -1, &stmt, &tail);
+
+ if (r != SQLITE_OK)
+ continue; /* EXPLAIN not enabled or doesn't support this query */
+
+ result = svn_stringbuf_create_empty(iterpool);
+
+ while (SQLITE_ROW == (r = sqlite3_step(stmt)))
+ {
+ int col;
+
+ for (col = 0; col < sqlite3_column_count(stmt); col++)
+ {
+ const char *txt = (const char*)sqlite3_column_text(stmt, col);
+ if (txt)
+ svn_stringbuf_appendcstr(result, txt);
+
+ svn_stringbuf_appendcstr(result, "|");
+ }
+
+ svn_stringbuf_appendcstr(result, "\n");
+ }
+
+ SQLITE_ERR(sqlite3_reset(stmt));
+ SQLITE_ERR(sqlite3_finalize(stmt));
+
+ SVN_ERR(svn_checksum(&checksum, svn_checksum_sha1,
+ result->data, result->len,
+ iterpool));
+
+ {
+ const char *hex = svn_checksum_to_cstring(checksum, scratch_pool);
+ const char *other;
+
+ other = svn_hash_gets(sha_to_query, hex);
+ if (other)
+ {
+ warnings = svn_error_createf(SVN_ERR_TEST_FAILED, warnings,
+ "Query %s has an identical execution plan as %s",
+ wc_query_info[i][0], other);
+ }
+ else
+ svn_hash_sets(sha_to_query, hex, wc_query_info[i][0]);
+ }
+ }
+ SQLITE_ERR(sqlite3_close(sdb)); /* Close the DB if ok; otherwise leaked */
+
+ return warnings;
+}
+
/* Helper to verify a bit of data in the sqlite3 statistics */
static int
parse_stat_data(const char *stat)
@@ -824,6 +927,15 @@ test_schema_statistics(apr_pool_t *scratch_pool)
"VALUES (1, '', '')",
NULL, NULL, NULL));
+ SQLITE_ERR(
+ sqlite3_exec(sdb,
+ "INSERT INTO EXTERNALS (wc_id, local_relpath,"
+ " parent_relpath, repos_id,"
+ " presence, kind, def_local_relpath,"
+ " def_repos_relpath) "
+ "VALUES (1, 'subdir', '', 1, 'normal', 'dir', '', '')",
+ NULL, NULL, NULL));
+
/* These are currently not necessary for query optimization, but it's better
to tell Sqlite how we intend to use this table anyway */
SQLITE_ERR(
@@ -882,7 +994,62 @@ test_schema_statistics(apr_pool_t *scratch_pool)
return SVN_NO_ERROR;
}
-struct svn_test_descriptor_t test_funcs[] =
+/* An SQLite application defined function that allows SQL queries to
+ use "relpath_depth(local_relpath)". */
+static void relpath_depth_sqlite(sqlite3_context* context,
+ int argc,
+ sqlite3_value* values[])
+{
+ SVN_ERR_MALFUNCTION_NO_RETURN(); /* STUB! */
+}
+
+/* Parse all verify/check queries */
+static svn_error_t *
+test_verify_parsable(apr_pool_t *scratch_pool)
+{
+ sqlite3 *sdb;
+ int i;
+
+ SVN_ERR(create_memory_db(&sdb, scratch_pool));
+
+ SQLITE_ERR(sqlite3_create_function(sdb, "relpath_depth", 1, SQLITE_ANY, NULL,
+ relpath_depth_sqlite, NULL, NULL));
+
+ for (i=STMT_VERIFICATION_TRIGGERS; wc_queries[i]; i++)
+ {
+ sqlite3_stmt *stmt;
+ const char *text = wc_queries[i];
+
+ /* Some of our statement texts contain multiple queries. We prepare
+ them all. */
+ while (*text != '\0')
+ {
+ const char *tail;
+ int r = sqlite3_prepare_v2(sdb, text, -1, &stmt, &tail);
+
+ if (r != SQLITE_OK)
+ return svn_error_createf(SVN_ERR_SQLITE_ERROR, NULL,
+ "Preparing %s failed: %s\n%s",
+ wc_query_info[i][0],
+ sqlite3_errmsg(sdb),
+ text);
+
+ SQLITE_ERR(sqlite3_finalize(stmt));
+
+ /* Continue after the current statement */
+ text = tail;
+ }
+ }
+
+ SQLITE_ERR(sqlite3_close(sdb)); /* Close the DB if ok; otherwise leaked */
+
+ return SVN_NO_ERROR;
+}
+
+
+static int max_threads = 1;
+
+static struct svn_test_descriptor_t test_funcs[] =
{
SVN_TEST_NULL,
SVN_TEST_PASS2(test_sqlite_version,
@@ -891,7 +1058,13 @@ struct svn_test_descriptor_t test_funcs[] =
"queries are parsable"),
SVN_TEST_PASS2(test_query_expectations,
"test query expectations"),
+ SVN_TEST_PASS2(test_query_duplicates,
+ "test query duplicates"),
SVN_TEST_PASS2(test_schema_statistics,
"test schema statistics"),
+ SVN_TEST_PASS2(test_verify_parsable,
+ "verify queries are parsable"),
SVN_TEST_NULL
};
+
+SVN_TEST_MAIN
diff --git a/subversion/tests/libsvn_wc/wc-test-queries.h b/subversion/tests/libsvn_wc/wc-test-queries.h
new file mode 100644
index 0000000..4b5060c
--- /dev/null
+++ b/subversion/tests/libsvn_wc/wc-test-queries.h
@@ -0,0 +1,112 @@
+/* This file is automatically generated from wc-test-queries.sql and .dist_sandbox/subversion-1.9.7/subversion/tests/libsvn_wc/token-map.h.
+ * Do not edit this file -- edit the source and rerun gen-make.py */
+
+#define STMT_SELECT_NODES_INFO 0
+#define STMT_0_INFO {"STMT_SELECT_NODES_INFO", NULL}
+#define STMT_0 \
+ "SELECT op_depth, n.presence, n.local_relpath, revision, " \
+ " repos_path, file_external, def_local_relpath, moved_to, moved_here, " \
+ " properties " \
+ "FROM nodes n " \
+ "LEFT OUTER JOIN externals e " \
+ " ON n.wc_id = e.wc_id " \
+ " AND n.local_relpath = e.local_relpath " \
+ "WHERE n.wc_id = ?1 " \
+ " AND (n.local_relpath = ?2 OR (((n.local_relpath) > (CASE (?2) WHEN '' THEN '' ELSE (?2) || '/' END)) AND ((n.local_relpath) < CASE (?2) WHEN '' THEN X'FFFF' ELSE (?2) || '0' END))) " \
+ ""
+
+#define STMT_SELECT_ACTUAL_INFO 1
+#define STMT_1_INFO {"STMT_SELECT_ACTUAL_INFO", NULL}
+#define STMT_1 \
+ "SELECT local_relpath " \
+ "FROM actual_node " \
+ "WHERE wc_id = ?1 " \
+ " AND conflict_data is NOT NULL " \
+ " AND (local_relpath = ?2 OR (((local_relpath) > (CASE (?2) WHEN '' THEN '' ELSE (?2) || '/' END)) AND ((local_relpath) < CASE (?2) WHEN '' THEN X'FFFF' ELSE (?2) || '0' END))) " \
+ ""
+
+#define STMT_DELETE_NODES 2
+#define STMT_2_INFO {"STMT_DELETE_NODES", NULL}
+#define STMT_2 \
+ "DELETE FROM nodes; " \
+ ""
+
+#define STMT_INSERT_NODE 3
+#define STMT_3_INFO {"STMT_INSERT_NODE", NULL}
+#define STMT_3 \
+ "INSERT INTO nodes (local_relpath, op_depth, presence, repos_path, " \
+ " revision, parent_relpath, moved_to, moved_here, " \
+ " properties, wc_id, repos_id, kind, " \
+ " depth) " \
+ " VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, 1, " \
+ " CASE WHEN ?3 != 'base-deleted' THEN 1 END, " \
+ " 'dir', " \
+ " CASE WHEN ?3 in ('normal', 'incomplete') " \
+ " THEN 'infinity' END) " \
+ ""
+
+#define STMT_DELETE_ACTUAL 4
+#define STMT_4_INFO {"STMT_DELETE_ACTUAL", NULL}
+#define STMT_4 \
+ "DELETE FROM actual_node; " \
+ ""
+
+#define STMT_INSERT_ACTUAL 5
+#define STMT_5_INFO {"STMT_INSERT_ACTUAL", NULL}
+#define STMT_5 \
+ "INSERT INTO actual_node (local_relpath, parent_relpath, changelist, wc_id) " \
+ " VALUES (?1, ?2, ?3, 1) " \
+ ""
+
+#define STMT_ENSURE_EMPTY_PRISTINE 6
+#define STMT_6_INFO {"STMT_ENSURE_EMPTY_PRISTINE", NULL}
+#define STMT_6 \
+ "INSERT OR IGNORE INTO pristine (checksum, md5_checksum, size, refcount) " \
+ " VALUES ('$sha1$da39a3ee5e6b4b0d3255bfef95601890afd80709', " \
+ " '$md5 $d41d8cd98f00b204e9800998ecf8427e', " \
+ " 0, 0) " \
+ ""
+
+#define STMT_NODES_SET_FILE 7
+#define STMT_7_INFO {"STMT_NODES_SET_FILE", NULL}
+#define STMT_7 \
+ "UPDATE nodes " \
+ " SET kind = 'file', " \
+ " checksum = '$sha1$da39a3ee5e6b4b0d3255bfef95601890afd80709', " \
+ " depth = NULL " \
+ "WHERE wc_id = 1 and local_relpath = ?1 " \
+ ""
+
+#define STMT_SELECT_ALL_ACTUAL 8
+#define STMT_8_INFO {"STMT_SELECT_ALL_ACTUAL", NULL}
+#define STMT_8 \
+ "SELECT local_relpath FROM actual_node WHERE wc_id = 1 " \
+ ""
+
+#define WC_TEST_QUERIES_SQL_DECLARE_STATEMENTS(varname) \
+ static const char * const varname[] = { \
+ STMT_0, \
+ STMT_1, \
+ STMT_2, \
+ STMT_3, \
+ STMT_4, \
+ STMT_5, \
+ STMT_6, \
+ STMT_7, \
+ STMT_8, \
+ NULL \
+ }
+
+#define WC_TEST_QUERIES_SQL_DECLARE_STATEMENT_INFO(varname) \
+ static const char * const varname[][2] = { \
+ STMT_0_INFO, \
+ STMT_1_INFO, \
+ STMT_2_INFO, \
+ STMT_3_INFO, \
+ STMT_4_INFO, \
+ STMT_5_INFO, \
+ STMT_6_INFO, \
+ STMT_7_INFO, \
+ STMT_8_INFO, \
+ {NULL, NULL} \
+ }
diff --git a/subversion/tests/libsvn_wc/wc-test-queries.sql b/subversion/tests/libsvn_wc/wc-test-queries.sql
new file mode 100644
index 0000000..613819a
--- /dev/null
+++ b/subversion/tests/libsvn_wc/wc-test-queries.sql
@@ -0,0 +1,78 @@
+/* wc-test-queries.sql -- queries used to verify wc metadata from
+ * the C tests.
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+
+-- STMT_SELECT_NODES_INFO
+SELECT op_depth, n.presence, n.local_relpath, revision,
+ repos_path, file_external, def_local_relpath, moved_to, moved_here,
+ properties
+FROM nodes n
+LEFT OUTER JOIN externals e
+ ON n.wc_id = e.wc_id
+ AND n.local_relpath = e.local_relpath
+WHERE n.wc_id = ?1
+ AND (n.local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(n.local_relpath, ?2))
+
+-- STMT_SELECT_ACTUAL_INFO
+SELECT local_relpath
+FROM actual_node
+WHERE wc_id = ?1
+ AND conflict_data is NOT NULL
+ AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
+
+-- STMT_DELETE_NODES
+DELETE FROM nodes;
+
+-- STMT_INSERT_NODE
+INSERT INTO nodes (local_relpath, op_depth, presence, repos_path,
+ revision, parent_relpath, moved_to, moved_here,
+ properties, wc_id, repos_id, kind,
+ depth)
+ VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, 1,
+ CASE WHEN ?3 != 'base-deleted' THEN 1 END,
+ 'dir',
+ CASE WHEN ?3 in ('normal', 'incomplete')
+ THEN 'infinity' END)
+
+-- STMT_DELETE_ACTUAL
+DELETE FROM actual_node;
+
+-- STMT_INSERT_ACTUAL
+INSERT INTO actual_node (local_relpath, parent_relpath, changelist, wc_id)
+ VALUES (?1, ?2, ?3, 1)
+
+-- STMT_ENSURE_EMPTY_PRISTINE
+INSERT OR IGNORE INTO pristine (checksum, md5_checksum, size, refcount)
+ VALUES ('$sha1$da39a3ee5e6b4b0d3255bfef95601890afd80709',
+ '$md5 $d41d8cd98f00b204e9800998ecf8427e',
+ 0, 0)
+
+-- STMT_NODES_SET_FILE
+UPDATE nodes
+ SET kind = 'file',
+ checksum = '$sha1$da39a3ee5e6b4b0d3255bfef95601890afd80709',
+ depth = NULL
+WHERE wc_id = 1 and local_relpath = ?1
+
+-- STMT_SELECT_ALL_ACTUAL
+SELECT local_relpath FROM actual_node WHERE wc_id = 1
+
diff --git a/subversion/tests/libsvn_wc/wc-test.c b/subversion/tests/libsvn_wc/wc-test.c
index 30eb18a..8910cb0 100644
--- a/subversion/tests/libsvn_wc/wc-test.c
+++ b/subversion/tests/libsvn_wc/wc-test.c
@@ -23,6 +23,9 @@
#include <apr_pools.h>
#include <apr_general.h>
+#include <apr_md5.h>
+
+#define SVN_DEPRECATED
#include "svn_types.h"
#include "svn_io.h"
@@ -71,7 +74,7 @@ struct base_origin_t
};
/* Data for testing node_get_base and node_get_origin. */
-struct base_origin_t base_origin_subtests[] =
+static struct base_origin_t base_origin_subtests[] =
{
/* file copied onto nothing */
{ "A/C/copy1", -1, "iota", {"iota", 1} },
@@ -138,7 +141,6 @@ test_node_get_base(const svn_test_opts_t *opts, apr_pool_t *pool)
NULL,
b->wc_ctx, local_abspath,
TRUE /* ignore_enoent */,
- FALSE /* show_hidden */,
b->pool, b->pool));
SVN_TEST_ASSERT(revision == subtest->base_rev);
if (SVN_IS_VALID_REVNUM(subtest->base_rev))
@@ -181,6 +183,7 @@ test_node_get_origin(const svn_test_opts_t *opts, apr_pool_t *pool)
SVN_ERR(svn_wc__node_get_origin(NULL, &revision, &repos_relpath,
&repos_root_url, &repos_uuid, NULL,
+ NULL,
b->wc_ctx, local_abspath, FALSE,
b->pool, b->pool));
SVN_TEST_ASSERT(revision == subtest->origin.rev);
@@ -304,11 +307,139 @@ test_externals_parse_erratic(apr_pool_t *pool)
return SVN_NO_ERROR;
}
+static svn_error_t *
+test_legacy_commit1(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+ svn_wc_adm_access_t *adm_access;
+ const char *lambda;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "legacy_commit1", opts, pool));
+ SVN_ERR(sbox_add_and_commit_greek_tree(&b));
+
+ SVN_ERR(sbox_wc_copy(&b, "A", "A_copied"));
+
+ lambda = sbox_wc_path(&b, "A_copied/B/lambda");
+
+
+ SVN_ERR(svn_io_remove_file2(lambda, FALSE, pool));
+ SVN_ERR(svn_io_copy_file(sbox_wc_path(&b, "iota"), lambda, FALSE, pool));
+ SVN_ERR(svn_wc_adm_open3(&adm_access, NULL, b.wc_abspath, TRUE, -1,
+ NULL, NULL, pool));
+
+ {
+ svn_wc_status2_t *status;
+
+ SVN_ERR(svn_wc_status2(&status, lambda, adm_access, pool));
+
+ SVN_TEST_ASSERT(status != NULL);
+ SVN_TEST_ASSERT(status->text_status == svn_wc_status_modified);
+ SVN_TEST_ASSERT(status->copied == TRUE);
+ }
+
+ /* Simulate a very old style svn ci . -m "QQQ" on the WC root */
+ SVN_ERR(svn_wc_process_committed4(sbox_wc_path(&b, "A_copied"), adm_access,
+ TRUE, 12, "2014-10-01T19:00:50.966679Z",
+ "me", NULL, TRUE, TRUE,
+ NULL, pool));
+
+ {
+ unsigned char digest[APR_MD5_DIGESTSIZE];
+
+ /* Use the fact that iota has the same checksum to ease committing */
+
+ SVN_ERR(svn_io_file_checksum (digest, lambda, pool));
+
+ SVN_ERR(svn_wc_process_committed4(lambda, adm_access,
+ TRUE, 12, "2014-10-01T19:00:50.966679Z",
+ "me", NULL, TRUE, TRUE,
+ digest, pool));
+ }
+
+ {
+ svn_wc_status2_t *status;
+
+ SVN_ERR(svn_wc_status2(&status, lambda, adm_access, pool));
+
+ /* Node is still modified, as we didn't change the text base! */
+ SVN_TEST_ASSERT(status != NULL);
+ SVN_TEST_ASSERT(status->text_status == svn_wc_status_normal);
+ SVN_TEST_ASSERT(status->copied == FALSE);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_legacy_commit2(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+ svn_wc_adm_access_t *adm_access;
+ const char *lambda;
+ svn_wc_committed_queue_t *queue;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "legacy_commit2", opts, pool));
+ SVN_ERR(sbox_add_and_commit_greek_tree(&b));
+
+ SVN_ERR(sbox_wc_copy(&b, "A", "A_copied"));
+
+ lambda = sbox_wc_path(&b, "A_copied/B/lambda");
+
+ SVN_ERR(svn_io_remove_file2(lambda, FALSE, pool));
+ SVN_ERR(svn_io_copy_file(sbox_wc_path(&b, "iota"), lambda, FALSE, pool));
+
+ SVN_ERR(svn_wc_adm_open3(&adm_access, NULL, b.wc_abspath, TRUE, -1,
+ NULL, NULL, pool));
+
+ {
+ svn_wc_status2_t *status;
+
+ SVN_ERR(svn_wc_status2(&status, lambda, adm_access, pool));
+
+ SVN_TEST_ASSERT(status != NULL);
+ SVN_TEST_ASSERT(status->text_status == svn_wc_status_modified);
+ SVN_TEST_ASSERT(status->copied == TRUE);
+ }
+
+ /* Simulate an old style svn ci . -m "QQQ" on the WC root */
+ queue = svn_wc_committed_queue_create(pool);
+ SVN_ERR(svn_wc_queue_committed(&queue, sbox_wc_path(&b, "A_copied"), adm_access,
+ TRUE, NULL, FALSE, FALSE, NULL, pool));
+ {
+ unsigned char digest[APR_MD5_DIGESTSIZE];
+
+ /* Use the fact that iota has the same checksum to ease committing */
+
+ SVN_ERR(svn_io_file_checksum(digest, lambda, pool));
+
+ SVN_ERR(svn_wc_queue_committed(&queue, lambda, adm_access, FALSE, NULL,
+ FALSE, FALSE, digest, pool));
+ }
+
+ SVN_ERR(svn_wc_process_committed_queue(queue, adm_access,
+ 12, "2014-10-01T19:00:50.966679Z",
+ "me", pool));
+
+ {
+ svn_wc_status2_t *status;
+
+ SVN_ERR(svn_wc_status2(&status, lambda, adm_access, pool));
+
+ /* Node is still modified, as we didn't change the text base! */
+ SVN_TEST_ASSERT(status != NULL);
+ SVN_TEST_ASSERT(status->text_status == svn_wc_status_normal);
+ SVN_TEST_ASSERT(status->copied == FALSE);
+ }
+
+ return SVN_NO_ERROR;
+}
/* ---------------------------------------------------------------------- */
/* The list of test functions */
-struct svn_test_descriptor_t test_funcs[] =
+static int max_threads = 2;
+
+static struct svn_test_descriptor_t test_funcs[] =
{
SVN_TEST_NULL,
SVN_TEST_OPTS_PASS(test_node_get_base,
@@ -319,5 +450,11 @@ struct svn_test_descriptor_t test_funcs[] =
"test svn_wc_parse_externals_description3"),
SVN_TEST_PASS2(test_externals_parse_erratic,
"parse erratic externals definition"),
+ SVN_TEST_OPTS_PASS(test_legacy_commit1,
+ "test legacy commit1"),
+ SVN_TEST_OPTS_PASS(test_legacy_commit2,
+ "test legacy commit2"),
SVN_TEST_NULL
};
+
+SVN_TEST_MAIN