You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2012/08/16 12:18:03 UTC

svn commit: r1373783 [33/50] - in /subversion/branches/compressed-pristines: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/win32/ contrib/client-side/emacs/ contrib/client-side/svn-push/ contrib/client-side/svnmerge/ cont...

Modified: subversion/branches/compressed-pristines/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_wc/wc_db.c?rev=1373783&r1=1373782&r2=1373783&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_wc/wc_db.c Thu Aug 16 10:17:48 2012
@@ -42,7 +42,10 @@
 #include "wc-queries.h"
 #include "entries.h"
 #include "lock.h"
+#include "conflicts.h"
+#if SVN_WC__VERSION < SVN_WC__USES_CONFLICT_SKELS
 #include "tree_conflicts.h"
+#endif
 #include "wc_db_private.h"
 #include "workqueue.h"
 
@@ -106,18 +109,13 @@
 
 /* Check if the column contains actual properties. The empty set of properties
    is stored as "()", so we have properties if the size of the column is
-   larger then 2. */
+   larger than 2. */
 #define SQLITE_PROPERTIES_AVAILABLE(stmt, i) \
                  (svn_sqlite__column_bytes(stmt, i) > 2)
 
-/* This is a character used to escape itself and the globbing character in
-   globbing sql expressions below.  See escape_sqlite_like().
-
-   NOTE: this should match the character used within wc-metadata.sql  */
-#define LIKE_ESCAPE_CHAR     "#"
-
 /* Calculates the depth of the relpath below "" */
-APR_INLINE static apr_int64_t relpath_depth(const char *relpath)
+APR_INLINE static int
+relpath_depth(const char *relpath)
 {
   int n = 1;
   if (*relpath == '\0')
@@ -134,7 +132,8 @@ APR_INLINE static apr_int64_t relpath_de
 }
 
 
-apr_int64_t svn_wc__db_op_depth_for_upgrade(const char *local_relpath)
+int
+svn_wc__db_op_depth_for_upgrade(const char *local_relpath)
 {
   return relpath_depth(local_relpath);
 }
