Modified: 
subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/op-depth-test.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/op-depth-test.c?rev=1685464&r1=1685463&r2=1685464&view=diff
==============================================================================
--- subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/op-depth-test.c 
(original)
+++ subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/op-depth-test.c Sun 
Jun 14 20:58:10 2015
@@ -128,6 +128,7 @@ typedef struct conflict_info_t {
 #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
@@ -176,13 +177,17 @@ print_row(const nodes_row_t *row,
   else
     moved_to_str = "";
 
-  if (row->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 = "";
 
@@ -194,14 +199,14 @@ print_row(const nodes_row_t *row,
   if (row->repo_revnum == SVN_INVALID_REVNUM)
     return apr_psprintf(result_pool, "%d, %-20s%-15s NO_COPY_FROM%s%s%s%s",
                         row->op_depth, relpath_str, presence_str,
-                        moved_here_str, moved_to_str,
-                        file_external_str, props);
+                        file_external_str, moved_here_str, moved_to_str,
+                        props);
   else
     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,
-                        moved_here_str, moved_to_str,
-                        file_external_str, props);
+                        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 {
@@ -305,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);
 
@@ -509,7 +515,8 @@ check_db_conflicts(svn_test__sandbox_t *
       local_abspath = svn_dirent_join(b->wc_abspath, info->local_relpath,
                                       iterpool);
 
-      SVN_ERR(svn_wc__db_read_conflict(&conflict, b->wc_ctx->db, local_abspath,
+      SVN_ERR(svn_wc__db_read_conflict(&conflict, NULL, NULL,
+                                       b->wc_ctx->db, local_abspath,
                                        iterpool, iterpool));
 
       SVN_TEST_ASSERT(conflict != NULL);
@@ -561,6 +568,34 @@ check_db_conflicts(svn_test__sandbox_t *
   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 */
@@ -1266,6 +1301,34 @@ insert_dirs(svn_test__sandbox_t *b,
                                   ? 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)
+        {
+          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 if (nodes->repo_relpath
+               && strcmp(nodes->presence, "normal") == 0)
+        {
+          SVN_ERR(svn_sqlite__bind_text(stmt, 9, "()"));
+        }
+
+      /* File externals? */
+
       SVN_ERR(svn_sqlite__step_done(stmt));
       ++nodes;
     }
@@ -1316,9 +1379,7 @@ base_dir_insert_remove(svn_test__sandbox
   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,
@@ -1628,29 +1689,11 @@ test_base_dir_insert_remove(const svn_te
 }
 
 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        -
@@ -1681,7 +1724,7 @@ test_temp_op_make_copy(const svn_test_op
       { 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        -
@@ -1719,14 +1762,18 @@ test_temp_op_make_copy(const svn_test_op
       { 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;
@@ -2044,6 +2091,9 @@ insert_actual(svn_test__sandbox_t *b,
       SVN_ERR(svn_sqlite__step_done(stmt));
       if (actual->changelist)
         {
+          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));
@@ -2793,8 +2843,8 @@ test_children_of_replaced_dir(const svn_
             &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
@@ -2803,12 +2853,7 @@ test_children_of_replaced_dir(const svn_
    * 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));
 
@@ -3538,11 +3583,13 @@ revert_file_externals(const svn_test_opt
   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));
@@ -3551,10 +3598,12 @@ revert_file_externals(const svn_test_opt
   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));
@@ -3563,9 +3612,22 @@ revert_file_externals(const svn_test_opt
   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));
+  }
+
+  SVN_ERR(sbox_wc_update(&b, "", 1));
+  {
+    nodes_row_t rows[] = {
+      { 0, "",    "normal",      1, "" },
+      { 0, "f",   "normal",      1, "f" },
+      { 0, "g",   "normal",      1, "f", TRUE },
       { 0 }
     };
     SVN_ERR(check_db_rows(&b, "", rows));
@@ -3742,6 +3804,8 @@ incomplete_switch(const svn_test_opts_t
     };
 
     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));
@@ -5928,8 +5992,8 @@ check_tree_conflict_repos_path(svn_test_
   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);
@@ -6110,7 +6174,16 @@ move_update_delete_mods(const svn_test_o
       {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"));
@@ -6918,6 +6991,31 @@ commit_moved_descendant(const svn_test_o
      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;
 }
 
@@ -6940,10 +7038,63 @@ commit_moved_away_descendant(const svn_t
   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");
 
@@ -7166,11 +7317,23 @@ move_away_delete_update(const svn_test_o
       {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;
@@ -8311,7 +8474,15 @@ move_retract(const svn_test_opts_t *opts
 
       {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));
   }
 
 
@@ -8342,9 +8513,21 @@ move_retract(const svn_test_opts_t *opts
       /* 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? */
@@ -8354,7 +8537,7 @@ move_retract(const svn_test_opts_t *opts
   {
     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}
     };
@@ -8612,36 +8795,46 @@ move_update_parent_replace(const svn_tes
   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"},
+      {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}
     };
-    actual_row_t actual[] = {
-      {"A/B", NULL},
+    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_actual(&b, actual));
+    SVN_ERR(check_db_conflicts(&b, "", conflicts));
   }
 
   SVN_ERR(sbox_wc_resolve(&b, "A/B", svn_depth_infinity,
-                          svn_wc_conflict_choose_mine_conflict));
+                          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"},
-      {0}
-    };
-    actual_row_t actual[] = {
+      {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_actual(&b, actual));
+    SVN_ERR(check_db_conflicts(&b, "", NULL));
   }
 
   return SVN_NO_ERROR;
@@ -9140,15 +9333,15 @@ move_twice_within_delete(const svn_test_
       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 },
@@ -9475,8 +9668,14 @@ del4_update_edit_AAA(const svn_test_opts
 
     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, "", svn_depth_infinity, 
svn_wc_conflict_choose_merged));
+  SVN_ERR(sbox_wc_resolve(&b, "D/A/A", svn_depth_empty, 
svn_wc_conflict_choose_merged));
 
   {
     nodes_row_t nodes[] = {
@@ -9499,12 +9698,12 @@ del4_update_edit_AAA(const svn_test_opts
       {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, "AAA_1"},
+      {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", MOVED_HERE},
-      {1, "AAA_1/A",   "normal",       1, "A/A/A/A", MOVED_HERE},
-      {1, "AAA_2",     "normal",       1, "B/A/A"},
-      {1, "AAA_2/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},
@@ -9512,7 +9711,7 @@ del4_update_edit_AAA(const svn_test_opts
       {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"},
+      {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},
@@ -9541,12 +9740,53 @@ del4_update_delete_AAA(const svn_test_op
 
   /* 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;
@@ -9561,12 +9801,53 @@ del4_update_add_AAA(const svn_test_opts_
 
   /* 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;
@@ -9581,27 +9862,6 @@ del4_update_replace_AAA(const svn_test_o
 
   /* 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 *
-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,
@@ -9610,23 +9870,89 @@ del4_update_delself_AAA(const svn_test_o
                                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,
+      {"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));
   }
-
-
-  /* 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));
-
+  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, ""},
@@ -9686,7 +10012,40 @@ del4_update_delself_AAA(const svn_test_o
   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));
+  {
+    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));
@@ -9921,7 +10280,21 @@ move4_update_delself_AAA(const svn_test_
 
         { 0 },
       };
-        SVN_ERR(check_db_rows(&b, "", nodes));
+      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,
@@ -9989,14 +10362,46 @@ move4_update_delself_AAA(const svn_test_
 
         { 0 },
       };
-        SVN_ERR(check_db_rows(&b, "", nodes));
+
+      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, "", 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;
+  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 *
@@ -10191,8 +10596,35 @@ movedhere_extract_retract(const svn_test
   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,
@@ -10203,8 +10635,10 @@ movedhere_extract_retract(const svn_test
   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[] = {
 
@@ -10259,6 +10693,8 @@ movedhere_extract_retract(const svn_test
       { 0 },
     };
     SVN_ERR(check_db_rows(&b, "", nodes));
+
+    SVN_ERR(check_db_conflicts(&b, "", NULL));
   }
 
   return SVN_NO_ERROR;
@@ -10815,10 +11251,640 @@ move_edit_obstruction(const svn_test_opt
   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 */
 
-static int max_threads = 2;
+static int max_threads = 4;
 
 static struct svn_test_descriptor_t test_funcs[] =
   {
@@ -10843,8 +11909,8 @@ static struct svn_test_descriptor_t test
                        "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,
@@ -10964,7 +12030,7 @@ static struct svn_test_descriptor_t test
                        "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)"),
@@ -10986,11 +12052,11 @@ static struct svn_test_descriptor_t test
                        "move twice and then delete"),
     SVN_TEST_OPTS_PASS(del4_update_edit_AAA,
                        "del4: edit AAA"),
-    SVN_TEST_OPTS_PASS(del4_update_delete_AAA,
+    SVN_TEST_OPTS_XFAIL(del4_update_delete_AAA,
                        "del4: delete AAA"),
-    SVN_TEST_OPTS_PASS(del4_update_add_AAA,
+    SVN_TEST_OPTS_XFAIL(del4_update_add_AAA,
                        "del4: add AAA"),
-    SVN_TEST_OPTS_PASS(del4_update_replace_AAA,
+    SVN_TEST_OPTS_XFAIL(del4_update_replace_AAA,
                        "del4: replace AAA"),
     SVN_TEST_OPTS_PASS(del4_update_delself_AAA,
                        "del4: delete self AAA"),
@@ -10998,11 +12064,11 @@ static struct svn_test_descriptor_t test
                        "del4: replace self AAA"),
     SVN_TEST_OPTS_PASS(move4_update_edit_AAA,
                        "move4: edit AAA"),
-    SVN_TEST_OPTS_PASS(move4_update_delete_AAA,
+    SVN_TEST_OPTS_XFAIL(move4_update_delete_AAA,
                        "move4: delete AAA"),
-    SVN_TEST_OPTS_PASS(move4_update_add_AAA,
+    SVN_TEST_OPTS_XFAIL(move4_update_add_AAA,
                        "move4: add AAA"),
-    SVN_TEST_OPTS_PASS(move4_update_replace_AAA,
+    SVN_TEST_OPTS_XFAIL(move4_update_replace_AAA,
                        "move4: replace AAA"),
     SVN_TEST_OPTS_PASS(move4_update_delself_AAA,
                        "move4: delete self AAA"),
@@ -11022,6 +12088,16 @@ static struct svn_test_descriptor_t test
                         "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
   };
 

Modified: subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/utils.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/utils.c?rev=1685464&r1=1685463&r2=1685464&view=diff
==============================================================================
--- subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/utils.c (original)
+++ subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/utils.c Sun Jun 14 
20:58:10 2015
@@ -33,7 +33,7 @@
 #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,
@@ -122,6 +122,9 @@ WC_QUERIES_SQL_DECLARE_STATEMENTS(statem
 svn_error_t *
 svn_test__create_fake_wc(const char *wc_abspath,
                          const char *extra_statements,
+                         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",
@@ -129,6 +132,8 @@ svn_test__create_fake_wc(const char *wc_
   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. */
@@ -153,6 +158,110 @@ svn_test__create_fake_wc(const char *wc_
 
   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;
 }
 
@@ -280,8 +389,14 @@ sbox_wc_copy_url(svn_test__sandbox_t *b,
 
   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;
@@ -484,6 +599,35 @@ sbox_wc_resolve(svn_test__sandbox_t *b,
 }
 
 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;

Modified: subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/utils.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/utils.h?rev=1685464&r1=1685463&r2=1685464&view=diff
==============================================================================
--- subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/utils.h (original)
+++ subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/utils.h Sun Jun 14 
20:58:10 2015
@@ -166,6 +166,12 @@ sbox_wc_resolve(svn_test__sandbox_t *b,
 
 /* */
 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. */
@@ -179,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
@@ -186,6 +225,8 @@ sbox_add_and_commit_greek_tree(svn_test_
 svn_error_t *
 svn_test__create_fake_wc(const char *wc_abspath,
                          const char *extra_statements,
+                         const svn_test__nodes_data_t nodes[],
+                         const svn_test__actual_data_t actuals[],
                          apr_pool_t *scratch_pool);
 
 

Modified: 
subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/wc-queries-test.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/wc-queries-test.c?rev=1685464&r1=1685463&r2=1685464&view=diff
==============================================================================
--- subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/wc-queries-test.c 
(original)
+++ subversion/branches/fsx-1.10/subversion/tests/libsvn_wc/wc-queries-test.c 
Sun Jun 14 20:58:10 2015
@@ -97,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,
@@ -107,6 +108,7 @@ static const int slow_statements[] =
   /* Slow, but just if foreign keys are enabled:
    * STMT_DELETE_PRISTINE_IF_UNREFERENCED,
    */
+  STMT_HAVE_STAT1_TABLE, /* Queries sqlite_master which has no index */
 
   -1 /* final marker */
 };
@@ -302,14 +304,21 @@ parse_explanation_item(struct explanatio
       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 */
@@ -918,6 +927,15 @@ test_schema_statistics(apr_pool_t *scrat
                    "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(
@@ -976,6 +994,59 @@ test_schema_statistics(apr_pool_t *scrat
   return SVN_NO_ERROR;
 }
 
+/* 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[] =
@@ -991,6 +1062,8 @@ static struct svn_test_descriptor_t test
                    "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
   };
 


Reply via email to