@@ -184,6 +183,9 @@ typedef struct insert_base_baton_t {
   /* insert a base-deleted working node as well as a base node */
   svn_boolean_t insert_base_deleted;
 
+  /* delete the current working nodes above BASE */
+  svn_boolean_t delete_working;
+
   /* may have work items to queue in this transaction  */
   const svn_skel_t *work_items;
 
@@ -194,7 +196,7 @@ typedef struct insert_working_baton_t {
   /* common to all insertions into WORKING (including NODE_DATA) */
   svn_wc__db_status_t presence;
   svn_kind_t kind;
-  apr_int64_t op_depth;
+  int op_depth;
 
   /* common to all "normal" presence insertions */
   const apr_hash_t *props;
@@ -216,12 +218,18 @@ typedef struct insert_working_baton_t {
   /* for inserting symlinks */
   const char *target;
 
+  svn_boolean_t update_actual_props;
+  const apr_hash_t *new_actual_props;
+
   /* may have work items to queue in this transaction  */
   const svn_skel_t *work_items;
 
+  /* may have conflict to install in this transaction */
+  const svn_skel_t *conflict;
+
   /* If the value is > 0 and < op_depth, also insert a not-present
      at op-depth NOT_PRESENT_OP_DEPTH, based on this same information */
-  apr_int64_t not_present_op_depth;
+  int not_present_op_depth;
 
 } insert_working_baton_t;
 
@@ -311,6 +319,12 @@ set_actual_props(apr_int64_t wc_id,
                  apr_pool_t *scratch_pool);
 
 static svn_error_t *
+mark_conflict(svn_wc__db_wcroot_t *wcroot,
+              const char *local_relpath,
+              const svn_skel_t *conflict_skel,
+              apr_pool_t *scratch_pool);
+
+static svn_error_t *
 insert_incomplete_children(svn_sqlite__db_t *sdb,
                            apr_int64_t wc_id,
                            const char *local_relpath,
@@ -318,7 +332,7 @@ insert_incomplete_children(svn_sqlite__d
                            const char *repos_relpath,
                            svn_revnum_t revision,
                            const apr_array_header_t *children,
-                           apr_int64_t op_depth,
+                           int op_depth,
                            apr_pool_t *scratch_pool);
 
 static svn_error_t *
@@ -329,6 +343,26 @@ db_read_pristine_props(apr_hash_t **prop
                        apr_pool_t *scratch_pool);
 
 static svn_error_t *
+base_get_info(svn_wc__db_status_t *status,
+              svn_kind_t *kind,
+              svn_revnum_t *revision,
+              const char **repos_relpath,
+              apr_int64_t *repos_id,
+              svn_revnum_t *changed_rev,
+              apr_time_t *changed_date,
+              const char **changed_author,
+              svn_depth_t *depth,
+              const svn_checksum_t **checksum,
+              const char **target,
+              svn_wc__db_lock_t **lock,
+              svn_boolean_t *had_props,
+              svn_boolean_t *update_root,
+              svn_wc__db_wcroot_t *wcroot,
+              const char *local_relpath,
+              apr_pool_t *result_pool,
+              apr_pool_t *scratch_pool);
+
+static svn_error_t *
 read_info(svn_wc__db_status_t *status,
           svn_kind_t *kind,
           svn_revnum_t *revision,
@@ -369,7 +403,7 @@ scan_addition(svn_wc__db_status_t *statu
               svn_revnum_t *original_revision,
               const char **moved_from_relpath,
               const char **moved_from_op_root_relpath,
-              apr_int64_t *moved_from_op_depth,
+              int *moved_from_op_depth,
               svn_wc__db_wcroot_t *wcroot,
               const char *local_relpath,
               apr_pool_t *result_pool,
@@ -397,7 +431,7 @@ wclock_owns_lock(svn_boolean_t *own_lock
                  apr_pool_t *scratch_pool);
 
 
-
+ 
 /* Return the absolute path, in local path style, of LOCAL_RELPATH
    in WCROOT.  */
 static const char *
@@ -451,64 +485,6 @@ lock_from_columns(svn_sqlite__stmt_t *st
 }
 
 
-/* */
-static const char *
-escape_sqlite_like(const char * const str, apr_pool_t *result_pool)
-{
-  char *result;
-  const char *old_ptr;
-  char *new_ptr;
-  int len = 0;
-
-  /* Count the number of extra characters we'll need in the escaped string.
-     We could just use the worst case (double) value, but we'd still need to
-     iterate over the string to get it's length.  So why not do something
-     useful why iterating over it, and save some memory at the same time? */
-  for (old_ptr = str; *old_ptr; ++old_ptr)
-    {
-      len++;
-      if (*old_ptr == '%'
-            || *old_ptr == '_'
-            || *old_ptr == LIKE_ESCAPE_CHAR[0])
-        len++;
-    }
-
-  result = apr_palloc(result_pool, len + 1);
-
-  /* Now do the escaping. */
-  for (old_ptr = str, new_ptr = result; *old_ptr; ++old_ptr, ++new_ptr)
-    {
-      if (*old_ptr == '%'
-            || *old_ptr == '_'
-            || *old_ptr == LIKE_ESCAPE_CHAR[0])
-        *(new_ptr++) = LIKE_ESCAPE_CHAR[0];
-      *new_ptr = *old_ptr;
-    }
-  *new_ptr = '\0';
-
-  return result;
-}
-
-
-/* Return a string that can be used as the argument to a SQLite 'LIKE'
-   operator, in order to match any path that is a child of LOCAL_RELPATH
-   (at any depth below LOCAL_RELPATH), *excluding* LOCAL_RELPATH itself.
-   LOCAL_RELPATH may be the empty string, in which case the result will
-   match any path except the empty path.
-
-   Allocate the result either statically or in RESULT_POOL.  */
-static const char *construct_like_arg(const char *local_relpath,
-                                      apr_pool_t *result_pool)
-{
-  if (local_relpath[0] == '\0')
-    return "_%";
-
-  return apr_pstrcat(result_pool,
-                     escape_sqlite_like(local_relpath, result_pool),
-                     "/%", (char *)NULL);
-}
-
-
 /* Look up REPOS_ID in SDB and set *REPOS_ROOT_URL and/or *REPOS_UUID to
    its root URL and UUID respectively.  If REPOS_ID is INVALID_REPOS_ID,
    use NULL for both URL and UUID.  Either or both output parameters may be
@@ -711,7 +687,7 @@ extend_parent_delete(svn_wc__db_wcroot_t
 {
   svn_boolean_t have_row;
   svn_sqlite__stmt_t *stmt;
-  apr_int64_t parent_op_depth;
+  int parent_op_depth;
   const char *parent_relpath = svn_relpath_dirname(local_relpath, scratch_pool);
 
   SVN_ERR_ASSERT(local_relpath[0]);
@@ -721,22 +697,22 @@ extend_parent_delete(svn_wc__db_wcroot_t
   SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, parent_relpath));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
   if (have_row)
-    parent_op_depth = svn_sqlite__column_int64(stmt, 0);
+    parent_op_depth = svn_sqlite__column_int(stmt, 0);
   SVN_ERR(svn_sqlite__reset(stmt));
   if (have_row)
     {
-      apr_int64_t op_depth;
+      int op_depth;
 
       SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
       SVN_ERR(svn_sqlite__step(&have_row, stmt));
       if (have_row)
-        op_depth = svn_sqlite__column_int64(stmt, 0);
+        op_depth = svn_sqlite__column_int(stmt, 0);
       SVN_ERR(svn_sqlite__reset(stmt));
       if (!have_row || parent_op_depth < op_depth)
         {
           SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                         STMT_INSTALL_WORKING_NODE_FOR_DELETE));
-          SVN_ERR(svn_sqlite__bindf(stmt, "isit", wcroot->wc_id,
+          SVN_ERR(svn_sqlite__bindf(stmt, "isdt", wcroot->wc_id,
                                     local_relpath, parent_op_depth,
                                     presence_map,
                                     svn_wc__db_status_base_deleted));
@@ -783,7 +759,6 @@ insert_base_node(void *baton,
   svn_sqlite__stmt_t *stmt;
   svn_filesize_t recorded_size = SVN_INVALID_FILESIZE;
   apr_int64_t recorded_mod_time;
-  svn_boolean_t have_row;
 
   /* The directory at the WCROOT has a NULL parent_relpath. Otherwise,
      bind the appropriate parent_relpath. */
@@ -798,32 +773,29 @@ insert_base_node(void *baton,
   SVN_ERR_ASSERT(repos_id != INVALID_REPOS_ID);
   SVN_ERR_ASSERT(pibb->repos_relpath != NULL);
 
-  /* ### we can't handle this right now  */
-  SVN_ERR_ASSERT(pibb->conflict == NULL);
-
-  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                    STMT_SELECT_BASE_NODE));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
-  SVN_ERR(svn_sqlite__step(&have_row, stmt));
-  if (have_row)
+  if (pibb->keep_recorded_info)
     {
-      /* A BASE node already exists. */
-      if (pibb->keep_recorded_info)
+      svn_boolean_t have_row;
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_SELECT_BASE_NODE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+      if (have_row)
         {
           /* Preserve size and modification time if caller asked us to. */
           recorded_size = get_recorded_size(stmt, 6);
           recorded_mod_time = svn_sqlite__column_int64(stmt, 12);
         }
+      SVN_ERR(svn_sqlite__reset(stmt));
     }
-  SVN_ERR(svn_sqlite__reset(stmt));
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_INSERT_NODE));
-  SVN_ERR(svn_sqlite__bindf(stmt, "isisisr"
+  SVN_ERR(svn_sqlite__bindf(stmt, "isdsisr"
                             "tstr"               /* 8 - 11 */
                             "isnnnnns",          /* 12 - 19 */
                             wcroot->wc_id,       /* 1 */
                             local_relpath,       /* 2 */
-                            (apr_int64_t)0, /* op_depth is 0 for base */
+                            0,              /* op_depth is 0 for base */
                             parent_relpath,      /* 4 */
                             repos_id,
                             pibb->repos_relpath,
@@ -920,17 +892,26 @@ insert_base_node(void *baton,
         }
     }
 
+  if (pibb->delete_working)
+    {
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_DELETE_WORKING_NODE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+    }
   if (pibb->insert_base_deleted)
     {
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                         STMT_INSERT_DELETE_FROM_BASE));
-      SVN_ERR(svn_sqlite__bindf(stmt, "isi",
+      SVN_ERR(svn_sqlite__bindf(stmt, "isd",
                                 wcroot->wc_id, local_relpath,
                                 relpath_depth(local_relpath)));
       SVN_ERR(svn_sqlite__step_done(stmt));
     }
 
   SVN_ERR(add_work_items(wcroot->sdb, pibb->work_items, scratch_pool));
+  if (pibb->conflict)
+    SVN_ERR(mark_conflict(wcroot, local_relpath, pibb->conflict, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -963,7 +944,7 @@ insert_incomplete_children(svn_sqlite__d
                            const char *repos_path,
                            svn_revnum_t revision,
                            const apr_array_header_t *children,
-                           apr_int64_t op_depth,
+                           int op_depth,
                            apr_pool_t *scratch_pool)
 {
   svn_sqlite__stmt_t *stmt;
@@ -1009,7 +990,7 @@ insert_incomplete_children(svn_sqlite__d
 
       svn_pool_clear(iterpool);
 
-      SVN_ERR(svn_sqlite__bindf(stmt, "isisnnrsnsnnnnnnnnnnsn",
+      SVN_ERR(svn_sqlite__bindf(stmt, "isdsnnrsnsnnnnnnnnnnsn",
                                 wc_id,
                                 svn_relpath_join(local_relpath, name,
                                                  iterpool),
@@ -1056,9 +1037,9 @@ insert_working_node(void *baton,
   parent_relpath = svn_relpath_dirname(local_relpath, scratch_pool);
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_INSERT_NODE));
-  SVN_ERR(svn_sqlite__bindf(stmt, "isisnnntstrisn"
+  SVN_ERR(svn_sqlite__bindf(stmt, "isdsnnntstrisn"
                 "nnnn" /* properties translated_size last_mod_time dav_cache */
-                "snni", /* symlink_target, file_external, moved_to, moved_here */
+                "snnd", /* symlink_target, file_external, moved_to, moved_here */
                 wcroot->wc_id, local_relpath,
                 piwb->op_depth,
                 parent_relpath,
@@ -1072,7 +1053,7 @@ insert_working_node(void *baton,
                 /* Note: incomplete nodes may have a NULL target.  */
                 (piwb->kind == svn_kind_symlink)
                             ? piwb->target : NULL,
-                (apr_int64_t)piwb->moved_here));
+                piwb->moved_here));
 
   if (piwb->kind == svn_kind_file)
     {
@@ -1084,7 +1065,7 @@ insert_working_node(void *baton,
     {
       SVN_ERR(svn_sqlite__bind_int64(stmt, 5, piwb->original_repos_id));
       SVN_ERR(svn_sqlite__bind_text(stmt, 6, piwb->original_repos_relpath));
-      SVN_ERR(svn_sqlite__bind_int64(stmt, 7, piwb->original_revnum));
+      SVN_ERR(svn_sqlite__bind_revnum(stmt, 7, piwb->original_revnum));
     }
 
   SVN_ERR(svn_sqlite__bind_properties(stmt, 15, piwb->props, scratch_pool));
@@ -1105,6 +1086,29 @@ insert_working_node(void *baton,
                                        piwb->op_depth,
                                        scratch_pool));
 
+  if (piwb->update_actual_props)
+    {
+      /* Cast away const, to allow calling property helpers */
+      apr_hash_t *base_props = (apr_hash_t *)piwb->props;
+      apr_hash_t *new_actual_props = (apr_hash_t *)piwb->new_actual_props;
+
+      if (base_props != NULL
+          && new_actual_props != NULL
+          && (apr_hash_count(base_props) == apr_hash_count(new_actual_props)))
+        {
+          apr_array_header_t *diffs;
+
+          SVN_ERR(svn_prop_diffs(&diffs, new_actual_props, base_props,
+                                 scratch_pool));
+
+          if (diffs->nelts == 0)
+            new_actual_props = NULL;
+        }
+
+      SVN_ERR(set_actual_props(wcroot->wc_id, local_relpath, new_actual_props,
+                               wcroot->sdb, scratch_pool));
+    }
+
   if (piwb->kind == svn_kind_dir)
     {
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
@@ -1118,8 +1122,6 @@ insert_working_node(void *baton,
       SVN_ERR(svn_sqlite__step_done(stmt));
     }
 
-  SVN_ERR(add_work_items(wcroot->sdb, piwb->work_items, scratch_pool));
-
   if (piwb->not_present_op_depth > 0
       && piwb->not_present_op_depth < piwb->op_depth)
     {
@@ -1128,7 +1130,7 @@ insert_working_node(void *baton,
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                         STMT_INSERT_NODE));
 
-      SVN_ERR(svn_sqlite__bindf(stmt, "isisisrtnt",
+      SVN_ERR(svn_sqlite__bindf(stmt, "isdsisrtnt",
                                 wcroot->wc_id, local_relpath,
                                 piwb->not_present_op_depth, parent_relpath,
                                 piwb->original_repos_id,
@@ -1141,6 +1143,11 @@ insert_working_node(void *baton,
       SVN_ERR(svn_sqlite__step_done(stmt));
     }
 
+  SVN_ERR(add_work_items(wcroot->sdb, piwb->work_items, scratch_pool));
+  if (piwb->conflict)
+    SVN_ERR(mark_conflict(wcroot, local_relpath, piwb->conflict,
+                          scratch_pool));
+
   return SVN_NO_ERROR;
 }
 
@@ -1232,7 +1239,7 @@ static svn_error_t *
 gather_repo_children(const apr_array_header_t **children,
                      svn_wc__db_wcroot_t *wcroot,
                      const char *local_relpath,
-                     apr_int64_t op_depth,
+                     int op_depth,
                      apr_pool_t *result_pool,
                      apr_pool_t *scratch_pool)
 {
@@ -1243,7 +1250,7 @@ gather_repo_children(const apr_array_hea
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                     STMT_SELECT_OP_DEPTH_CHILDREN));
-  SVN_ERR(svn_sqlite__bindf(stmt, "isi", wcroot->wc_id, local_relpath,
+  SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
                             op_depth));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
   while (have_row)
@@ -1363,7 +1370,7 @@ add_single_work_item(svn_sqlite__db_t *s
 }
 
 
-/* Add work item(s) to the given SDB. Also see add_one_work_item(). This
+/* Add work item(s) to the given SDB. Also see add_single_work_item(). This
    SKEL is usually passed to the various wc_db operation functions. It may
    be NULL, indicating no additional work items are needed, it may be a
    single work item, or it may be a list of work items.  */
@@ -1459,11 +1466,77 @@ create_pristine_db(svn_sqlite__db_t **pd
   return SVN_NO_ERROR;
 }
 
+/* baton for init_db */
+struct init_db_baton
+{
+  /* output values */
+  apr_int64_t wc_id;
+  apr_int64_t repos_id;
+  /* input values */
+  const char *repos_root_url;
+  const char *repos_uuid;
+  const char *root_node_repos_relpath;
+  svn_revnum_t root_node_revision;
+  svn_depth_t root_node_depth;
+};
+
+/* Helper for create_db(). Initializes our wc.db schema */
+static svn_error_t *
+init_db( void *baton, svn_sqlite__db_t *db, apr_pool_t *scratch_pool)
+{
+  struct init_db_baton *idb = baton;
+  svn_sqlite__stmt_t *stmt;
+
+  /* Create the database's schema.  */
+  SVN_ERR(svn_sqlite__exec_statements(db, STMT_CREATE_SCHEMA));
+  SVN_ERR(svn_sqlite__exec_statements(db, STMT_CREATE_NODES));
+  SVN_ERR(svn_sqlite__exec_statements(db, STMT_CREATE_NODES_TRIGGERS));
+  SVN_ERR(svn_sqlite__exec_statements(db, STMT_CREATE_EXTERNALS));
+
+  /* Insert the repository. */
+  SVN_ERR(create_repos_id(&idb->repos_id, idb->repos_root_url, idb->repos_uuid,
+                          db, scratch_pool));
+
+  /* Insert the wcroot. */
+  /* ### Right now, this just assumes wc metadata is being stored locally. */
+  SVN_ERR(svn_sqlite__get_statement(&stmt, db, STMT_INSERT_WCROOT));
+  SVN_ERR(svn_sqlite__insert(&idb->wc_id, stmt));
+
+  if (idb->root_node_repos_relpath)
+    {
+      svn_wc__db_status_t status = svn_wc__db_status_normal;
+
+      if (idb->root_node_revision > 0)
+        status = svn_wc__db_status_incomplete; /* Will be filled by update */
+
+      SVN_ERR(svn_sqlite__get_statement(&stmt, db, STMT_INSERT_NODE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "isdsisrtst",
+                                idb->wc_id,          /* 1 */
+                                "",                  /* 2 */
+                                0,                   /* op_depth is 0 for base */
+                                NULL,                /* 4 */
+                                idb->repos_id,
+                                idb->root_node_repos_relpath,
+                                idb->root_node_revision,
+                                presence_map, status, /* 8 */
+                                svn_depth_to_word(idb->root_node_depth),
+                                kind_map, svn_kind_dir /* 10 */));
+
+      SVN_ERR(svn_sqlite__insert(NULL, stmt));
+    }
+
+  return SVN_NO_ERROR;
+}
 
 /* Create an sqlite database at DIR_ABSPATH/SDB_FNAME and insert
    records for REPOS_ID (using REPOS_ROOT_URL and REPOS_UUID) into
    REPOSITORY and for WC_ID into WCROOT.  Return the DB connection
-   in *SDB. */
+   in *SDB.
+
+   If ROOT_NODE_REPOS_RELPATH is not NULL, insert a BASE node at
+   the working copy root with repository relpath ROOT_NODE_REPOS_RELPATH,
+   revision ROOT_NODE_REVISION and depth ROOT_NODE_DEPTH.
+   */
 static svn_error_t *
 create_db(svn_sqlite__db_t **sdb,
           apr_int64_t *repos_id,
@@ -1472,30 +1545,29 @@ create_db(svn_sqlite__db_t **sdb,
           const char *repos_root_url,
           const char *repos_uuid,
           const char *sdb_fname,
+          const char *root_node_repos_relpath,
+          svn_revnum_t root_node_revision,
+          svn_depth_t root_node_depth,
           apr_pool_t *result_pool,
           apr_pool_t *scratch_pool)
 {
-  svn_sqlite__stmt_t *stmt;
+  struct init_db_baton idb;
 
   SVN_ERR(svn_wc__db_util_open_db(sdb, dir_abspath, sdb_fname,
                                   svn_sqlite__mode_rwcreate,
                                   NULL /* my_statements */,
                                   result_pool, scratch_pool));
 
-  /* Create the database's schema.  */
-  SVN_ERR(svn_sqlite__exec_statements(*sdb, STMT_CREATE_SCHEMA));
-  SVN_ERR(svn_sqlite__exec_statements(*sdb, STMT_CREATE_NODES));
-  SVN_ERR(svn_sqlite__exec_statements(*sdb, STMT_CREATE_NODES_TRIGGERS));
-  SVN_ERR(svn_sqlite__exec_statements(*sdb, STMT_CREATE_EXTERNALS));
+  idb.repos_root_url = repos_root_url;
+  idb.repos_uuid = repos_uuid;
+  idb.root_node_repos_relpath = root_node_repos_relpath;
+  idb.root_node_revision = root_node_revision;
+  idb.root_node_depth = root_node_depth;
 
-  /* Insert the repository. */
-  SVN_ERR(create_repos_id(repos_id, repos_root_url, repos_uuid, *sdb,
-                          scratch_pool));
+  SVN_ERR(svn_sqlite__with_lock(*sdb, init_db, &idb, scratch_pool));
 
-  /* Insert the wcroot. */
-  /* ### Right now, this just assumes wc metadata is being stored locally. */
-  SVN_ERR(svn_sqlite__get_statement(&stmt, *sdb, STMT_INSERT_WCROOT));
-  SVN_ERR(svn_sqlite__insert(wc_id, stmt));
+  *repos_id = idb.repos_id;
+  *wc_id = idb.wc_id;
 
   return SVN_NO_ERROR;
 }
@@ -1516,7 +1588,6 @@ svn_wc__db_init(svn_wc__db_t *db,
   apr_int64_t repos_id;
   apr_int64_t wc_id;
   svn_wc__db_wcroot_t *wcroot;
-  insert_base_baton_t ibb;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
   SVN_ERR_ASSERT(repos_relpath != NULL);
@@ -1529,7 +1600,9 @@ svn_wc__db_init(svn_wc__db_t *db,
 
   /* Create the SDB and insert the basic rows.  */
   SVN_ERR(create_db(&sdb, &repos_id, &wc_id, local_abspath, repos_root_url,
-                    repos_uuid, SDB_FILE, db->state_pool, scratch_pool));
+                    repos_uuid, SDB_FILE, 
+                    repos_relpath, initial_rev, depth,
+                    db->state_pool, scratch_pool));
 
   /* Create the PDB. */
   SVN_ERR(create_pristine_db(&pdb, local_abspath, repos_root_url,
@@ -1546,24 +1619,7 @@ svn_wc__db_init(svn_wc__db_t *db,
   /* The WCROOT is complete. Stash it into DB.  */
   apr_hash_set(db->dir_data, wcroot->abspath, APR_HASH_KEY_STRING, wcroot);
 
-  blank_ibb(&ibb);
-
-  if (initial_rev > 0)
-    ibb.status = svn_wc__db_status_incomplete;
-  else
-    ibb.status = svn_wc__db_status_normal;
-  ibb.kind = svn_kind_dir;
-  ibb.repos_id = repos_id;
-  ibb.repos_relpath = repos_relpath;
-  ibb.revision = initial_rev;
-
-  /* ### what about the children?  */
-  ibb.children = NULL;
-  ibb.depth = depth;
-
-  /* ### no children, conflicts, or work items to install in a txn... */
-
-  return svn_error_trace(insert_base_node(&ibb, wcroot, "", scratch_pool));
+  return SVN_NO_ERROR;
 }
 
 
@@ -1735,6 +1791,60 @@ svn_wc__db_base_add_directory(svn_wc__db
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_wc__db_base_add_incomplete_directory(svn_wc__db_t *db,
+                                         const char *local_abspath,
+                                         const char *repos_relpath,
+                                         const char *repos_root_url,
+                                         const char *repos_uuid,
+                                         svn_revnum_t revision,
+                                         svn_depth_t depth,
+                                         svn_boolean_t insert_base_deleted,
+                                         svn_boolean_t delete_working,
+                                         svn_skel_t *conflict,
+                                         svn_skel_t *work_items,
+                                         apr_pool_t *scratch_pool)
+{
+  svn_wc__db_wcroot_t *wcroot;
+  const char *local_relpath;
+  struct insert_base_baton_t ibb;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+  SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(revision));
+  SVN_ERR_ASSERT(repos_relpath && repos_root_url && repos_uuid);
+
+  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath,
+                                                db, local_abspath,
+                                                scratch_pool, scratch_pool));
+
+  VERIFY_USABLE_WCROOT(wcroot);
+
+  blank_ibb(&ibb);
+
+  /* Calculate repos_id in insert_base_node() to avoid extra transaction */
+  ibb.repos_root_url = repos_root_url;
+  ibb.repos_uuid = repos_uuid;
+
+  ibb.status = svn_wc__db_status_incomplete;
+  ibb.kind = svn_kind_dir;
+  ibb.repos_relpath = repos_relpath;
+  ibb.revision = revision;
+  ibb.depth = depth;
+  ibb.insert_base_deleted = insert_base_deleted;
+  ibb.delete_working = delete_working;
+
+  ibb.conflict = conflict;
+  ibb.work_items = work_items;
+
+  SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath,
+                              insert_base_node,
+                              &ibb, scratch_pool));
+
+  SVN_ERR(flush_entries(wcroot, local_abspath, svn_depth_empty, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
 
 svn_error_t *
 svn_wc__db_base_add_file(svn_wc__db_t *db,
@@ -1750,11 +1860,12 @@ svn_wc__db_base_add_file(svn_wc__db_t *d
                          const char *changed_author,
                          const svn_checksum_t *checksum,
                          apr_hash_t *dav_cache,
-                         const svn_skel_t *conflict,
+                         svn_boolean_t delete_working,
                          svn_boolean_t update_actual_props,
                          apr_hash_t *new_actual_props,
                          svn_boolean_t keep_recorded_info,
                          svn_boolean_t insert_base_deleted,
+                         const svn_skel_t *conflict,
                          const svn_skel_t *work_items,
                          apr_pool_t *scratch_pool)
 {
@@ -1795,8 +1906,6 @@ svn_wc__db_base_add_file(svn_wc__db_t *d
   ibb.checksum = checksum;
 
   ibb.dav_cache = dav_cache;
-  ibb.conflict = conflict;
-  ibb.work_items = work_items;
 
   if (update_actual_props)
     {
@@ -1806,6 +1915,10 @@ svn_wc__db_base_add_file(svn_wc__db_t *d
 
   ibb.keep_recorded_info = keep_recorded_info;
   ibb.insert_base_deleted = insert_base_deleted;
+  ibb.delete_working = delete_working;
+
+  ibb.conflict = conflict;
+  ibb.work_items = work_items;
 
   SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath, insert_base_node, &ibb,
                               scratch_pool));
@@ -1832,9 +1945,12 @@ svn_wc__db_base_add_symlink(svn_wc__db_t
                             const char *changed_author,
                             const char *target,
                             apr_hash_t *dav_cache,
-                            const svn_skel_t *conflict,
+                            svn_boolean_t delete_working,
                             svn_boolean_t update_actual_props,
                             apr_hash_t *new_actual_props,
+                            svn_boolean_t keep_recorded_info,
+                            svn_boolean_t insert_base_deleted,
+                            const svn_skel_t *conflict,
                             const svn_skel_t *work_items,
                             apr_pool_t *scratch_pool)
 {
@@ -1874,8 +1990,6 @@ svn_wc__db_base_add_symlink(svn_wc__db_t
   ibb.target = target;
 
   ibb.dav_cache = dav_cache;
-  ibb.conflict = conflict;
-  ibb.work_items = work_items;
 
   if (update_actual_props)
     {
@@ -1883,6 +1997,13 @@ svn_wc__db_base_add_symlink(svn_wc__db_t
       ibb.new_actual_props = new_actual_props;
     }
 
+  ibb.keep_recorded_info = keep_recorded_info;
+  ibb.insert_base_deleted = insert_base_deleted;
+  ibb.delete_working = delete_working;
+
+  ibb.conflict = conflict;
+  ibb.work_items = work_items;
+
   SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath, insert_base_node, &ibb,
                               scratch_pool));
 
@@ -2005,6 +2126,15 @@ svn_wc__db_base_add_not_present_node(svn
     kind, svn_wc__db_status_not_present, conflict, work_items, scratch_pool);
 }
 
+/* Baton for db_base_remove */
+struct base_remove_baton
+{
+  svn_wc__db_t *db; /* For checking conflicts */
+  svn_boolean_t keep_as_working;
+  svn_revnum_t not_present_revision;
+  svn_skel_t *conflict;
+  svn_skel_t *work_items;
+};
 
 /* This implements svn_wc__db_txn_callback_t */
 static svn_error_t *
@@ -2015,57 +2145,232 @@ db_base_remove(void *baton,
 {
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
+  struct base_remove_baton *rb = baton;
+  svn_wc__db_status_t status;
+  apr_int64_t repos_id;
+  const char *repos_relpath;
+  svn_kind_t kind;
+  svn_boolean_t keep_working;
 
-  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                    STMT_DELETE_BASE_NODE));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
-  SVN_ERR(svn_sqlite__step_done(stmt));
-
-  SVN_ERR(retract_parent_delete(wcroot, local_relpath, scratch_pool));
+  SVN_ERR(base_get_info(&status, &kind, NULL, &repos_relpath, &repos_id,
+                        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                        NULL,
+                        wcroot, local_relpath,
+                        scratch_pool, scratch_pool));
 
-  /* If there is no working node then any actual node must be deleted,
-     unless it marks a conflict */
-  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                    STMT_SELECT_WORKING_NODE));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
-  SVN_ERR(svn_sqlite__step(&have_row, stmt));
-  SVN_ERR(svn_sqlite__reset(stmt));
-  if (!have_row)
+  /* ### This function should be turned into a helper of this function,
+         as this is the only valid caller */
+  if (status == svn_wc__db_status_normal
+      && rb->keep_as_working)
+    {
+      SVN_ERR(svn_wc__db_temp_op_make_copy(rb->db,
+                                           svn_dirent_join(wcroot->abspath,
+                                                           local_relpath,
+                                                           scratch_pool),
+                                           scratch_pool));
+      keep_working = TRUE;
+    }
+  else
     {
+      /* Check if there is already a working node */
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                    STMT_DELETE_ACTUAL_NODE_WITHOUT_CONFLICT));
+                                        STMT_SELECT_WORKING_NODE));
       SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
-      SVN_ERR(svn_sqlite__step_done(stmt));
+      SVN_ERR(svn_sqlite__step(&keep_working, stmt));
+      SVN_ERR(svn_sqlite__reset(stmt));
     }
 
-  return SVN_NO_ERROR;
-}
+  /* Step 1: Create workqueue operations to remove files and dirs in the
+     local-wc */
+  if (!keep_working
+      && (status == svn_wc__db_status_normal
+          || status == svn_wc__db_status_incomplete))
+    {
+      svn_skel_t *work_item;
+      const char *local_abspath;
 
+      local_abspath = svn_dirent_join(wcroot->abspath, local_relpath,
+                                      scratch_pool);
+      if (kind == svn_kind_dir)
+        {
+          apr_pool_t *iterpool;
+          SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                            STMT_SELECT_BASE_PRESENT));
+          SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
 
-svn_error_t *
-svn_wc__db_base_remove(svn_wc__db_t *db,
-                       const char *local_abspath,
-                       apr_pool_t *scratch_pool)
-{
-  svn_wc__db_wcroot_t *wcroot;
-  const char *local_relpath;
+          iterpool = svn_pool_create(scratch_pool);
 
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+          SVN_ERR(svn_sqlite__step(&have_row, stmt));
 
-  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
-                              local_abspath, scratch_pool, scratch_pool));
-  VERIFY_USABLE_WCROOT(wcroot);
+          while (have_row)
+            {
+              const char *node_relpath = svn_sqlite__column_text(stmt, 0, NULL);
+              svn_kind_t node_kind = svn_sqlite__column_token(stmt, 1,
+                                                              kind_map);
+              const char *node_abspath;
 
-  SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath, db_base_remove, NULL,
-                              scratch_pool));
+              svn_pool_clear(iterpool);
 
-  /* If this used to be a directory we should remove children so pass
-   * depth infinity. */
-  SVN_ERR(flush_entries(wcroot, local_abspath, svn_depth_infinity,
-                        scratch_pool));
+              node_abspath = svn_dirent_join(wcroot->abspath, node_relpath,
+                                             iterpool);
 
-  return SVN_NO_ERROR;
-}
+              if (node_kind == svn_kind_dir)
+                SVN_ERR(svn_wc__wq_build_dir_remove(&work_item,
+                                                    rb->db, wcroot->abspath,
+                                                    node_abspath, FALSE,
+                                                    iterpool, iterpool));
+              else
+                SVN_ERR(svn_wc__wq_build_file_remove(&work_item,
+                                                     rb->db,
+                                                     wcroot->abspath,
+                                                     node_abspath,
+                                                     iterpool, iterpool));
+
+              SVN_ERR(add_work_items(wcroot->sdb, work_item, iterpool));
+
+              SVN_ERR(svn_sqlite__step(&have_row, stmt));
+           }
+
+          SVN_ERR(svn_sqlite__reset(stmt));
+
+          SVN_ERR(svn_wc__wq_build_dir_remove(&work_item,
+                                              rb->db, wcroot->abspath,
+                                              local_abspath, FALSE,
+                                              scratch_pool, iterpool));
+          svn_pool_destroy(iterpool);
+        }
+      else
+        SVN_ERR(svn_wc__wq_build_file_remove(&work_item,
+                                             rb->db, wcroot->abspath,
+                                             local_abspath,
+                                             scratch_pool, scratch_pool));
+
+      SVN_ERR(add_work_items(wcroot->sdb, work_item, scratch_pool));
+    }
+
+  /* Step 2: Delete ACTUAL nodes */
+  if (! keep_working)
+    {
+      /* There won't be a record in NODE left for this node, so we want
+         to remove *all* ACTUAL nodes, including ACTUAL ONLY. */
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_DELETE_ACTUAL_NODE_RECURSIVE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+    }
+  else if (! rb->keep_as_working)
+    {
+      /* Delete only the ACTUAL nodes that apply to a delete of a BASE node */
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                       STMT_DELETE_ACTUAL_FOR_BASE_RECURSIVE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+    }
+  /* Else: Everything has been turned into a copy, so we want to keep all
+           ACTUAL_NODE records */
+
+  /* Step 3: Delete WORKING nodes */
+  if (keep_working)
+    {
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_DELETE_WORKING_BASE_DELETE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+    }
+  else
+    {
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_DELETE_WORKING_RECURSIVE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+    }
+
+  /* Step 4: Delete the BASE node descendants */
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_DELETE_BASE_RECURSIVE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+
+  /* Step 5: handle the BASE node itself */
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_DELETE_BASE_NODE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+
+  SVN_ERR(retract_parent_delete(wcroot, local_relpath, scratch_pool));
+
+  /* Step 6: Delete actual node if we don't keep working */
+  if (! keep_working)
+    {
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_DELETE_ACTUAL_NODE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+    }
+
+  if (SVN_IS_VALID_REVNUM(rb->not_present_revision))
+    {
+      struct insert_base_baton_t ibb;
+      blank_ibb(&ibb);
+
+      ibb.repos_id = repos_id;
+      ibb.status = svn_wc__db_status_not_present;
+      ibb.kind = kind;
+      ibb.repos_relpath = repos_relpath;
+      ibb.revision = rb->not_present_revision;
+
+      /* Depending upon KIND, any of these might get used. */
+      ibb.children = NULL;
+      ibb.depth = svn_depth_unknown;
+      ibb.checksum = NULL;
+      ibb.target = NULL;
+
+      SVN_ERR(insert_base_node(&ibb, wcroot, local_relpath, scratch_pool));
+    }
+
+  SVN_ERR(add_work_items(wcroot->sdb, rb->work_items, scratch_pool));
+  if (rb->conflict)
+    SVN_ERR(mark_conflict(wcroot, local_relpath, rb->conflict, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
+svn_wc__db_base_remove(svn_wc__db_t *db,
+                       const char *local_abspath,
+                       svn_boolean_t keep_as_working,
+                       svn_revnum_t not_present_revision,
+                       svn_skel_t *conflict,
+                       svn_skel_t *work_items,
+                       apr_pool_t *scratch_pool)
+{
+  svn_wc__db_wcroot_t *wcroot;
+  const char *local_relpath;
+  struct base_remove_baton rb;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+
+  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
+                              local_abspath, scratch_pool, scratch_pool));
+  VERIFY_USABLE_WCROOT(wcroot);
+
+  rb.db = db;
+  rb.keep_as_working = keep_as_working;
+  rb.not_present_revision = not_present_revision;
+  rb.conflict = conflict;
+  rb.work_items = work_items;
+
+  SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath, db_base_remove, &rb,
+                              scratch_pool));
+
+  /* If this used to be a directory we should remove children so pass
+   * depth infinity. */
+  SVN_ERR(flush_entries(wcroot, local_abspath, svn_depth_infinity,
+                        scratch_pool));
+
+  return SVN_NO_ERROR;
+}
 
 
 /* Like svn_wc__db_base_get_info(), but taking WCROOT+LOCAL_RELPATH instead of
@@ -2464,7 +2769,7 @@ depth_get_info(svn_wc__db_status_t *stat
                 svn_boolean_t *had_props,
                 svn_wc__db_wcroot_t *wcroot,
                 const char *local_relpath,
-                apr_int64_t op_depth,
+                int op_depth,
                 apr_pool_t *result_pool,
                 apr_pool_t *scratch_pool)
 {
@@ -2474,7 +2779,7 @@ depth_get_info(svn_wc__db_status_t *stat
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                     STMT_SELECT_DEPTH_NODE));
-  SVN_ERR(svn_sqlite__bindf(stmt, "isi",
+  SVN_ERR(svn_sqlite__bindf(stmt, "isd",
                             wcroot->wc_id, local_relpath, op_depth));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
 
@@ -2802,6 +3107,7 @@ svn_wc__db_external_add_file(svn_wc__db_
                              apr_hash_t *new_actual_props,
 
                              svn_boolean_t keep_recorded_info,
+                             const svn_skel_t *conflict,
                              const svn_skel_t *work_items,
                              apr_pool_t *scratch_pool)
 {
@@ -2858,6 +3164,7 @@ svn_wc__db_external_add_file(svn_wc__db_
 
   ieb.keep_recorded_info = keep_recorded_info;
 
+  ieb.conflict = conflict;
   ieb.work_items = work_items;
 
   return svn_error_trace(
@@ -3172,8 +3479,8 @@ svn_wc__db_committable_externals_below(a
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                     STMT_SELECT_COMMITTABLE_EXTERNALS_BELOW));
 
-  SVN_ERR(svn_sqlite__bindf(stmt, "isi", wcroot->wc_id, local_relpath,
-                            (apr_int64_t)(immediates_only ? 1 : 0)));
+  SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
+                            (immediates_only ? 1 : 0)));
 
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
 
@@ -3193,8 +3500,8 @@ svn_wc__db_committable_externals_below(a
       SVN_ERR_ASSERT(db_kind == svn_kind_file || db_kind == svn_kind_dir);
       info->kind = db_kind;
 
-      info->repos_relpath = svn_sqlite__column_text(stmt, 3, result_pool);
-      info->repos_root_url = svn_sqlite__column_text(stmt, 4, result_pool);
+      info->repos_relpath = svn_sqlite__column_text(stmt, 2, result_pool);
+      info->repos_root_url = svn_sqlite__column_text(stmt, 3, result_pool);
 
       APR_ARRAY_PUSH(result, svn_wc__committable_external_info_t *) = info;
 
@@ -3354,9 +3661,9 @@ copy_actual(svn_wc__db_wcroot_t *src_wcr
       const char *properties;
 
       /* Skipping conflict data... */
-      changelist = svn_sqlite__column_text(stmt, 1, scratch_pool);
+      changelist = svn_sqlite__column_text(stmt, 0, scratch_pool);
       /* No need to parse the properties when simply copying. */
-      properties = svn_sqlite__column_blob(stmt, 6, &props_size, scratch_pool);
+      properties = svn_sqlite__column_blob(stmt, 1, &props_size, scratch_pool);
 
       if (changelist || properties)
         {
@@ -3364,11 +3671,10 @@ copy_actual(svn_wc__db_wcroot_t *src_wcr
 
           SVN_ERR(svn_sqlite__get_statement(&stmt, dst_wcroot->sdb,
                                             STMT_INSERT_ACTUAL_NODE));
-          SVN_ERR(svn_sqlite__bindf(stmt, "issbssssss",
+          SVN_ERR(svn_sqlite__bindf(stmt, "issbs",
                                     dst_wcroot->wc_id, dst_relpath,
                                 svn_relpath_dirname(dst_relpath, scratch_pool),
-                                    properties, props_size, NULL, NULL, NULL,
-                                    NULL, changelist, NULL));
+                                    properties, props_size, changelist));
           SVN_ERR(svn_sqlite__step(&have_row, stmt));
         }
     }
@@ -3385,8 +3691,8 @@ cross_db_copy(svn_wc__db_wcroot_t *src_w
               svn_wc__db_wcroot_t *dst_wcroot,
               const char *dst_relpath,
               svn_wc__db_status_t dst_status,
-              apr_int64_t dst_op_depth,
-              apr_int64_t dst_np_op_depth,
+              int dst_op_depth,
+              int dst_np_op_depth,
               svn_kind_t kind,
               const apr_array_header_t *children,
               apr_int64_t copyfrom_id,
@@ -3456,7 +3762,6 @@ get_info_for_copy(apr_int64_t *copyfrom_
                   svn_wc__db_status_t *status,
                   svn_kind_t *kind,
                   svn_boolean_t *op_root,
-                  svn_boolean_t *have_work,
                   svn_wc__db_wcroot_t *wcroot,
                   const char *local_relpath,
                   apr_pool_t *result_pool,
@@ -3471,7 +3776,7 @@ get_info_for_copy(apr_int64_t *copyfrom_
                     NULL, NULL, NULL, NULL, NULL, op_root, NULL, NULL,
                     NULL /* have_base */,
                     NULL /* have_more_work */,
-                    have_work,
+                    NULL /* have_work */,
                     wcroot, local_relpath, result_pool, scratch_pool));
 
   if (node_status == svn_wc__db_status_excluded)
@@ -3483,7 +3788,7 @@ get_info_for_copy(apr_int64_t *copyfrom_
       svn_dirent_split(&parent_relpath, &base_name, local_relpath,
                        scratch_pool);
       SVN_ERR(get_info_for_copy(copyfrom_id, copyfrom_relpath, copyfrom_rev,
-                                NULL, NULL, NULL, NULL,
+                                NULL, NULL, NULL,
                                 wcroot, parent_relpath,
                                 scratch_pool, scratch_pool));
       if (*copyfrom_relpath)
@@ -3564,13 +3869,13 @@ get_info_for_copy(apr_int64_t *copyfrom_
    ### these are just to avoid churn. a future commit should shuffle the
    ### functions around.  */
 static svn_error_t *
-op_depth_of(apr_int64_t *op_depth,
+op_depth_of(int *op_depth,
             svn_wc__db_wcroot_t *wcroot,
             const char *local_relpath);
 
 static svn_error_t *
-op_depth_for_copy(apr_int64_t *op_depth,
-                  apr_int64_t *np_op_depth,
+op_depth_for_copy(int *op_depth,
+                  int *np_op_depth,
                   apr_int64_t copyfrom_repos_id,
                   const char *copyfrom_relpath,
                   svn_revnum_t copyfrom_revision,
@@ -3595,15 +3900,14 @@ db_op_copy(svn_wc__db_wcroot_t *src_wcro
   svn_wc__db_status_t status;
   svn_wc__db_status_t dst_presence;
   svn_boolean_t op_root;
-  svn_boolean_t have_work;
   apr_int64_t copyfrom_id;
-  apr_int64_t dst_op_depth;
-  apr_int64_t dst_np_op_depth;
+  int dst_op_depth;
+  int dst_np_op_depth;
   svn_kind_t kind;
   const apr_array_header_t *children;
 
   SVN_ERR(get_info_for_copy(&copyfrom_id, &copyfrom_relpath, &copyfrom_rev,
-                            &status, &kind, &op_root, &have_work, src_wcroot,
+                            &status, &kind, &op_root, src_wcroot,
                             src_relpath, scratch_pool, scratch_pool));
 
   SVN_ERR(op_depth_for_copy(&dst_op_depth, &dst_np_op_depth, copyfrom_id,
@@ -3683,7 +3987,7 @@ db_op_copy(svn_wc__db_wcroot_t *src_wcro
 
   if (kind == svn_kind_dir)
     {
-      apr_int64_t src_op_depth;
+      int src_op_depth;
 
       SVN_ERR(op_depth_of(&src_op_depth, src_wcroot, src_relpath));
       SVN_ERR(gather_repo_children(&children, src_wcroot, src_relpath,
@@ -3698,14 +4002,10 @@ db_op_copy(svn_wc__db_wcroot_t *src_wcro
       const char *dst_parent_relpath = svn_relpath_dirname(dst_relpath,
                                                            scratch_pool);
 
-      if (have_work)
-        SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb,
-                          STMT_INSERT_WORKING_NODE_COPY_FROM_WORKING));
-      else
-        SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb,
-                          STMT_INSERT_WORKING_NODE_COPY_FROM_BASE));
+      SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb,
+                                        STMT_INSERT_WORKING_NODE_COPY_FROM));
 
-      SVN_ERR(svn_sqlite__bindf(stmt, "issist",
+      SVN_ERR(svn_sqlite__bindf(stmt, "issdst",
                     src_wcroot->wc_id, src_relpath,
                     dst_relpath,
                     dst_op_depth,
@@ -3724,7 +4024,7 @@ db_op_copy(svn_wc__db_wcroot_t *src_wcro
                * Perform a normal copy operation in these cases. */
               if (!(status == svn_wc__db_status_added ||
                     (status == svn_wc__db_status_copied && op_root)))
-                SVN_ERR(svn_sqlite__bind_int64(stmt, 7, 1));
+                SVN_ERR(svn_sqlite__bind_int(stmt, 7, 1));
             }
           else
             {
@@ -3744,7 +4044,7 @@ db_op_copy(svn_wc__db_wcroot_t *src_wcro
               SVN_ERR(svn_sqlite__step(&have_row, info_stmt));
               SVN_ERR_ASSERT(have_row);
               if (svn_sqlite__column_boolean(info_stmt, 15))
-                SVN_ERR(svn_sqlite__bind_int64(stmt, 7, 1));
+                SVN_ERR(svn_sqlite__bind_int(stmt, 7, 1));
               SVN_ERR(svn_sqlite__reset(info_stmt));
             }
         }
@@ -3764,7 +4064,7 @@ db_op_copy(svn_wc__db_wcroot_t *src_wcro
 
           SVN_ERR(svn_sqlite__get_statement(&stmt, dst_wcroot->sdb,
                                             STMT_INSERT_NODE));
-          SVN_ERR(svn_sqlite__bindf(stmt, "isisisrtnt",
+          SVN_ERR(svn_sqlite__bindf(stmt, "isdsisrtnt",
                                     src_wcroot->wc_id, dst_relpath,
                                     dst_np_op_depth, dst_parent_relpath,
                                     copyfrom_id, copyfrom_relpath,
@@ -3888,11 +4188,11 @@ svn_wc__db_op_copy(svn_wc__db_t *db,
 static svn_error_t *
 db_op_copy_shadowed_layer(svn_wc__db_wcroot_t *src_wcroot,
                           const char *src_relpath,
-                          apr_int64_t src_op_depth,
+                          int src_op_depth,
                           svn_wc__db_wcroot_t *dst_wcroot,
                           const char *dst_relpath,
-                          apr_int64_t dst_op_depth,
-                          apr_int64_t del_op_depth,
+                          int dst_op_depth,
+                          int del_op_depth,
                           apr_int64_t repos_id,
                           const char *repos_relpath,
                           svn_revnum_t revision,
@@ -4007,25 +4307,19 @@ db_op_copy_shadowed_layer(svn_wc__db_wcr
   if (dst_presence == svn_wc__db_status_normal
       && src_wcroot == dst_wcroot) /* ### Remove limitation */
     {
-      if (src_op_depth > 0)
-        SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb,
+      SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb,
                              STMT_INSERT_WORKING_NODE_COPY_FROM_DEPTH));
-      else
-        SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb,
-                             STMT_INSERT_WORKING_NODE_COPY_FROM_BASE));
 
       /* Perhaps we should avoid setting moved_here to 0 and leave it
          null instead? */
-      SVN_ERR(svn_sqlite__bindf(stmt, "issisti",
+      SVN_ERR(svn_sqlite__bindf(stmt, "issdstdd",
                         src_wcroot->wc_id, src_relpath,
                         dst_relpath,
                         dst_op_depth,
                         svn_relpath_dirname(dst_relpath, iterpool),
                         presence_map, dst_presence,
-                        (apr_int64_t)(is_move ? 1 : 0)));
-
-      if (src_op_depth > 0)
-        SVN_ERR(svn_sqlite__bind_int64(stmt, 8, src_op_depth));
+                        (is_move ? 1 : 0),
+                        src_op_depth));
 
       SVN_ERR(svn_sqlite__step_done(stmt));
 
@@ -4101,9 +4395,9 @@ op_copy_shadowed_layer_txn(void * baton,
   struct op_copy_baton *ocb = baton;
   const char *src_parent_relpath;
   const char *dst_parent_relpath;
-  apr_int64_t src_op_depth;
-  apr_int64_t dst_op_depth;
-  apr_int64_t del_op_depth;
+  int src_op_depth;
+  int dst_op_depth;
+  int del_op_depth;
   const char *repos_relpath = NULL;
   apr_int64_t repos_id = INVALID_REPOS_ID;
   svn_revnum_t revision = SVN_INVALID_REVNUM;
@@ -4203,7 +4497,7 @@ svn_wc__db_op_copy_shadowed_layer(svn_wc
 
 /* Set *OP_DEPTH to the highest op depth of WCROOT:LOCAL_RELPATH. */
 static svn_error_t *
-op_depth_of(apr_int64_t *op_depth,
+op_depth_of(int *op_depth,
             svn_wc__db_wcroot_t *wcroot,
             const char *local_relpath)
 {
@@ -4215,7 +4509,7 @@ op_depth_of(apr_int64_t *op_depth,
   SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
   SVN_ERR_ASSERT(have_row);
-  *op_depth = svn_sqlite__column_int64(stmt, 0);
+  *op_depth = svn_sqlite__column_int(stmt, 0);
   SVN_ERR(svn_sqlite__reset(stmt));
 
   return SVN_NO_ERROR;
@@ -4235,7 +4529,7 @@ catch_copy_of_server_excluded(svn_wc__db
   const char *server_excluded_relpath;
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                    STMT_HAS_SERVER_EXCLUDED_NODES));
+                                    STMT_HAS_SERVER_EXCLUDED_DESCENDANTS));
   SVN_ERR(svn_sqlite__bindf(stmt, "is",
                             wcroot->wc_id,
                             local_relpath));
@@ -4269,8 +4563,8 @@ catch_copy_of_server_excluded(svn_wc__db
    *OP_DEPTH will be set to the proper op_depth for a new operation root.
  */
 static svn_error_t *
-op_depth_for_copy(apr_int64_t *op_depth,
-                  apr_int64_t *np_op_depth,
+op_depth_for_copy(int *op_depth,
+                  int *np_op_depth,
                   apr_int64_t copyfrom_repos_id,
                   const char *copyfrom_relpath,
                   svn_revnum_t copyfrom_revision,
@@ -4281,8 +4575,8 @@ op_depth_for_copy(apr_int64_t *op_depth,
   const char *parent_relpath, *name;
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
-  apr_int64_t incomplete_op_depth = -1;
-  apr_int64_t min_op_depth = 1; /* Never touch BASE */
+  int incomplete_op_depth = -1;
+  int min_op_depth = 1; /* Never touch BASE */
 
   *op_depth = relpath_depth(local_relpath);
   *np_op_depth = -1;
@@ -4299,7 +4593,7 @@ op_depth_for_copy(apr_int64_t *op_depth,
       svn_wc__db_status_t status = svn_sqlite__column_token(stmt, 1,
                                                             presence_map);
 
-      min_op_depth = svn_sqlite__column_int64(stmt, 0);
+      min_op_depth = svn_sqlite__column_int(stmt, 0);
       if (status == svn_wc__db_status_incomplete)
         incomplete_op_depth = min_op_depth;
     }
@@ -4312,7 +4606,7 @@ op_depth_for_copy(apr_int64_t *op_depth,
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
   if (have_row)
     {
-      apr_int64_t parent_op_depth = svn_sqlite__column_int64(stmt, 0);
+      int parent_op_depth = svn_sqlite__column_int(stmt, 0);
       svn_wc__db_status_t presence = svn_sqlite__column_token(stmt, 1,
                                                               presence_map);
 
@@ -4385,7 +4679,6 @@ svn_wc__db_op_copy_dir(svn_wc__db_t *db,
 #if 0
   SVN_ERR_ASSERT(children != NULL);
 #endif
-  SVN_ERR_ASSERT(conflict == NULL);  /* ### can't handle yet  */
 
   SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
                               local_abspath, scratch_pool, scratch_pool));
@@ -4421,6 +4714,7 @@ svn_wc__db_op_copy_dir(svn_wc__db_t *db,
   iwb.depth = depth;
 
   iwb.work_items = work_items;
+  iwb.conflict = conflict;
 
   SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath, insert_working_node, &iwb,
                               scratch_pool));
@@ -4442,6 +4736,8 @@ svn_wc__db_op_copy_file(svn_wc__db_t *db
                         const char *original_uuid,
                         svn_revnum_t original_revision,
                         const svn_checksum_t *checksum,
+                        svn_boolean_t update_actual_props,
+                        const apr_hash_t *new_actual_props,
                         svn_boolean_t is_move,
                         const svn_skel_t *conflict,
                         const svn_skel_t *work_items,
@@ -4460,7 +4756,6 @@ svn_wc__db_op_copy_file(svn_wc__db_t *db
                  || (original_repos_relpath && original_root_url
                      && original_uuid && checksum
                      && original_revision != SVN_INVALID_REVNUM));
-  SVN_ERR_ASSERT(conflict == NULL);  /* ### can't handle yet  */
 
   SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
                               local_abspath, scratch_pool, scratch_pool));
@@ -4494,7 +4789,14 @@ svn_wc__db_op_copy_file(svn_wc__db_t *db
 
   iwb.checksum = checksum;
 
+  if (update_actual_props)
+    {
+      iwb.update_actual_props = update_actual_props;
+      iwb.new_actual_props = new_actual_props;
+    }
+
   iwb.work_items = work_items;
+  iwb.conflict = conflict;
 
   SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath, insert_working_node, &iwb,
                               scratch_pool));
@@ -4529,7 +4831,6 @@ svn_wc__db_op_copy_symlink(svn_wc__db_t 
   /* ### any assertions for CHANGED_* ?  */
   /* ### any assertions for ORIGINAL_* ?  */
   SVN_ERR_ASSERT(target != NULL);
-  SVN_ERR_ASSERT(conflict == NULL);  /* ### can't handle yet  */
 
   SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
                               local_abspath, scratch_pool, scratch_pool));
@@ -4564,6 +4865,7 @@ svn_wc__db_op_copy_symlink(svn_wc__db_t 
   iwb.target = target;
 
   iwb.work_items = work_items;
+  iwb.conflict = conflict;
 
   SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath, insert_working_node, &iwb,
                               scratch_pool));
@@ -4724,8 +5026,7 @@ svn_wc__db_global_record_fileinfo(svn_wc
   rb.translated_size = translated_size;
   rb.last_mod_time = last_mod_time;
 
-  SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath, db_record_fileinfo, &rb,
-                              scratch_pool));
+  SVN_ERR(db_record_fileinfo(&rb, wcroot, local_relpath, scratch_pool));
 
   /* We *totally* monkeyed the entries. Toss 'em.  */
   SVN_ERR(flush_entries(wcroot, local_abspath, svn_depth_empty, scratch_pool));
@@ -4791,12 +5092,6 @@ set_props_txn(void *baton,
   struct set_props_baton_t *spb = baton;
   apr_hash_t *pristine_props;
 
-  /* ### we dunno what to do with CONFLICT yet.  */
-  SVN_ERR_ASSERT(spb->conflict == NULL);
-
-  /* First order of business: insert all the work items.  */
-  SVN_ERR(add_work_items(wcroot->sdb, spb->work_items, scratch_pool));
-
   /* Check if the props are modified. If no changes, then wipe out the
      ACTUAL props.  PRISTINE_PROPS==NULL means that any
      ACTUAL props are okay as provided, so go ahead and set them.  */
@@ -4823,6 +5118,11 @@ set_props_txn(void *baton,
       SVN_ERR(db_record_fileinfo(&rb, wcroot, local_relpath, scratch_pool));
     }
 
+  /* And finally.  */
+  SVN_ERR(add_work_items(wcroot->sdb, spb->work_items, scratch_pool));
+  if (spb->conflict)
+    SVN_ERR(mark_conflict(wcroot, local_relpath, spb->conflict, scratch_pool));
+
   return SVN_NO_ERROR;
 }
 
@@ -4979,17 +5279,29 @@ populate_targets_tree(svn_wc__db_wcroot_
           const char *changelist = APR_ARRAY_IDX(changelist_filter, i,
                                                  const char *);
 
-          SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, stmt_idx));
+          SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_INSERT_TARGET_WITH_CHANGELIST));
           SVN_ERR(svn_sqlite__bindf(stmt, "iss", wcroot->wc_id,
                                     local_relpath, changelist));
           SVN_ERR(svn_sqlite__update(&sub_affected, stmt));
 
+          /* If the root is matched by the changelist, we don't have to match
+             the children. As that tells us the root is a file */
+          if (!sub_affected && depth > svn_depth_empty)
+            {
+              SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, stmt_idx));
+              SVN_ERR(svn_sqlite__bindf(stmt, "iss", wcroot->wc_id,
+                                        local_relpath, changelist));
+              SVN_ERR(svn_sqlite__update(&sub_affected, stmt));
+            }
+
           affected_rows += sub_affected;
         }
     }
   else /* No changelist filtering */
     {
       int stmt_idx;
+      int sub_affected;
 
       switch (depth)
         {
@@ -5015,9 +5327,19 @@ populate_targets_tree(svn_wc__db_wcroot_
             break;
         }
 
-      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, stmt_idx));
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_INSERT_TARGET));
       SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
-      SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
+      SVN_ERR(svn_sqlite__update(&sub_affected, stmt));
+      affected_rows += sub_affected;
+
+      if (depth > svn_depth_empty)
+        {
+          SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, stmt_idx));
+          SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+          SVN_ERR(svn_sqlite__update(&sub_affected, stmt));
+          affected_rows += sub_affected;
+        }
     }
 
   /* Does the target exist? */
@@ -5085,17 +5407,24 @@ set_changelist_txn(void *baton,
                                 scb->changelist_filter, scratch_pool));
 
   /* Ensure we have actual nodes for our targets. */
-  SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb,
-                                      STMT_INSERT_ACTUAL_EMPTIES));
+  if (scb->new_changelist)
+    {
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_INSERT_ACTUAL_EMPTIES));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+    }
 
   /* Now create our notification table. */
   SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb,
                                       STMT_CREATE_CHANGELIST_LIST));
+  SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb,
+                                      STMT_CREATE_CHANGELIST_TRIGGER));
 
   /* Update our changelists. */
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                     STMT_UPDATE_ACTUAL_CHANGELISTS));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, scb->new_changelist));
+  SVN_ERR(svn_sqlite__bindf(stmt, "iss", wcroot->wc_id, local_relpath,
+                            scb->new_changelist));
   SVN_ERR(svn_sqlite__step_done(stmt));
 
   if (scb->new_changelist)
@@ -5103,7 +5432,8 @@ set_changelist_txn(void *baton,
       /* We have to notify that we skipped directories, so do that now. */
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                         STMT_MARK_SKIPPED_CHANGELIST_DIRS));
-      SVN_ERR(svn_sqlite__bind_text(stmt, 1, scb->new_changelist));
+      SVN_ERR(svn_sqlite__bindf(stmt, "iss", wcroot->wc_id, local_relpath,
+                                scb->new_changelist));
       SVN_ERR(svn_sqlite__step_done(stmt));
     }
 
@@ -5113,7 +5443,7 @@ set_changelist_txn(void *baton,
     {
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                         STMT_DELETE_ACTUAL_EMPTIES));
-      SVN_ERR(svn_sqlite__bind_int64(stmt, 1, wcroot->wc_id));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
       SVN_ERR(svn_sqlite__step_done(stmt));
     }
 
@@ -5151,7 +5481,14 @@ do_changelist_notify(void *baton,
       svn_pool_clear(iterpool);
 
       if (cancel_func)
-        SVN_ERR(cancel_func(cancel_baton));
+        {
+          svn_error_t *err = cancel_func(cancel_baton);
+
+          if (err)
+            return svn_error_trace(svn_error_compose_create(
+                                                    err,
+                                                    svn_sqlite__reset(stmt)));
+        }
 
       notify_abspath = svn_dirent_join(wcroot->abspath, notify_relpath,
                                        iterpool);
@@ -5181,8 +5518,11 @@ svn_wc__db_op_set_changelist(svn_wc__db_
 {
   svn_wc__db_wcroot_t *wcroot;
   const char *local_relpath;
-  struct set_changelist_baton_t scb = { new_changelist, changelist_filter,
-                                        depth };
+  struct set_changelist_baton_t scb;
+
+  scb.new_changelist = new_changelist;
+  scb.changelist_filter = changelist_filter;
+  scb.depth = depth;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
@@ -5206,158 +5546,461 @@ svn_wc__db_op_set_changelist(svn_wc__db_
                                            scratch_pool));
 }
 
-
-svn_error_t *
-svn_wc__db_op_mark_conflict(svn_wc__db_t *db,
-                            const char *local_abspath,
-                            apr_pool_t *scratch_pool)
-{
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-
-  NOT_IMPLEMENTED();
-}
-
-
-svn_error_t *
-svn_wc__db_op_mark_resolved(svn_wc__db_t *db,
-                            const char *local_abspath,
-                            svn_boolean_t resolved_text,
-                            svn_boolean_t resolved_props,
-                            svn_boolean_t resolved_tree,
-                            apr_pool_t *scratch_pool)
-{
-  svn_wc__db_wcroot_t *wcroot;
-  const char *local_relpath;
-  svn_sqlite__stmt_t *stmt;
-
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-
-  /* ### we're not ready to handy RESOLVED_TREE just yet.  */
-  SVN_ERR_ASSERT(!resolved_tree);
-
-  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
-                              local_abspath, scratch_pool, scratch_pool));
-  VERIFY_USABLE_WCROOT(wcroot);
-
-  /* ### these two statements are not transacted together. is this a
-     ### problem? I suspect a failure simply leaves the other in a
-     ### continued, unresolved state. However, that still retains
-     ### "integrity", so another re-run by the user will fix it.  */
-
-  if (resolved_text)
-    {
-      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                        STMT_CLEAR_TEXT_CONFLICT));
-      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
-      SVN_ERR(svn_sqlite__step_done(stmt));
-    }
-  if (resolved_props)
-    {
-      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                        STMT_CLEAR_PROPS_CONFLICT));
-      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
-      SVN_ERR(svn_sqlite__step_done(stmt));
-    }
-
-  /* Some entries have cached the above values. Kapow!!  */
-  SVN_ERR(flush_entries(wcroot, local_abspath, svn_depth_empty, scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-
-/* */
+/* Implementation of svn_wc__db_op_mark_conflict() */
 static svn_error_t *
-set_tc_txn(void *baton,
-           svn_wc__db_wcroot_t *wcroot,
-           const char *local_relpath,
-           apr_pool_t *scratch_pool)
+mark_conflict(svn_wc__db_wcroot_t *wcroot,
+              const char *local_relpath,
+              const svn_skel_t *conflict_skel,
+              apr_pool_t *scratch_pool)
 {
-  const svn_wc_conflict_description2_t *tree_conflict = baton;
-  const char *parent_relpath;
   svn_sqlite__stmt_t *stmt;
-  svn_boolean_t have_row;
-  const char *tree_conflict_data;
+  svn_boolean_t got_row;
+  svn_boolean_t is_complete;
+#if defined(SVN_DEBUG) && (SVN_WC__VERSION < SVN_WC__USES_CONFLICT_SKELS)
+  svn_boolean_t had_text_conflict;
+  svn_boolean_t had_prop_conflict;
+  svn_boolean_t had_tree_conflict;
+#endif
 
-  /* ### does this work correctly? */
-  parent_relpath = svn_relpath_dirname(local_relpath, scratch_pool);
+  SVN_ERR(svn_wc__conflict_skel_is_complete(&is_complete, conflict_skel));
+  SVN_ERR_ASSERT(is_complete);
 
-  /* Get existing conflict information for LOCAL_RELPATH. */
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                     STMT_SELECT_ACTUAL_NODE));
   SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
-  SVN_ERR(svn_sqlite__step(&have_row, stmt));
-  SVN_ERR(svn_sqlite__reset(stmt));
+  SVN_ERR(svn_sqlite__step(&got_row, stmt));
 
-  if (tree_conflict)
+#if defined(SVN_DEBUG) && (SVN_WC__VERSION < SVN_WC__USES_CONFLICT_SKELS)
+  if (got_row)
     {
-      svn_skel_t *skel;
-
-      SVN_ERR(svn_wc__serialize_conflict(&skel, tree_conflict,
-                                         scratch_pool, scratch_pool));
-      tree_conflict_data = svn_skel__unparse(skel, scratch_pool)->data;
+      had_text_conflict = (!svn_sqlite__column_is_null(stmt, 3)
+                           || !svn_sqlite__column_is_null(stmt, 4)
+                           || !svn_sqlite__column_is_null(stmt, 5));
+      had_prop_conflict = !svn_sqlite__column_is_null(stmt, 6);
+      had_tree_conflict = !svn_sqlite__column_is_null(stmt, 7);
     }
   else
-    tree_conflict_data = NULL;
+    {
+      had_text_conflict = FALSE;
+      had_prop_conflict = FALSE;
+      had_tree_conflict = FALSE;
+    }
+#endif
+  SVN_ERR(svn_sqlite__reset(stmt));
 
-  if (have_row)
+  if (got_row)
     {
-      /* There is an existing ACTUAL row, so just update it. */
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                        STMT_UPDATE_ACTUAL_TREE_CONFLICTS));
+                                        STMT_UPDATE_ACTUAL_CONFLICT));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
     }
   else
     {
-      /* We need to insert an ACTUAL row with the tree conflict data. */
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                        STMT_INSERT_ACTUAL_TREE_CONFLICTS));
+                                        STMT_INSERT_ACTUAL_CONFLICT));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      if (*local_relpath != '\0')
+        SVN_ERR(svn_sqlite__bind_text(stmt, 9,
+                                      svn_relpath_dirname(local_relpath,
+                                                          scratch_pool)));
     }
 
-  SVN_ERR(svn_sqlite__bindf(stmt, "iss", wcroot->wc_id, local_relpath,
-                            tree_conflict_data));
-  if (!have_row)
-    SVN_ERR(svn_sqlite__bind_text(stmt, 4, parent_relpath));
-
-  SVN_ERR(svn_sqlite__step_done(stmt));
-
-  /* Now, remove the actual node if it doesn't have any more useful
-     information.  We only need to do this if we've remove data ourselves. */
-  if (!tree_conflict_data)
+#if SVN_WC__VERSION < SVN_WC__USES_CONFLICT_SKELS
     {
-      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                        STMT_DELETE_ACTUAL_EMPTY));
-      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
-      SVN_ERR(svn_sqlite__step_done(stmt));
-    }
+      /* Store conflict data in the old locations */
+      svn_boolean_t text_conflict;
+      svn_boolean_t prop_conflict;
+      svn_boolean_t tree_conflict;
+      const apr_array_header_t *locations;
+      svn_wc_operation_t operation;
 
-  return SVN_NO_ERROR;
-}
+      svn_wc__db_t *db;
+      const char *local_abspath;
 
+      /* Ugly but temporary hack: obtain a DB for transforming paths.
+         ### Can't use this for a write tranaction or we get a deadlock! */
 
-svn_error_t *
-svn_wc__db_op_set_tree_conflict(svn_wc__db_t *db,
-                                const char *local_abspath,
-                                const svn_wc_conflict_description2_t *tree_conflict,
-                                apr_pool_t *scratch_pool)
-{
-  svn_wc__db_wcroot_t *wcroot;
-  const char *local_relpath;
+      SVN_ERR(svn_wc__db_open(&db, NULL, FALSE, FALSE,
+                              scratch_pool, scratch_pool));
 
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+      local_abspath = svn_dirent_join(wcroot->abspath, local_relpath,
+                                      scratch_pool);
 
-  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath,
-                              db, local_abspath, scratch_pool, scratch_pool));
-  VERIFY_USABLE_WCROOT(wcroot);
+      SVN_ERR(svn_wc__conflict_read_info(&operation, &locations,
+                                         &text_conflict, &prop_conflict,
+                                         &tree_conflict,
+                                         db, local_abspath, conflict_skel,
+                                         scratch_pool, scratch_pool));
 
-  SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath, set_tc_txn,
-                              (void *) tree_conflict, scratch_pool));
+#ifdef SVN_DEBUG
+      /* This function should only ADD conflicts */
+      SVN_ERR_ASSERT(text_conflict || !had_text_conflict);
+      SVN_ERR_ASSERT(prop_conflict || !had_prop_conflict);
+      SVN_ERR_ASSERT(tree_conflict || !had_tree_conflict);
+#endif
 
-  /* There may be some entries, and the conflict info is now out of date.  */
-  SVN_ERR(flush_entries(wcroot, local_abspath, svn_depth_empty, scratch_pool));
+      if (text_conflict)
+        {
+          const char *mine_path;
+          const char *their_old_path;
+          const char *their_path;
+
+          SVN_ERR(svn_wc__conflict_read_text_conflict(&mine_path,
+                                                      &their_old_path,
+                                                      &their_path,
+                                                      db, local_abspath,
+                                                      conflict_skel,
+                                                      scratch_pool,
+                                                      scratch_pool));
 
-  return SVN_NO_ERROR;
-}
+          if (their_old_path)
+            {
+              their_old_path = svn_dirent_skip_ancestor(wcroot->abspath,
+                                                        their_old_path);
+              SVN_ERR(svn_sqlite__bind_text(stmt, 4, their_old_path));
+            }
 
+          if (their_path)
+            {
+              their_path = svn_dirent_skip_ancestor(wcroot->abspath,
+                                                    their_path);
+              SVN_ERR(svn_sqlite__bind_text(stmt, 5, their_path));
+            }
+
+          if (mine_path)
+            {
+              mine_path = svn_dirent_skip_ancestor(wcroot->abspath, mine_path);
+              SVN_ERR(svn_sqlite__bind_text(stmt, 6, mine_path));
+            }
+        }
+
+      if (prop_conflict)
+        {
+          const char *prej_path;
+
+          SVN_ERR(svn_wc__conflict_read_prop_conflict(&prej_path, NULL,
+                                                      NULL, NULL, NULL,
+                                                      db, local_abspath,
+                                                      conflict_skel,
+                                                      scratch_pool, scratch_pool));
+
+          if (prej_path)
+            {
+              prej_path = svn_dirent_skip_ancestor(wcroot->abspath, prej_path);
+              SVN_ERR(svn_sqlite__bind_text(stmt, 7, prej_path));
+            }
+        }
+
+      if (tree_conflict)
+        {
+          svn_wc_conflict_description2_t *desc;
+          svn_wc_conflict_version_t *v1;
+          svn_wc_conflict_version_t *v2;
+          svn_node_kind_t tc_kind;
+          svn_skel_t *skel;
+          svn_wc_conflict_reason_t local_change;
+          svn_wc_conflict_action_t incoming_change;
+
+          SVN_ERR(svn_wc__conflict_read_tree_conflict(&local_change,
+                                                      &incoming_change,
+                                                      db, local_abspath,
+                                                      conflict_skel,
+                                                      scratch_pool, scratch_pool));
+
+
+          v1 = (locations && locations->nelts > 0)
+                    ? APR_ARRAY_IDX(locations, 0, svn_wc_conflict_version_t *)
+                    : NULL;
+
+          v2 = (locations && locations->nelts > 1)
+                    ? APR_ARRAY_IDX(locations, 1, svn_wc_conflict_version_t *)
+                    : NULL;
+
+          if (incoming_change != svn_wc_conflict_action_delete
+              && (operation == svn_wc_operation_update
+                  || operation == svn_wc_operation_switch))
+            {
+              svn_wc__db_status_t status;
+              svn_revnum_t revision;
+              const char *repos_relpath;
+              apr_int64_t repos_id;
+              svn_kind_t kind;
+              svn_error_t *err;
+
+              /* ### Theoretically we should just fetch the BASE information
+                     here. This code might need tweaks until all tree conflicts
+                     are installed in the proper state */
+
+              SVN_ERR_ASSERT(v2 == NULL); /* Not set for update and switch */
+
+              /* With an update or switch we have to fetch the second location
+                 for a tree conflict from WORKING. (For text or prop from BASE)
+               */
+              err = base_get_info(&status, &kind, &revision,
+                                  &repos_relpath, &repos_id, NULL, NULL, NULL,
+                                  NULL, NULL, NULL, NULL, NULL, NULL,
+                                  wcroot, local_relpath,
+                                  scratch_pool, scratch_pool);
+
+              if (err)
+                {
+                  if (err && err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+                    return svn_error_trace(err);
+
+                  svn_error_clear(err);
+                  /* Ignore BASE */
+
+                  tc_kind = svn_node_file; /* Avoid assertion */
+                }
+              else if (repos_relpath)
+                {
+                  const char *repos_root_url;
+                  const char *repos_uuid;
+
+                  SVN_ERR(fetch_repos_info(&repos_root_url, &repos_uuid,
+                                           wcroot->sdb, repos_id,
+                                           scratch_pool));
+
+                  v2 = svn_wc_conflict_version_create2(repos_root_url,
+                                                       repos_uuid,
+                                                       repos_relpath,
+                                                       revision,
+                                                svn__node_kind_from_kind(kind),
+                                                       scratch_pool);
+                  tc_kind = svn__node_kind_from_kind(kind);
+                }
+              else
+                tc_kind = svn_node_file; /* Avoid assertion */
+            }
+          else
+            {
+              if (v1)
+                tc_kind = v1->node_kind;
+              else if (v2)
+                tc_kind = v2->node_kind;
+              else
+                tc_kind = svn_node_file; /* Avoid assertion */
+            }
+
+          desc = svn_wc_conflict_description_create_tree2(local_abspath,
+                                                          tc_kind,
+                                                          operation,
+                                                          v1, v2,
+                                                          scratch_pool);
+          desc->reason = local_change;
+          desc->action = incoming_change;
+
+          SVN_ERR(svn_wc__serialize_conflict(&skel, desc,
+                                             scratch_pool, scratch_pool));
+
+          SVN_ERR(svn_sqlite__bind_text(stmt, 8,
+                        svn_skel__unparse(skel, scratch_pool)->data));
+        }
+      SVN_ERR(svn_wc__db_close(db));
+    }
+#else
+  /* And in the new location */
+  {
+    svn_stringbuf_t *sb = svn_skel__unparse(conflict_skel, scratch_pool);
+
+    SVN_ERR(svn_sqlite__bind_blob(stmt, 3, sb->data, sb->len));
+  }
+#endif
+  SVN_ERR(svn_sqlite__update(NULL, stmt));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__db_op_mark_conflict(svn_wc__db_t *db,
+                            const char *local_abspath,
+                            const svn_skel_t *conflict_skel,
+                            const svn_skel_t *work_items,
+                            apr_pool_t *scratch_pool)
+{
+  svn_wc__db_wcroot_t *wcroot;
+  const char *local_relpath;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+
+  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
+                              local_abspath, scratch_pool, scratch_pool));
+  VERIFY_USABLE_WCROOT(wcroot);
+
+  SVN_ERR(mark_conflict(wcroot, local_relpath, conflict_skel, scratch_pool));
+
+  /* ### Should be handled in the same transaction as setting the conflict */
+  if (work_items)
+    SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
+
+  SVN_ERR(flush_entries(wcroot, local_abspath, svn_depth_empty, scratch_pool));
+
+  return SVN_NO_ERROR;
+
+}
+
+/* Baton for db_op_mark_resolved */
+struct op_mark_resolved_baton
+{
+  svn_boolean_t resolved_text;
+  svn_boolean_t resolved_props;
+  svn_boolean_t resolved_tree;
+  const svn_skel_t *work_items;
+#if SVN_WC__VERSION >= SVN_WC__USES_CONFLICT_SKELS
+  svn_wc__db_t *db;
+#endif
+};
+
+/* Helper for svn_wc__db_op_mark_resolved */
+static svn_error_t *
+db_op_mark_resolved(void *baton,
+                   svn_wc__db_wcroot_t *wcroot,
+                   const char *local_relpath,
+                   apr_pool_t *scratch_pool)
+{
+  struct op_mark_resolved_baton *rb = baton;
+  svn_sqlite__stmt_t *stmt;
+  svn_boolean_t have_row;
+  int total_affected_rows = 0;
+#if SVN_WC__VERSION < SVN_WC__USES_CONFLICT_SKELS
+  int affected_rows;
+#else
+  svn_boolean_t resolved_all;
+  apr_size_t conflict_len;
+  const void *conflict_data;
+  svn_skel_t *conflicts;
+#endif
+
+  /* Check if we have a conflict in ACTUAL */
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_SELECT_ACTUAL_NODE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+
+  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+  if (! have_row)
+    {
+      SVN_ERR(svn_sqlite__reset(stmt));
+
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_SELECT_NODE_INFO));
+
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+
+      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+      SVN_ERR(svn_sqlite__reset(stmt));
+
+      if (have_row)
+        return SVN_NO_ERROR;
+
+      return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+                               _("The node '%s' was not found."),
+                                   path_for_error_message(wcroot,
+                                                          local_relpath,
+                                                          scratch_pool));
+    }
+
+#if SVN_WC__VERSION < SVN_WC__USES_CONFLICT_SKELS
+  SVN_ERR(svn_sqlite__reset(stmt));
+  if (rb->resolved_text)
+    {
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_CLEAR_TEXT_CONFLICT));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
+      total_affected_rows += affected_rows;
+    }
+  if (rb->resolved_props)
+    {
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_CLEAR_PROPS_CONFLICT));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
+      total_affected_rows += affected_rows;
+    }
+  if (rb->resolved_tree)
+    {
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_CLEAR_TREE_CONFLICT));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
+      total_affected_rows += affected_rows;
+    }
+#else
+  conflict_data = svn_sqlite__column_blob(stmt, 2, &conflict_len,
+                                          scratch_pool);
+  conflicts = svn_skel__parse(conflict_data, conflict_len, scratch_pool);
+  SVN_ERR(svn_sqlite__reset(stmt));
+
+  SVN_ERR(svn_wc__conflict_skel_resolve(&resolved_all, conflicts,
+                                        rb->db, wcroot->abspath,
+                                        rb->resolved_text,
+                                        rb->resolved_props ? "" : NULL,
+                                        rb->resolved_tree,
+                                        scratch_pool, scratch_pool));
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_UPDATE_ACTUAL_CONFLICT));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+
+  if (! resolved_all)
+    {
+      svn_stringbuf_t *sb = svn_skel__unparse(conflicts, scratch_pool);
+
+      SVN_ERR(svn_sqlite__bind_blob(stmt, 3, sb->data, sb->len));
+    }
+
+  SVN_ERR(svn_sqlite__update(&total_affected_rows, stmt));
+#endif
+
+  /* Now, remove the actual node if it doesn't have any more useful
+     information.  We only need to do this if we've remove data ourselves. */
+  if (total_affected_rows > 0)
+    {
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_DELETE_ACTUAL_EMPTY));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+    }
+
+  SVN_ERR(add_work_items(wcroot->sdb, rb->work_items, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__db_op_mark_resolved(svn_wc__db_t *db,
+                            const char *local_abspath,
+                            svn_boolean_t resolved_text,
+                            svn_boolean_t resolved_props,
+                            svn_boolean_t resolved_tree,
+                            const svn_skel_t *work_items,
+                            apr_pool_t *scratch_pool)
+{
+  svn_wc__db_wcroot_t *wcroot;
+  const char *local_relpath;
+  struct op_mark_resolved_baton rb;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+
+  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
+                              local_abspath, scratch_pool, scratch_pool));
+  VERIFY_USABLE_WCROOT(wcroot);
+
+  rb.resolved_props = resolved_props;
+  rb.resolved_text = resolved_text;
+  rb.resolved_tree = resolved_tree;
+  rb.work_items = work_items;
+#if SVN_WC__VERSION >= SVN_WC__USES_CONFLICT_SKELS
+  rb.db = db;
+#endif
+
+  SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath, db_op_mark_resolved,
+                              &rb, scratch_pool));
+
+  SVN_ERR(flush_entries(wcroot, local_abspath, svn_depth_empty, scratch_pool));
+  return SVN_NO_ERROR;
+}
 
 /* Clear moved-to information at the delete-half of the move which
  * moved LOCAL_RELPATH here. This transforms the move into a simple delete. */
@@ -5401,7 +6044,7 @@ op_revert_txn(void *baton,
 {
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
-  apr_int64_t op_depth;
+  int op_depth;
   svn_boolean_t moved_here;
   int affected_rows;
 
@@ -5447,7 +6090,7 @@ op_revert_txn(void *baton,
                                                       scratch_pool));
     }
 
-  op_depth = svn_sqlite__column_int64(stmt, 0);
+  op_depth = svn_sqlite__column_int(stmt, 0);
   moved_here = svn_sqlite__column_boolean(stmt, 15);
   SVN_ERR(svn_sqlite__reset(stmt));
 
@@ -5456,7 +6099,7 @@ op_revert_txn(void *baton,
       /* Can't do non-recursive revert if children exist */
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                         STMT_SELECT_GE_OP_DEPTH_CHILDREN));
-      SVN_ERR(svn_sqlite__bindf(stmt, "isi", wcroot->wc_id,
+      SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
                                 local_relpath, op_depth));
       SVN_ERR(svn_sqlite__step(&have_row, stmt));
       SVN_ERR(svn_sqlite__reset(stmt));
@@ -5472,7 +6115,7 @@ op_revert_txn(void *baton,
          direct children into roots of deletes. */
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                      STMT_UPDATE_OP_DEPTH_INCREASE_RECURSIVE));
-      SVN_ERR(svn_sqlite__bindf(stmt, "isi", wcroot->wc_id,
+      SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
                                 local_relpath,
                                 op_depth));
       SVN_ERR(svn_sqlite__step_done(stmt));
@@ -5518,8 +6161,8 @@ op_revert_recursive_txn(void *baton,
 {
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
-  apr_int64_t op_depth;
-  apr_int64_t select_op_depth;
+  int op_depth;
+  int select_op_depth;
   svn_boolean_t moved_here;
   int affected_rows;
   apr_pool_t *iterpool;
@@ -5536,10 +6179,10 @@ op_revert_recursive_txn(void *baton,
       SVN_ERR(svn_sqlite__reset(stmt));
 
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                        STMT_DELETE_ACTUAL_NODE_RECURSIVE));
+                                        STMT_DELETE_ACTUAL_NODE));
       SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id,

[... 3043 lines stripped ...]