You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/08/11 18:43:31 UTC

svn commit: r984468 [17/25] - in /subversion/branches/ignore-mergeinfo: ./ build/ build/generator/ build/generator/templates/ notes/ notes/tree-conflicts/ notes/wc-ng/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subvers...

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc_db.h?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc_db.h Wed Aug 11 16:43:22 2010
@@ -347,13 +347,17 @@ svn_wc__db_close(svn_wc__db_t *db);
    A REPOSITORY row will be constructed for the repository identified by
    REPOS_ROOT_URL and REPOS_UUID. Neither of these may be NULL.
 
-   A node will be created for the directory at REPOS_RELPATH will be added.
+   A BASE_NODE row will be created for the directory at REPOS_RELPATH at
+   revision INITIAL_REV.
    If INITIAL_REV is greater than zero, then the node will be marked as
    "incomplete" because we don't know its children. Contrary, if the
    INITIAL_REV is zero, then this directory should represent the root and
    we know it has no children, so the node is complete.
 
-   DEPTH is the initial depth of the working copy, it must be a definite
+   ### Is there any benefit to marking it 'complete' if rev==0?  Seems like
+   ### an unnecessary special case.
+
+   DEPTH is the initial depth of the working copy; it must be a definite
    depth, not svn_depth_unknown.
 
    Use SCRATCH_POOL for temporary allocations.
@@ -413,6 +417,15 @@ svn_wc__db_from_relpath(const char **loc
                         apr_pool_t *result_pool,
                         apr_pool_t *scratch_pool);
 
+/* Compute the working copy root WCROOT_ABSPATH for WRI_ABSPATH using DB.
+ */
+svn_error_t *
+svn_wc__db_get_wcroot(const char **wcroot_abspath,
+                      svn_wc__db_t *db,
+                      const char *wri_abspath,
+                      apr_pool_t *result_pool,
+                      apr_pool_t *scratch_pool);
+
 /* @} */
 
 /* Different kinds of trees
@@ -455,6 +468,9 @@ svn_wc__db_from_relpath(const char **loc
    This subsystem does not use DEPTH, but it can be recorded here in
    the BASE tree for higher-level code to use.
 
+   If DAV_CACHE is not NULL, sets LOCAL_ABSPATH's dav cache to the specified
+   data.
+
    If CONFLICT is not NULL, then it describes a conflict for this node. The
    node will be record as conflicted (in ACTUAL).
 
@@ -476,6 +492,7 @@ svn_wc__db_base_add_directory(svn_wc__db
                               const char *changed_author,
                               const apr_array_header_t *children,
                               svn_depth_t depth,
+                              apr_hash_t *dav_cache,
                               const svn_skel_t *conflict,
                               const svn_skel_t *work_items,
                               apr_pool_t *scratch_pool);
@@ -500,6 +517,9 @@ svn_wc__db_base_add_directory(svn_wc__db
    by its properties) is known, then pass it as TRANSLATED_SIZE. Otherwise,
    pass SVN_INVALID_FILESIZE.
 
+   If DAV_CACHE is not NULL, sets LOCAL_ABSPATH's dav cache to the specified
+   data.
+
    If CONFLICT is not NULL, then it describes a conflict for this node. The
    node will be record as conflicted (in ACTUAL).
 
@@ -521,6 +541,7 @@ svn_wc__db_base_add_file(svn_wc__db_t *d
                          const char *changed_author,
                          const svn_checksum_t *checksum,
                          svn_filesize_t translated_size,
+                         apr_hash_t *dav_cache,
                          const svn_skel_t *conflict,
                          const svn_skel_t *work_items,
                          apr_pool_t *scratch_pool);
@@ -540,6 +561,9 @@ svn_wc__db_base_add_file(svn_wc__db_t *d
 
    The target of the symlink is specified by TARGET.
 
+   If DAV_CACHE is not NULL, sets LOCAL_ABSPATH's dav cache to the specified
+   data.
+
    If CONFLICT is not NULL, then it describes a conflict for this node. The
    node will be record as conflicted (in ACTUAL).
 
@@ -588,6 +612,7 @@ svn_wc__db_base_add_symlink(svn_wc__db_t
                             apr_time_t changed_date,
                             const char *changed_author,
                             const char *target,
+                            apr_hash_t *dav_cache,
                             const svn_skel_t *conflict,
                             const svn_skel_t *work_items,
                             apr_pool_t *scratch_pool);
@@ -836,53 +861,6 @@ svn_wc__db_base_clear_dav_cache_recursiv
    @{
 */
 
-/* Enumerated constants for how hard svn_wc__db_pristine_check() should
-   work on checking for the pristine file.
-*/
-typedef enum {
-
-  /* ### bah. this is bogus. we open the sqlite database "all the time",
-     ### and don't worry about optimizing that. so: given the db is always
-     ### open, then the following modes are overengineered, premature
-     ### optimizations. ... will clean up in a future rev.  */
-
-  /* The caller wants to be sure the pristine file is present and usable.
-     This is the typical mode to use.
-
-     Implementation note: the SQLite database is opened (if not already)
-       and its state is verified against the file in the filesystem. */
-  svn_wc__db_checkmode_usable,
-
-  /* The caller is performing just this one check. The implementation will
-     optimize around the assumption no further calls to _check() will occur
-     (but of course has no problem if they do).
-
-     Note: this test is best used for detecting a *missing* file
-     rather than for detecting a usable file.
-
-     Implementation note: this will examine the presence of the pristine file
-       in the filesystem. The SQLite database is untouched, though if it is
-       (already) open, then it will be used instead. */
-  svn_wc__db_checkmode_single,
-
-  /* The caller is going to perform multiple calls, so the implementation
-     should optimize its operation around that.
-
-     Note: this test is best used for detecting a *missing* file
-     rather than for detecting a usable file.
-
-     Implementation note: the SQLite database will be opened (if not already),
-     and all checks will simply look in the TEXT_BASE table to see if the
-     given key is present. Note that the file may not be present. */
-  svn_wc__db_checkmode_multi,
-
-  /* Similar to _usable, but the file is checksum'd to ensure that it has
-     not been corrupted in some way. */
-  svn_wc__db_checkmode_validate
-
-} svn_wc__db_checkmode_t;
-
-
 /* Set *PRISTINE_ABSPATH to the path to the pristine text file
    identified by SHA1_CHECKSUM.  Error if it does not exist.
 
@@ -1002,15 +980,14 @@ svn_wc__db_pristine_cleanup(svn_wc__db_t
                             apr_pool_t *scratch_pool);
 
 
-/* ### check for presence, according to the given mode (on how hard we
-   ### should examine things)
+/* Set *PRESENT to true if the pristine store for WRI_ABSPATH in DB contains
+   a pristine text with SHA-1 checksum SHA1_CHECKSUM, and to false otherwise.
 */
 svn_error_t *
 svn_wc__db_pristine_check(svn_boolean_t *present,
                           svn_wc__db_t *db,
                           const char *wri_abspath,
                           const svn_checksum_t *sha1_checksum,
-                          svn_wc__db_checkmode_t mode,
                           apr_pool_t *scratch_pool);
 
 
@@ -1190,6 +1167,8 @@ svn_wc__db_op_set_props(svn_wc__db_t *db
                         const svn_skel_t *work_items,
                         apr_pool_t *scratch_pool);
 
+/* See props.h  */
+#ifdef SVN__SUPPORT_BASE_MERGE
 /* ### Set the properties of the node LOCAL_ABSPATH in the BASE tree to PROPS.
    ###
    ### This function should not exist because properties should be stored
@@ -1222,7 +1201,7 @@ svn_wc__db_temp_working_set_props(svn_wc
                                   const char *local_abspath,
                                   const apr_hash_t *props,
                                   apr_pool_t *scratch_pool);
-
+#endif
 
 /* ### KFF: This handles files, dirs, symlinks, anything else? */
 /* ### dlr: Does this support recursive dir deletes (e.g. _revert)? Document. */
@@ -1715,10 +1694,14 @@ svn_wc__db_global_relocate(svn_wc__db_t 
    the commit. It will become the BASE node's 'revnum' and 'changed_rev'
    values in the BASE_NODE table.
 
-   NEW_DATE is the (server-side) date of the new revision. It may be 0 if
+   CHANGED_REVISION is the the new 'last changed' revision. If the node is
+   modified its value is equivalent to NEW_REVISION, but in case of a
+   decendant of a copy/move it can be an older revision.
+
+   CHANGED_DATE is the (server-side) date of CHANGED_REVISION. It may be 0 if
    the revprop is missing on the revision.
 
-   NEW_AUTHOR is the (server-side) author of the new revision. It may be
+   CHANGED_AUTHOR is the (server-side) author of CHANGED_REVISION. It may be
    NULL if the revprop is missing on the revision.
 
    One or both of NEW_CHECKSUM and NEW_CHILDREN should be NULL. For new:
@@ -1732,8 +1715,9 @@ svn_error_t *
 svn_wc__db_global_commit(svn_wc__db_t *db,
                          const char *local_abspath,
                          svn_revnum_t new_revision,
-                         apr_time_t new_date,
-                         const char *new_author,
+                         svn_revnum_t changed_revision,
+                         apr_time_t changed_date,
+                         const char *changed_author,
                          const svn_checksum_t *new_checksum,
                          const apr_array_header_t *new_children,
                          apr_hash_t *new_dav_cache,
@@ -2082,6 +2066,7 @@ svn_wc__db_upgrade_apply_dav_cache(svn_s
 */
 svn_error_t *
 svn_wc__db_upgrade_apply_props(svn_sqlite__db_t *sdb,
+                               const char *dir_abspath,
                                const char *local_relpath,
                                apr_hash_t *base_props,
                                apr_hash_t *revert_props,
@@ -2168,23 +2153,39 @@ svn_wc__db_wq_completed(svn_wc__db_t *db
    that they still function correctly, even in the new world.  'levels to
    lock' should not be exposed through the wc-ng APIs at all: users either
    get to lock the entire tree (rooted at some subdir, of course), or none.
+
+   An infinite depth lock is obtained with LEVELS_TO_LOCK set to -1, but until
+   we move to a single DB only depth 0 is supported.
 */
 svn_error_t *
-svn_wc__db_wclock_set(svn_wc__db_t *db,
-                      const char *local_abspath,
-                      int levels_to_lock,
-                      apr_pool_t *scratch_pool);
+svn_wc__db_wclock_obtain(svn_wc__db_t *db,
+                         const char *local_abspath,
+                         int levels_to_lock,
+                         svn_boolean_t steal_lock,
+                         apr_pool_t *scratch_pool);
 
+/* Check if somebody has a wclock on LOCAL_ABSPATH */
 svn_error_t *
 svn_wc__db_wclocked(svn_boolean_t *locked,
                     svn_wc__db_t *db,
                     const char *local_abspath,
                     apr_pool_t *scratch_pool);
 
+/* Release the previously obtained lock on LOCAL_ABSPATH */
 svn_error_t *
-svn_wc__db_wclock_remove(svn_wc__db_t *db,
-                         const char *local_abspath,
-                         apr_pool_t *scratch_pool);
+svn_wc__db_wclock_release(svn_wc__db_t *db,
+                          const char *local_abspath,
+                          apr_pool_t *scratch_pool);
+
+/* Checks whether DB currently owns a lock to operate on LOCAL_ABSPATH.
+   If EXACT is TRUE only lock roots are checked. */
+svn_error_t *
+svn_wc__db_wclock_owns_lock(svn_boolean_t *own_lock,
+                            svn_wc__db_t *db,
+                            const char *local_abspath,
+                            svn_boolean_t exact,
+                            apr_pool_t *scratch_pool);
+
 
 
 /* @defgroup svn_wc__db_temp Various temporary functions during transition
@@ -2241,6 +2242,7 @@ svn_wc__db_temp_is_dir_deleted(svn_boole
                                const char *local_abspath,
                                apr_pool_t *scratch_pool);
 
+#ifndef SVN_WC__SINGLE_DB
 /* For a deleted node, determine its keep_local flag. (This flag will
    go away once we have a consolidated administrative area) */
 svn_error_t *
@@ -2256,6 +2258,7 @@ svn_wc__db_temp_set_keep_local(svn_wc__d
                                const char *local_abspath,
                                svn_boolean_t keep_local,
                                apr_pool_t *scratch_pool);
+#endif
 
 /* Removes all references of LOCAL_ABSPATH from its working copy
    using DB. */
@@ -2354,19 +2357,6 @@ svn_wc__db_temp_wcroot_tempdir(const cha
                                apr_pool_t *result_pool,
                                apr_pool_t *scratch_pool);
 
-
-svn_error_t *
-svn_wc__db_temp_mark_locked(svn_wc__db_t *db,
-                            const char *local_dir_abspath,
-                            apr_pool_t *scratch_pool);
-
-
-svn_error_t *
-svn_wc__db_temp_own_lock(svn_boolean_t *own_lock,
-                         svn_wc__db_t *db,
-                         const char *local_dir_abspath,
-                         apr_pool_t *scratch_pool);
-
 svn_error_t *
 svn_wc__db_temp_op_set_base_incomplete(svn_wc__db_t *db,
                                        const char *local_dir_abspath,
@@ -2494,8 +2484,27 @@ svn_wc__db_temp_op_set_new_dir_to_incomp
                                              const char *repos_root_url,
                                              const char *repos_uuid,
                                              svn_revnum_t revision,
+                                             svn_depth_t depth,
                                              apr_pool_t *scratch_pool);
 
+/* Close the wc root LOCAL_ABSPATH and remove any per-directory
+   handles associated with it. */
+svn_error_t *
+svn_wc__db_drop_root(svn_wc__db_t *db,
+                     const char *local_abspath,
+                     apr_pool_t *scratch_pool);
+
+/* Internal version of svn_wc__node_get_copyfrom_info */
+svn_error_t *
+svn_wc__internal_get_copyfrom_info(const char **copyfrom_root_url,
+                                   const char **copyfrom_repos_relpath,
+                                   const char **copyfrom_url,
+                                   svn_revnum_t *copyfrom_rev,
+                                   svn_boolean_t *is_copy_target,
+                                   svn_wc__db_t *db,
+                                   const char *local_abspath,
+                                   apr_pool_t *result_pool,
+                                   apr_pool_t *scratch_pool);
 /* @} */
 
 

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc_db_pdh.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc_db_pdh.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc_db_pdh.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc_db_pdh.c Wed Aug 11 16:43:22 2010
@@ -34,10 +34,6 @@
 
 #include "svn_private_config.h"
 
-WC_QUERIES_SQL_DECLARE_STATEMENTS(statements);
-
-
-
 /* ### Same values as wc_db.c */
 #define SDB_FILE  "wc.db"
 #define UNKNOWN_WC_ID ((apr_int64_t) -1)
@@ -89,7 +85,7 @@ get_old_version(int *version,
   return SVN_NO_ERROR;
 }
 
-
+#ifndef SVN_WC__SINGLE_DB
 /* The filesystem has a directory at LOCAL_RELPATH. Examine the metadata
    to determine if a *file* was supposed to be there.
 
@@ -133,6 +129,7 @@ determine_obstructed_file(svn_boolean_t 
 
   return svn_sqlite__reset(stmt);
 }
+#endif
 
 
 /* */
@@ -329,6 +326,12 @@ svn_wc__db_pdh_create_wcroot(svn_wc__db_
   (*wcroot)->sdb = sdb;
   (*wcroot)->wc_id = wc_id;
   (*wcroot)->format = format;
+#ifdef SVN_WC__SINGLE_DB
+  /* 8 concurrent locks is probably more than a typical wc_ng based svn client
+     uses. */
+  (*wcroot)->owned_locks = apr_array_make(result_pool, 8,
+                                          sizeof(svn_wc__db_wclock_t));
+#endif
 
   /* SDB will be NULL for pre-NG working copies. We only need to run a
      cleanup when the SDB is present.  */
@@ -693,6 +696,7 @@ svn_wc__db_pdh_parse_local_abspath(svn_w
             }
         }
 
+#ifndef SVN_WC__SINGLE_DB
       if (parent_pdh)
         {
           const char *lookfor_relpath = svn_dirent_basename(local_abspath,
@@ -714,6 +718,7 @@ svn_wc__db_pdh_parse_local_abspath(svn_w
               return SVN_NO_ERROR;
             }
         }
+#endif
     }
 
   /* The PDH is complete. Stash it into DB.  */
@@ -776,3 +781,69 @@ svn_wc__db_pdh_parse_local_abspath(svn_w
 
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_wc__db_pdh_navigate_to_parent(svn_wc__db_pdh_t **parent_pdh,
+                                  svn_wc__db_t *db,
+                                  svn_wc__db_pdh_t *child_pdh,
+                                  svn_sqlite__mode_t smode,
+                                  apr_pool_t *scratch_pool)
+{
+  const char *parent_abspath;
+  const char *local_relpath;
+
+  if ((*parent_pdh = child_pdh->parent) != NULL
+      && (*parent_pdh)->wcroot != NULL)
+    return SVN_NO_ERROR;
+
+  /* Make sure we don't see the root as its own parent */
+  SVN_ERR_ASSERT(!svn_dirent_is_root(child_pdh->local_abspath,
+                                     strlen(child_pdh->local_abspath)));
+
+  parent_abspath = svn_dirent_dirname(child_pdh->local_abspath, scratch_pool);
+  SVN_ERR(svn_wc__db_pdh_parse_local_abspath(parent_pdh, &local_relpath, db,
+                              parent_abspath, smode,
+                              scratch_pool, scratch_pool));
+  VERIFY_USABLE_PDH(*parent_pdh);
+
+  child_pdh->parent = *parent_pdh;
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__db_drop_root(svn_wc__db_t *db,
+                     const char *local_abspath,
+                     apr_pool_t *scratch_pool)
+{
+  svn_wc__db_pdh_t *root_pdh = apr_hash_get(db->dir_data, local_abspath,
+                                            APR_HASH_KEY_STRING);
+  apr_hash_index_t *hi;
+  apr_status_t result;
+
+  if (!root_pdh)
+    return SVN_NO_ERROR;
+
+  if (!root_pdh->wcroot || strcmp(root_pdh->wcroot->abspath, local_abspath))
+    return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL,
+                             _("'%s' is not a working copy root"),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+
+  for (hi = apr_hash_first(scratch_pool, db->dir_data);
+       hi;
+       hi = apr_hash_next(hi))
+    {
+      svn_wc__db_pdh_t *pdh = svn__apr_hash_index_val(hi);
+
+      if (pdh->wcroot == root_pdh->wcroot)
+        apr_hash_set(db->dir_data,
+                     pdh->local_abspath, svn__apr_hash_index_klen(hi), NULL);
+    }
+
+  result = apr_pool_cleanup_run(db->state_pool, root_pdh->wcroot, close_wcroot);
+  if (result != APR_SUCCESS)
+    return svn_error_wrap_apr(result, NULL);
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc_db_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc_db_private.h?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc_db_private.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc_db_private.h Wed Aug 11 16:43:22 2010
@@ -56,11 +56,20 @@ struct svn_wc__db_t {
   apr_pool_t *state_pool;
 };
 
+/* Hold information about an owned lock */
+typedef struct svn_wc__db_wclock_t
+{
+  /* Relative path of the lock root */
+  const char *local_relpath;
+  /* Number of levels locked (0 for infinity) */
+  int levels;
+} svn_wc__db_wclock_t;
+
 /** Hold information about a WCROOT.
  *
  * This structure is referenced by all per-directory handles underneath it.
  */
-typedef struct {
+typedef struct svn_wc__db_wcroot_t {
   /* Location of this wcroot in the filesystem.  */
   const char *abspath;
 
@@ -75,6 +84,12 @@ typedef struct {
      format has not (yet) been determined, this will be UNKNOWN_FORMAT.  */
   int format;
 
+#ifdef SVN_WC__SINGLE_DB
+  /* Array of svn_wc__db_wclock_t fields (not pointers!).
+     Typically just one or two locks maximum. */
+  apr_array_header_t *owned_locks;
+#endif
+
 } svn_wc__db_wcroot_t;
 
 /**  Pristine Directory Handle
@@ -83,6 +98,7 @@ typedef struct {
  * a given working copy directory.
  */
 typedef struct svn_wc__db_pdh_t {
+#ifndef SVN_WC__SINGLE_DB
   /* This (versioned) working copy directory is obstructing what *should*
      be a file in the parent directory (according to its metadata).
 
@@ -90,6 +106,7 @@ typedef struct svn_wc__db_pdh_t {
 
      ### obstruction is only possible with per-dir wc.db databases.  */
   svn_boolean_t obstructed_file;
+#endif
 
   /* The absolute path to this working copy directory. */
   const char *local_abspath;
@@ -100,8 +117,10 @@ typedef struct svn_wc__db_pdh_t {
   /* The parent directory's per-dir information. */
   struct svn_wc__db_pdh_t *parent;
 
+#ifndef SVN_WC__SINGLE_DB
   /* Whether this process owns a write-lock on this directory. */
   svn_boolean_t locked;
+#endif
 
   /* Hold onto the old-style access baton that corresponds to this PDH.  */
   svn_wc_adm_access_t *adm_access;
@@ -161,6 +180,21 @@ const char *
 svn_wc__db_pdh_compute_relpath(const svn_wc__db_pdh_t *pdh,
                                apr_pool_t *result_pool);
 
+/* Gets or opens the PDH of the parent directory of CHILD_PDH.
+   (This function doesn't verify if the PDHs are related) */
+svn_error_t *
+svn_wc__db_pdh_navigate_to_parent(svn_wc__db_pdh_t **parent_pdh,
+                                  svn_wc__db_t *db,
+                                  svn_wc__db_pdh_t *child_pdh,
+                                  svn_sqlite__mode_t smode,
+                                  apr_pool_t *scratch_pool);
+
+/* Assert that the given PDH is usable.
+   NOTE: the expression is multiply-evaluated!!  */
+#define VERIFY_USABLE_PDH(pdh) SVN_ERR_ASSERT(  \
+    (pdh)->wcroot != NULL                       \
+    && (pdh)->wcroot->format == SVN_WC__VERSION)
+
 /* */
 svn_error_t *
 svn_wc__db_util_fetch_wc_id(apr_int64_t *wc_id,

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/workqueue.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/workqueue.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/workqueue.c Wed Aug 11 16:43:22 2010
@@ -35,33 +35,26 @@
 #include "workqueue.h"
 #include "adm_files.h"
 #include "translate.h"
-#include "log.h"
 
 #include "svn_private_config.h"
 #include "private/svn_skel.h"
 
 
-#define NOT_IMPLEMENTED() \
-  return svn_error__malfunction(TRUE, __FILE__, __LINE__, "Not implemented.")
-
-
 /* Workqueue operation names.  */
 #define OP_REVERT "revert"
-#define OP_PREPARE_REVERT_FILES "prep-rev-files"
 #define OP_KILLME "killme"
-#define OP_LOGGY "loggy"
+#define OP_BASE_REMOVE "base-remove"
 #define OP_DELETION_POSTCOMMIT "deletion-postcommit"
 /* Arguments of OP_POSTCOMMIT:
  *   (local_abspath, revnum, date, [author], [checksum],
  *    [dav_cache/wc_props], keep_changelist, [tmp_text_base_abspath]). */
 #define OP_POSTCOMMIT "postcommit"
-#define OP_INSTALL_PROPERTIES "install-properties-2"
-#define OP_DELETE "delete"
 #define OP_FILE_INSTALL "file-install"
 #define OP_FILE_REMOVE "file-remove"
+#define OP_FILE_MOVE "file-move"
+#define OP_FILE_COPY_TRANSLATED "file-translate"
 #define OP_SYNC_FILE_FLAGS "sync-file-flags"
 #define OP_PREJ_INSTALL "prej-install"
-#define OP_WRITE_OLD_PROPS "write-old-props"
 #define OP_RECORD_FILEINFO "record-fileinfo"
 #define OP_TMP_SET_TEXT_CONFLICT_MARKERS "tmp-set-text-conflict-markers"
 #define OP_TMP_SET_PROPERTY_CONFLICT_MARKER "tmp-set-property-conflict-marker"
@@ -75,6 +68,7 @@ struct work_item_dispatch {
   const char *name;
   svn_error_t *(*func)(svn_wc__db_t *db,
                        const svn_skel_t *work_item,
+                       const char *wri_abspath,
                        svn_cancel_func_t cancel_func,
                        void *cancel_baton,
                        apr_pool_t *scratch_pool);
@@ -145,30 +139,6 @@ get_and_record_fileinfo(svn_wc__db_t *db
 }
 
 
-/* If SOURCE_ABSPATH is present, then move it to DEST_ABSPATH. Ignore any
-   ENOENT message for a missing source, which may indicate the move has
-   already been performed.  */
-static svn_error_t *
-move_if_present(const char *source_abspath,
-                const char *dest_abspath,
-                apr_pool_t *scratch_pool)
-{
-  svn_error_t *err;
-
-  err = svn_io_file_rename(source_abspath, dest_abspath, scratch_pool);
-  if (err)
-    {
-      if (!APR_STATUS_IS_ENOENT(err->apr_err))
-        return svn_error_return(err);
-
-      /* Not there. Maybe the node was moved in a prior run.  */
-      svn_error_clear(err);
-    }
-
-  return SVN_NO_ERROR;
-}
-
-
 /* ------------------------------------------------------------------------ */
 
 /* OP_REVERT  */
@@ -204,6 +174,7 @@ maybe_remove_conflict(const char *parent
 static svn_error_t *
 run_revert(svn_wc__db_t *db,
            const svn_skel_t *work_item,
+           const char *wri_abspath,
            svn_cancel_func_t cancel_func,
            void *cancel_baton,
            apr_pool_t *scratch_pool)
@@ -212,7 +183,6 @@ run_revert(svn_wc__db_t *db,
   const char *local_abspath;
   svn_boolean_t replaced;
   svn_wc__db_kind_t kind;
-  const char *working_props_path;
   const char *parent_abspath;
   svn_boolean_t conflicted;
 
@@ -233,39 +203,6 @@ run_revert(svn_wc__db_t *db,
             db, local_abspath,
             scratch_pool, scratch_pool));
 
-#if (SVN_WC__VERSION < SVN_WC__PROPS_IN_DB)
-  /* Move the "revert" props over/on the "base" props.  */
-  if (replaced)
-    {
-      const char *revert_props_path;
-      const char *base_props_path;
-
-      SVN_ERR(svn_wc__prop_path(&revert_props_path, local_abspath,
-                                kind, svn_wc__props_revert, scratch_pool));
-      SVN_ERR(svn_wc__prop_path(&base_props_path, local_abspath,
-                                kind, svn_wc__props_base, scratch_pool));
-
-      SVN_ERR(move_if_present(revert_props_path, base_props_path,
-                              scratch_pool));
-
-      /* ### we should also be setting BASE props. and really... we shouldn't
-         ### even bother zero-ing out these props. the WORKING node should
-         ### be disappearing after a revert.  */
-#if 0
-      SVN_ERR(svn_wc__db_temp_working_set_props(db, local_abspath,
-                                                apr_hash_make(scratch_pool),
-                                                scratch_pool));
-#endif
-    }
-#endif
-
-  /* The "working" props contain changes. Nuke 'em from orbit.  */
-#if (SVN_WC__VERSION < SVN_WC__PROPS_IN_DB)
-  SVN_ERR(svn_wc__prop_path(&working_props_path, local_abspath,
-                            kind, svn_wc__props_working, scratch_pool));
-  SVN_ERR(svn_io_remove_file2(working_props_path, TRUE, scratch_pool));
-#endif
-
   SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, NULL, NULL, NULL,
                                   scratch_pool));
 
@@ -283,26 +220,16 @@ run_revert(svn_wc__db_t *db,
          using the original base.  */
       reinstall_working = magic_changed || replaced;
 
+      /* ### This "if (replaced)" looks very likely to be an artifact of the
+         old WC-1 "revert-base and normal-base" system, and if so then it
+         should go away. */
       if (replaced)
         {
-#ifdef SVN_EXPERIMENTAL_PRISTINE
-          /* With the Pristine Store, the checksum of this base stays in the
-             BASE_NODE table so we don't need to rename or move anything. */
-#else
-          /* For WC-1: If there is a "revert base" file (because the file
-           * is replaced), then move that revert base over to the normal
-           * base. WC-NG keeps the checksum which we used to recalculate
-           * in the past. */
-          const char *revert_base_path;
-          const char *text_base_path;
-
-          SVN_ERR(svn_wc__text_revert_path(&revert_base_path, db,
-                                           local_abspath, scratch_pool));
-          SVN_ERR(svn_wc__text_base_path(&text_base_path, db, local_abspath,
-                                         scratch_pool));
-          SVN_ERR(move_if_present(revert_base_path, text_base_path,
-                                  scratch_pool));
-#endif
+          /* With the Pristine Store, there is no longer a "revert-base"
+             text that needs to be moved to a "normal text-base" location.
+
+             ### JAF: I wonder why the "revert-base" properties weren't being
+             handled the same way in this same code path.  An oversight? */
         }
       else if (!reinstall_working)
         {
@@ -362,8 +289,18 @@ run_revert(svn_wc__db_t *db,
     }
   else if (kind == svn_wc__db_kind_symlink)
     {
-      NOT_IMPLEMENTED();
+      SVN__NOT_IMPLEMENTED();
     }
+#ifdef SVN_WC__SINGLE_DB
+  else if (kind == svn_wc__db_kind_dir)
+    {
+      svn_node_kind_t disk_kind;
+      SVN_ERR(svn_io_check_path(local_abspath, &disk_kind, scratch_pool));
+
+      if (disk_kind == svn_node_none)
+        SVN_ERR(svn_io_dir_make(local_abspath, APR_OS_DEFAULT, scratch_pool));
+    }
+#endif
 
   if (kind == svn_wc__db_kind_dir)
     parent_abspath = local_abspath;
@@ -429,7 +366,6 @@ verify_pristine_present(svn_wc__db_t *db
                         const char *local_abspath,
                         apr_pool_t *scratch_pool)
 {
-#ifdef SVN_EXPERIMENTAL_PRISTINE
   const svn_checksum_t *base_checksum;
 
   SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, NULL, NULL, NULL,
@@ -448,25 +384,6 @@ verify_pristine_present(svn_wc__db_t *db
                                scratch_pool, scratch_pool));
   if (base_checksum != NULL)
     return SVN_NO_ERROR;
-#else
-  const char *base_abspath;
-  svn_error_t *err;
-
-  /* Verify that one of the two text bases are present.  */
-  err = svn_wc__text_base_path_to_read(&base_abspath, db, local_abspath,
-                                       scratch_pool, scratch_pool);
-  if (err && err->apr_err == SVN_ERR_WC_PATH_UNEXPECTED_STATUS)
-    svn_error_clear(err);
-  else
-    return svn_error_return(err);
-
-  err = svn_wc__text_revert_path_to_read(&base_abspath, db, local_abspath,
-                                         scratch_pool);
-  if (err && err->apr_err == SVN_ERR_WC_PATH_UNEXPECTED_STATUS)
-    svn_error_clear(err);
-  else
-    return svn_error_return(err);
-#endif
 
   /* A real file must have either a regular or a revert text-base.
      If it has neither, we could be looking at the situation described
@@ -594,113 +511,8 @@ svn_wc__wq_add_revert(svn_boolean_t *wil
   return SVN_NO_ERROR;
 }
 
-
 /* ------------------------------------------------------------------------ */
-
-/* OP_PREPARE_REVERT_FILES  */
-
-
-/* Process the OP_PREPARE_REVERT_FILES work item WORK_ITEM.
- * See svn_wc__wq_prepare_revert_files() which generates this work item.
- * Implements (struct work_item_dispatch).func. */
-static svn_error_t *
-run_prepare_revert_files(svn_wc__db_t *db,
-                         const svn_skel_t *work_item,
-                         svn_cancel_func_t cancel_func,
-                         void *cancel_baton,
-                         apr_pool_t *scratch_pool)
-{
-  const svn_skel_t *arg1 = work_item->children->next;
-  const char *local_abspath;
-  svn_wc__db_kind_t kind;
-  const char *revert_prop_abspath;
-  const char *base_prop_abspath;
-  svn_node_kind_t on_disk;
-
-  /* We need a NUL-terminated path, so copy it out of the skel.  */
-  local_abspath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
-
-  /* Rename the original text base over to the revert text base.  */
-  SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, FALSE, scratch_pool));
-#ifdef SVN_EXPERIMENTAL_PRISTINE
-  /* With the Pristine Store, the checksum of this base stays in the
-   * BASE_NODE table so we don't need to rename or move anything. */
-#else
-  if (kind == svn_wc__db_kind_file)
-    {
-      const char *text_base;
-      const char *text_revert;
-
-      SVN_ERR(svn_wc__text_base_path(&text_base, db, local_abspath,
-                                     scratch_pool));
-      SVN_ERR(svn_wc__text_revert_path(&text_revert, db, local_abspath,
-                                       scratch_pool));
-
-      SVN_ERR(move_if_present(text_base, text_revert, scratch_pool));
-    }
-#endif
-
-  /* Set up the revert props.  */
-
-#if (SVN_WC__VERSION < SVN_WC__PROPS_IN_DB)
-  SVN_ERR(svn_wc__prop_path(&revert_prop_abspath, local_abspath, kind,
-                            svn_wc__props_revert, scratch_pool));
-  SVN_ERR(svn_wc__prop_path(&base_prop_abspath, local_abspath, kind,
-                            svn_wc__props_base, scratch_pool));
-
-  /* First: try to move any base properties to the revert location.  */
-  SVN_ERR(move_if_present(base_prop_abspath, revert_prop_abspath,
-                          scratch_pool));
-
-  /* If no props exist at the revert location, then drop a set of empty
-     props there. They are expected to be present.  */
-  SVN_ERR(svn_io_check_path(revert_prop_abspath, &on_disk, scratch_pool));
-  if (on_disk == svn_node_none)
-    {
-      svn_stream_t *stream;
-
-      /* A set of empty props is just an empty file. */
-      SVN_ERR(svn_stream_open_writable(&stream, revert_prop_abspath,
-                                       scratch_pool, scratch_pool));
-      SVN_ERR(svn_stream_close(stream));
-      SVN_ERR(svn_io_set_file_read_only(revert_prop_abspath, FALSE,
-                                        scratch_pool));
-    }
-#endif
-
-  /* Put some blank properties into the WORKING node.  */
-  /* ### this seems bogus. something else should come along and put the
-     ### correct values in here. we shouldn't put empty values in.  */
-#if 0
-  SVN_ERR(svn_wc__db_temp_working_set_props(db, local_abspath,
-                                            apr_hash_make(scratch_pool),
-                                            scratch_pool));
-#endif
-
-  return SVN_NO_ERROR;
-}
-
-
-svn_error_t *
-svn_wc__wq_prepare_revert_files(svn_wc__db_t *db,
-                                const char *local_abspath,
-                                apr_pool_t *scratch_pool)
-{
-  svn_skel_t *work_item = svn_skel__make_empty_list(scratch_pool);
-
-  /* These skel atoms hold references to very transitory state, but
-     we only need the work_item to survive for the duration of wq_add.  */
-  svn_skel__prepend_str(local_abspath, work_item, scratch_pool);
-  svn_skel__prepend_str(OP_PREPARE_REVERT_FILES, work_item, scratch_pool);
-
-  SVN_ERR(svn_wc__db_wq_add(db, local_abspath, work_item, scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-
-/* ------------------------------------------------------------------------ */
-
+#ifndef SVN_WC__SINGLE_DB
 /* OP_KILLME  */
 
 /* Process the OP_KILLME work item WORK_ITEM.
@@ -709,6 +521,7 @@ svn_wc__wq_prepare_revert_files(svn_wc__
 static svn_error_t *
 run_killme(svn_wc__db_t *db,
            const svn_skel_t *work_item,
+           const char *wri_abspath,
            svn_cancel_func_t cancel_func,
            void *cancel_baton,
            apr_pool_t *scratch_pool)
@@ -822,60 +635,232 @@ svn_wc__wq_add_killme(svn_wc__db_t *db,
 
   return SVN_NO_ERROR;
 }
-
+#endif
 
 /* ------------------------------------------------------------------------ */
+/* OP_REMOVE_BASE  */
+
+/* Removes a BASE_NODE and all it's data, leaving any adds and copies as is.
+   Do this as a depth first traversal to make sure than any parent still exists
+   on error conditions. 
+   
+   ### This function needs review for 4th tree behavior.*/
+static svn_error_t *
+remove_base_node(svn_wc__db_t *db,
+                 const char *local_abspath,
+                 svn_cancel_func_t cancel_func,
+                 void *cancel_baton,
+                 apr_pool_t *scratch_pool)
+{
+  svn_wc__db_status_t base_status, wrk_status;
+  svn_wc__db_kind_t base_kind, wrk_kind;
+  svn_boolean_t have_base, have_work;
+
+  if (cancel_func)
+    SVN_ERR(cancel_func(cancel_baton));
+
+  SVN_ERR(svn_wc__db_read_info(&wrk_status, &wrk_kind, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, &have_base,
+                               &have_work, NULL, NULL,
+                               db, local_abspath, scratch_pool, scratch_pool));
+
+#ifndef SVN_WC__SINGLE_DB
+  if (!have_base)
+    return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+                             _("Node '%s' not found."),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+#else
+  SVN_ERR_ASSERT(have_base); /* Verified in caller and _base_get_children() */
+#endif
 
-/* OP_LOGGY  */
+  if (wrk_status == svn_wc__db_status_normal
+      || wrk_status == svn_wc__db_status_not_present
+      || wrk_status == svn_wc__db_status_absent)
+    {
+      base_status = wrk_status;
+      base_kind = wrk_kind;
+    }
+  else
+    SVN_ERR(svn_wc__db_base_get_info(&base_status, &base_kind, NULL, NULL,
+                                     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                     NULL, NULL, NULL, NULL,
+                                     db, local_abspath,
+                                     scratch_pool, scratch_pool));
 
-/* Process the OP_LOGGY work item WORK_ITEM.
- * See svn_wc__wq_add_loggy() which generates this work item.
+  /* Children first */
+  if (base_kind == svn_wc__db_kind_dir
+      && base_status == svn_wc__db_status_normal)
+    {
+      const apr_array_header_t *children;
+      apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+      int i;
+
+      SVN_ERR(svn_wc__db_base_get_children(&children, db, local_abspath,
+                                           scratch_pool, iterpool));
+
+      for (i = 0; i < children->nelts; i++)
+        {
+          const char *child_name = APR_ARRAY_IDX(children, i, const char *);
+          const char *child_abspath;
+
+          svn_pool_clear(iterpool);
+
+          child_abspath = svn_dirent_join(local_abspath, child_name, iterpool);
+
+          SVN_ERR(remove_base_node(db, child_abspath, cancel_func, cancel_baton,
+                                   iterpool));
+        }
+
+      svn_pool_destroy(iterpool);
+    }
+
+  if (base_status == svn_wc__db_status_normal
+      && wrk_status != svn_wc__db_status_added
+      && wrk_status != svn_wc__db_status_obstructed_add
+      && wrk_status != svn_wc__db_status_excluded)
+    {
+#ifndef SVN_WC__SINGLE_DB
+      if (base_kind == svn_wc__db_kind_dir)
+        SVN_ERR(svn_wc__adm_destroy(db, local_abspath, cancel_func, cancel_baton,
+                                    scratch_pool));
+#endif
+
+      if (wrk_status != svn_wc__db_status_deleted
+          && (base_kind == svn_wc__db_kind_file
+              || base_kind == svn_wc__db_kind_symlink))
+        {
+          SVN_ERR(svn_io_remove_file2(local_abspath, TRUE, scratch_pool));
+        }
+      else if (base_kind == svn_wc__db_kind_dir
+#ifdef SVN_WC__SINGLE_DB
+               && wrk_status != svn_wc__db_status_deleted
+#endif
+              )
+        {
+          svn_error_t *err = svn_io_dir_remove_nonrecursive(local_abspath,
+                                                            scratch_pool);
+
+          if (err && (APR_STATUS_IS_ENOENT(err->apr_err)
+                      || SVN__APR_STATUS_IS_ENOTDIR(err->apr_err)
+                      || APR_STATUS_IS_ENOTEMPTY(err->apr_err)))
+            svn_error_clear(err);
+          else
+            SVN_ERR(err);
+        }
+
+      /* This should remove just BASE and ACTUAL, but for now also remove
+         not existing WORKING_NODE data. */
+      SVN_ERR(svn_wc__db_temp_op_remove_entry(db, local_abspath, scratch_pool));
+    }
+  else if (wrk_status == svn_wc__db_status_added
+           || wrk_status == svn_wc__db_status_obstructed_add
+           || (have_work && wrk_status == svn_wc__db_status_excluded))
+    /* ### deletes of working additions should fall in this case, but
+       ### we can't express these without the 4th tree */
+    {
+      /* Just remove the BASE_NODE data */
+      SVN_ERR(svn_wc__db_base_remove(db, local_abspath, scratch_pool));
+    }
+  else
+    SVN_ERR(svn_wc__db_temp_op_remove_entry(db, local_abspath, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+/* Process the OP_REMOVE_BASE work item WORK_ITEM.
+ * See svn_wc__wq_build_remove_base() which generates this work item.
  * Implements (struct work_item_dispatch).func. */
+
 static svn_error_t *
-run_loggy(svn_wc__db_t *db,
-          const svn_skel_t *work_item,
-          svn_cancel_func_t cancel_func,
-          void *cancel_baton,
-          apr_pool_t *scratch_pool)
+run_base_remove(svn_wc__db_t *db,
+                const svn_skel_t *work_item,
+                const char *wri_abspath,
+                svn_cancel_func_t cancel_func,
+                void *cancel_baton,
+                apr_pool_t *scratch_pool)
 {
   const svn_skel_t *arg1 = work_item->children->next;
-  const char *adm_abspath;
+  const char *local_abspath;
+  svn_boolean_t keep_not_present;
+  svn_revnum_t revision;
+  const char *repos_relpath, *repos_root_url, *repos_uuid;
+  svn_wc__db_kind_t kind;
 
-  /* We need a NUL-terminated path, so copy it out of the skel.  */
-  adm_abspath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
+  local_abspath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
+  keep_not_present = svn_skel__parse_int(arg1->next, scratch_pool) != 0;
 
-  return svn_error_return(svn_wc__run_xml_log(
-                            db, adm_abspath,
-                            arg1->next->data, arg1->next->len,
-                            scratch_pool));
-}
+  if (keep_not_present)
+    {
+      SVN_ERR(svn_wc__db_base_get_info(NULL, &kind, &revision, &repos_relpath,
+                                       &repos_root_url, &repos_uuid, NULL,
+                                       NULL, NULL, NULL, NULL, NULL, NULL,
+                                       NULL, NULL,
+                                       db, local_abspath,
+                                       scratch_pool, scratch_pool));
 
+      if (!repos_relpath)
+        SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath, &repos_root_url,
+                                           &repos_uuid,
+                                           db, local_abspath, scratch_pool,
+                                           scratch_pool));
 
-svn_error_t *
-svn_wc__wq_build_loggy(svn_skel_t **work_item,
-                       svn_wc__db_t *db,
-                       const char *adm_abspath,
-                       const svn_stringbuf_t *log_content,
-                       apr_pool_t *result_pool)
-{
-  if (log_content == NULL || svn_stringbuf_isempty(log_content))
+#ifndef SVN_WC__SINGLE_DB
+      /* ### When LOCAL_ABSPATH is obstructed, we might not receive a valid
+         ### revision here. For the small time that is left until Single-DB
+         ### just mark the not-present node as revision 0, as we are not
+         ### interested in the revision of not-present nodes anyway.
+
+         ### Triggered by update_tests.py 15: issue #919, updates that delete
+       */
+      if (!SVN_IS_VALID_REVNUM(revision))
+        revision = 0;
+#endif
+    }
+
+  SVN_ERR(remove_base_node(db, local_abspath,
+                           cancel_func, cancel_baton,
+                           scratch_pool));
+
+  if (keep_not_present)
     {
-      *work_item = NULL;
-      return SVN_NO_ERROR;
+      SVN_ERR(svn_wc__db_base_add_absent_node(db, local_abspath,
+                                              repos_relpath,
+                                              repos_root_url,
+                                              repos_uuid,
+                                              revision,
+                                              kind,
+                                              svn_wc__db_status_not_present,
+                                              NULL,
+                                              NULL,
+                                              scratch_pool));
     }
 
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__wq_build_base_remove(svn_skel_t **work_item,
+                             svn_wc__db_t *db,
+                             const char *local_abspath,
+                             svn_boolean_t keep_not_present,
+                             apr_pool_t *result_pool,
+                             apr_pool_t *scratch_pool)
+{
   *work_item = svn_skel__make_empty_list(result_pool);
 
-  /* NOTE: the skel still points at ADM_ABSPATH and LOG_CONTENT, but we
-     require these parameters to be allocated in RESULT_POOL.  */
-  svn_skel__prepend_str(log_content->data, *work_item, result_pool);
-  svn_skel__prepend_str(adm_abspath, *work_item, result_pool);
-  svn_skel__prepend_str(OP_LOGGY, *work_item, result_pool);
+  /* If a SOURCE_ABSPATH was provided, then put it into the skel. If this
+     value is not provided, then the file's pristine contents will be used.  */
+
+  svn_skel__prepend_int(keep_not_present, *work_item, result_pool);
+  svn_skel__prepend_str(apr_pstrdup(result_pool, local_abspath),
+                        *work_item, result_pool);
+  svn_skel__prepend_str(OP_BASE_REMOVE, *work_item, result_pool);
 
   return SVN_NO_ERROR;
 }
 
-
 /* ------------------------------------------------------------------------ */
 
 /* OP_DELETION_POSTCOMMIT  */
@@ -886,6 +871,7 @@ svn_wc__wq_build_loggy(svn_skel_t **work
 static svn_error_t *
 run_deletion_postcommit(svn_wc__db_t *db,
                         const svn_skel_t *work_item,
+                        const char *wri_abspath,
                         svn_cancel_func_t cancel_func,
                         void *cancel_baton,
                         apr_pool_t *scratch_pool)
@@ -914,6 +900,7 @@ run_deletion_postcommit(svn_wc__db_t *db
       const char *repos_uuid;
       svn_revnum_t parent_revision;
 
+#ifndef SVN_WC__SINGLE_DB
       /* If we are suppose to delete "this dir", drop a 'killme' file
          into my own administrative dir as a signal for svn_wc__run_log()
          to blow away the administrative area after it is finished
@@ -945,6 +932,7 @@ run_deletion_postcommit(svn_wc__db_t *db
                                     keep_local /* adm_only */,
                                     scratch_pool));
         }
+#endif
 
       /* Get hold of repository info, if we are going to need it,
          before deleting the file, */
@@ -965,7 +953,9 @@ run_deletion_postcommit(svn_wc__db_t *db
                 db, local_abspath,
                 FALSE, FALSE, cancel_func, cancel_baton, scratch_pool));
 
-      /* If the parent entry's working rev 'lags' behind new_rev... */
+      /* If the parent entry's working rev 'lags' behind new_rev... 
+         ### Maybe we should also add a not-present node if the
+         ### deleted node was switched? */
       if (new_revision > parent_revision)
         {
           /* ...then the parent's revision is now officially a
@@ -975,7 +965,7 @@ run_deletion_postcommit(svn_wc__db_t *db
           SVN_ERR(svn_wc__db_base_add_absent_node(
                     db, local_abspath,
                     repos_relpath, repos_root_url, repos_uuid,
-                    new_revision, svn_wc__db_kind_file,
+                    new_revision, kind,
                     svn_wc__db_status_not_present,
                     NULL, NULL,
                     scratch_pool));
@@ -1013,10 +1003,10 @@ svn_wc__wq_add_deletion_postcommit(svn_w
 /* OP_POSTCOMMIT  */
 
 
-/* If TMP_TEXT_BASE_ABSPATH is not NULL, then replace the text base for
- * newly-committed file FILE_ABSPATH with the new post-commit text base,
- * TMP_TEXT_BASE_ABSPATH which is in repository-normal form (aka
- * "detranslated" form).
+/* If TMP_TEXT_BASE_ABSPATH is not NULL, then assume that it is a copy of
+ * the new text base of the newly-committed versioned file FILE_ABSPATH,
+ * and adjust the working file accordingly.  TMP_TEXT_BASE_ABSPATH is in
+ * repository-normal form (aka "detranslated" form).
  *
  * If eol and/or keyword translation would cause the working file to
  * change, then overwrite the working file with a translated copy of
@@ -1104,7 +1094,11 @@ install_committed_file(svn_boolean_t *ov
      * it has the right executable and read_write attributes set.
      */
 
-    SVN_ERR(svn_wc__get_special(&special, db, file_abspath, scratch_pool));
+    SVN_ERR(svn_wc__get_translate_info(NULL, NULL,
+                                       NULL,
+                                       &special,
+                                       db, file_abspath,
+                                       scratch_pool, scratch_pool));
     if (! special && tmp != tmp_wfile)
       SVN_ERR(svn_io_files_contents_same_p(&same, tmp_wfile,
                                            file_abspath, scratch_pool));
@@ -1163,17 +1157,6 @@ install_committed_file(svn_boolean_t *ov
         *overwrote_working = TRUE;
     }
 
-  /* Install the new text base if one is waiting. */
-#ifdef SVN_EXPERIMENTAL_PRISTINE
-  /* The Pristine Store equivalent is putting the text in the pristine store
-     and putting its checksum in the database, both of which happened before
-     this function was called. */
-#else
-  if (tmp_text_base_abspath != NULL)
-    SVN_ERR(svn_wc__sync_text_base(db, file_abspath, tmp_text_base_abspath,
-                                   scratch_pool));
-#endif
-
   return SVN_NO_ERROR;
 }
 
@@ -1192,8 +1175,9 @@ log_do_committed(svn_wc__db_t *db,
                  const char *local_abspath,
                  const char *tmp_text_base_abspath,
                  svn_revnum_t new_revision,
-                 apr_time_t new_date,
-                 const char *new_author,
+                 svn_revnum_t changed_rev,
+                 apr_time_t changed_date,
+                 const char *changed_author,
                  const svn_checksum_t *new_checksum,
                  apr_hash_t *new_dav_cache,
                  svn_boolean_t keep_changelist,
@@ -1336,9 +1320,6 @@ log_do_committed(svn_wc__db_t *db,
                 set_read_write = TRUE;
             }
         }
-
-      /* Install LOCAL_ABSPATHs working props as base props. */
-      SVN_ERR(svn_wc__working_props_committed(db, local_abspath, pool));
     }
 
   /* If it's a file, install the tree changes and the file's text. */
@@ -1351,7 +1332,8 @@ log_do_committed(svn_wc__db_t *db,
       apr_time_t last_mod_time;
 
       SVN_ERR(svn_wc__db_global_commit(db, local_abspath,
-                                       new_revision, new_date, new_author,
+                                       new_revision, changed_rev,
+                                       changed_date, changed_author,
                                        new_checksum,
                                        NULL /* new_children */,
                                        new_dav_cache,
@@ -1435,7 +1417,8 @@ log_do_committed(svn_wc__db_t *db,
   /* It's not a file, so it's a directory. */
 
   SVN_ERR(svn_wc__db_global_commit(db, local_abspath,
-                                   new_revision, new_date, new_author,
+                                   new_revision, changed_rev,
+                                   changed_date, changed_author,
                                    NULL /* new_checksum */,
                                    NULL /* new_children */,
                                    new_dav_cache,
@@ -1472,6 +1455,7 @@ log_do_committed(svn_wc__db_t *db,
 static svn_error_t *
 run_postcommit(svn_wc__db_t *db,
                const svn_skel_t *work_item,
+               const char *wri_abspath,
                svn_cancel_func_t cancel_func,
                void *cancel_baton,
                apr_pool_t *scratch_pool)
@@ -1479,9 +1463,9 @@ run_postcommit(svn_wc__db_t *db,
   const svn_skel_t *arg1 = work_item->children->next;
   const svn_skel_t *arg5 = work_item->children->next->next->next->next->next;
   const char *local_abspath;
-  svn_revnum_t new_revision;
-  apr_time_t new_date;
-  const char *new_author;
+  svn_revnum_t new_revision, changed_rev;
+  apr_time_t changed_date;
+  const char *changed_author;
   const svn_checksum_t *new_checksum;
   apr_hash_t *new_dav_cache;
   svn_boolean_t keep_changelist, no_unlock;
@@ -1490,13 +1474,13 @@ run_postcommit(svn_wc__db_t *db,
 
   local_abspath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
   new_revision = (svn_revnum_t)svn_skel__parse_int(arg1->next, scratch_pool);
-  new_date = svn_skel__parse_int(arg1->next->next, scratch_pool);
+  changed_date = svn_skel__parse_int(arg1->next->next, scratch_pool);
   if (arg1->next->next->next->len == 0)
-    new_author = NULL;
+    changed_author = NULL;
   else
-    new_author = apr_pstrmemdup(scratch_pool,
-                                arg1->next->next->next->data,
-                                arg1->next->next->next->len);
+    changed_author = apr_pstrmemdup(scratch_pool,
+                                    arg1->next->next->next->data,
+                                    arg1->next->next->next->len);
   if (arg5->len == 0)
     {
       new_checksum = NULL;
@@ -1530,9 +1514,15 @@ run_postcommit(svn_wc__db_t *db,
   else
     no_unlock = TRUE;
 
+  if (arg5->next->next->next->next->next)
+    changed_rev = svn_skel__parse_int(arg5->next->next->next->next->next,
+                                      scratch_pool);
+  else
+    changed_rev = new_revision; /* Behavior before fixing issue #3676 */
+
   err = log_do_committed(db, local_abspath, tmp_text_base_abspath,
-                         new_revision, new_date,
-                         new_author, new_checksum, new_dav_cache,
+                         new_revision, changed_rev, changed_date,
+                         changed_author, new_checksum, new_dav_cache,
                          keep_changelist, no_unlock,
                          cancel_func, cancel_baton,
                          scratch_pool);
@@ -1551,8 +1541,9 @@ svn_wc__wq_add_postcommit(svn_wc__db_t *
                           const char *local_abspath,
                           const char *tmp_text_base_abspath,
                           svn_revnum_t new_revision,
-                          apr_time_t new_date,
-                          const char *new_author,
+                          svn_revnum_t changed_rev,
+                          apr_time_t changed_date,
+                          const char *changed_author,
                           const svn_checksum_t *new_checksum,
                           apr_hash_t *new_dav_cache,
                           svn_boolean_t keep_changelist,
@@ -1561,6 +1552,7 @@ svn_wc__wq_add_postcommit(svn_wc__db_t *
 {
   svn_skel_t *work_item = svn_skel__make_empty_list(scratch_pool);
 
+  svn_skel__prepend_int(changed_rev, work_item, scratch_pool);
   svn_skel__prepend_int(no_unlock, work_item, scratch_pool);
   svn_skel__prepend_str(tmp_text_base_abspath ? tmp_text_base_abspath : "",
                         work_item, scratch_pool);
@@ -1582,8 +1574,8 @@ svn_wc__wq_add_postcommit(svn_wc__db_t *
                                                    scratch_pool, scratch_pool)
                           : "",
                         work_item, scratch_pool);
-  svn_skel__prepend_str(new_author ? new_author : "", work_item, scratch_pool);
-  svn_skel__prepend_int(new_date, work_item, scratch_pool);
+  svn_skel__prepend_str(changed_author ? changed_author : "", work_item, scratch_pool);
+  svn_skel__prepend_int(changed_date, work_item, scratch_pool);
   svn_skel__prepend_int(new_revision, work_item, scratch_pool);
   svn_skel__prepend_str(local_abspath, work_item, scratch_pool);
   svn_skel__prepend_str(OP_POSTCOMMIT, work_item, scratch_pool);
@@ -1595,215 +1587,6 @@ svn_wc__wq_add_postcommit(svn_wc__db_t *
 
 /* ------------------------------------------------------------------------ */
 
-/* OP_INSTALL_PROPERTIES */
-
-/* See props.h  */
-#ifdef SVN__SUPPORT_BASE_MERGE
-
-/* Process the OP_INSTALL_PROPERTIES work item WORK_ITEM.
- * See svn_wc__wq_add_install_properties() which generates this work item.
- * Implements (struct work_item_dispatch).func. */
-static svn_error_t *
-run_install_properties(svn_wc__db_t *db,
-                       const svn_skel_t *work_item,
-                       svn_cancel_func_t cancel_func,
-                       void *cancel_baton,
-                       apr_pool_t *scratch_pool)
-{
-  const svn_skel_t *arg = work_item->children->next;
-  const char *local_abspath;
-  apr_hash_t *base_props;
-  apr_hash_t *actual_props;
-
-  /* We need a NUL-terminated path, so copy it out of the skel.  */
-  local_abspath = apr_pstrmemdup(scratch_pool, arg->data, arg->len);
-
-  arg = arg->next;
-  if (arg->is_atom)
-    base_props = NULL;
-  else
-    SVN_ERR(svn_skel__parse_proplist(&base_props, arg, scratch_pool));
-
-  arg = arg->next;
-  if (arg->is_atom)
-    actual_props = NULL;
-  else
-    SVN_ERR(svn_skel__parse_proplist(&actual_props, arg, scratch_pool));
-
-  if (base_props != NULL)
-    {
-        svn_boolean_t written = FALSE;
-
-          {
-            svn_error_t *err;
-
-            /* Try writing to the WORKING tree first.  */
-            err = svn_wc__db_temp_working_set_props(db, local_abspath,
-                                                    base_props,
-                                                    scratch_pool);
-            if (err)
-              {
-                if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
-                  return svn_error_return(err);
-                svn_error_clear(err);
-                /* The WORKING node is not present.  */
-              }
-            else
-              {
-                /* The WORKING node is present, and we wrote the props.  */
-                written = TRUE;
-              }
-          }
-
-        if (!written)
-          SVN_ERR(svn_wc__db_temp_base_set_props(db, local_abspath,
-                                                 base_props, scratch_pool));
-    }
-
-  /* Okay. It's time to save the ACTUAL props.  */
-  SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, actual_props,
-                                  NULL, NULL, scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-
-svn_error_t *
-svn_wc__wq_add_install_properties(svn_wc__db_t *db,
-                                  const char *local_abspath,
-                                  apr_hash_t *base_props,
-                                  apr_hash_t *actual_props,
-                                  apr_pool_t *scratch_pool)
-{
-  svn_skel_t *work_item = svn_skel__make_empty_list(scratch_pool);
-  svn_skel_t *props;
-
-  if (actual_props != NULL)
-    {
-      SVN_ERR(svn_skel__unparse_proplist(&props, actual_props, scratch_pool));
-      svn_skel__prepend(props, work_item);
-    }
-  else
-    svn_skel__prepend_str("", work_item, scratch_pool);
-
-  if (base_props != NULL)
-    {
-      SVN_ERR(svn_skel__unparse_proplist(&props, base_props, scratch_pool));
-      svn_skel__prepend(props, work_item);
-    }
-  else
-    svn_skel__prepend_str("", work_item, scratch_pool);
-
-  svn_skel__prepend_str(local_abspath, work_item, scratch_pool);
-  svn_skel__prepend_str(OP_INSTALL_PROPERTIES, work_item, scratch_pool);
-
-  SVN_ERR(svn_wc__db_wq_add(db, local_abspath, work_item, scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-#endif /* SVN__SUPPORT_BASE_MERGE  */
-
-
-/* ------------------------------------------------------------------------ */
-
-/* OP_DELETE */
-
-/* Process the OP_DELETE work item WORK_ITEM.
- * See svn_wc__wq_add_delete() which generates this work item.
- * Implements (struct work_item_dispatch).func. */
-static svn_error_t *
-run_delete(svn_wc__db_t *db,
-           const svn_skel_t *work_item,
-           svn_cancel_func_t cancel_func,
-           void *cancel_baton,
-           apr_pool_t *scratch_pool)
-{
-  const svn_skel_t *arg = work_item->children->next;
-  const char *local_abspath;
-  svn_wc__db_kind_t kind;
-  svn_boolean_t was_added, was_copied, was_replaced;
-
-  local_abspath = apr_pstrmemdup(scratch_pool, arg->data, arg->len);
-  arg = arg->next;
-  kind = (int) svn_skel__parse_int(arg, scratch_pool);
-  arg = arg->next;
-  was_added = svn_skel__parse_int(arg, scratch_pool) != 0;
-  arg = arg->next;
-  was_copied = svn_skel__parse_int(arg, scratch_pool) != 0;
-  arg = arg->next;
-  was_replaced = svn_skel__parse_int(arg, scratch_pool) != 0;
-
-  if (was_replaced && was_copied)
-    {
-#if (SVN_WC__VERSION < SVN_WC__PROPS_IN_DB)
-      const char *props_base, *props_revert;
-
-      SVN_ERR(svn_wc__prop_path(&props_base, local_abspath, kind,
-                                svn_wc__props_base, scratch_pool));
-      SVN_ERR(svn_wc__prop_path(&props_revert, local_abspath, kind,
-                                svn_wc__props_revert, scratch_pool));
-      SVN_ERR(move_if_present(props_revert, props_base, scratch_pool));
-#endif
-
-#ifndef SVN_EXPERIMENTAL_PRISTINE
-      if (kind != svn_wc__db_kind_dir)
-        {
-          const char *text_base, *text_revert;
-
-          SVN_ERR(svn_wc__text_base_path(&text_base, db, local_abspath,
-                                         scratch_pool));
-          SVN_ERR(svn_wc__text_revert_path(&text_revert, db,
-                                           local_abspath, scratch_pool));
-          SVN_ERR(move_if_present(text_revert, text_base, scratch_pool));
-        }
-#endif
-    }
-#if (SVN_WC__VERSION < SVN_WC__PROPS_IN_DB)
-  if (was_added)
-    {
-      const char *props_base, *props_working;
-
-      SVN_ERR(svn_wc__prop_path(&props_base, local_abspath, kind,
-                                svn_wc__props_base, scratch_pool));
-      SVN_ERR(svn_wc__prop_path(&props_working, local_abspath, kind,
-                                svn_wc__props_working, scratch_pool));
-
-      SVN_ERR(svn_io_remove_file2(props_base, TRUE, scratch_pool));
-      SVN_ERR(svn_io_remove_file2(props_working, TRUE, scratch_pool));
-    }
-#endif
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_wc__wq_add_delete(svn_wc__db_t *db,
-                      const char *parent_abspath,
-                      const char *local_abspath,
-                      svn_wc__db_kind_t kind,
-                      svn_boolean_t was_added,
-                      svn_boolean_t was_copied,
-                      svn_boolean_t was_replaced,
-                      apr_pool_t *scratch_pool)
-{
-  svn_skel_t *work_item = svn_skel__make_empty_list(scratch_pool);
-
-  svn_skel__prepend_int(was_replaced, work_item, scratch_pool);
-  svn_skel__prepend_int(was_copied, work_item, scratch_pool);
-  svn_skel__prepend_int(was_added, work_item, scratch_pool);
-  svn_skel__prepend_int(kind, work_item, scratch_pool);
-  svn_skel__prepend_str(local_abspath, work_item, scratch_pool);
-  svn_skel__prepend_str(OP_DELETE, work_item, scratch_pool);
-
-  SVN_ERR(svn_wc__db_wq_add(db, parent_abspath, work_item, scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-
-/* ------------------------------------------------------------------------ */
-
 /* OP_FILE_INSTALL */
 
 /* Process the OP_FILE_INSTALL work item WORK_ITEM.
@@ -1812,6 +1595,7 @@ svn_wc__wq_add_delete(svn_wc__db_t *db,
 static svn_error_t *
 run_file_install(svn_wc__db_t *db,
                  const svn_skel_t *work_item,
+                 const char *wri_abspath,
                  svn_cancel_func_t cancel_func,
                  void *cancel_baton,
                  apr_pool_t *scratch_pool)
@@ -1851,7 +1635,11 @@ run_file_install(svn_wc__db_t *db,
                                        scratch_pool, scratch_pool));
     }
 
-  SVN_ERR(svn_wc__get_special(&special, db, local_abspath, scratch_pool));
+  /* Fetch all the translation bits.  */
+  SVN_ERR(svn_wc__get_translate_info(&style, &eol,
+                                     &keywords,
+                                     &special, db, local_abspath,
+                                     scratch_pool, scratch_pool));
   if (special)
     {
       /* When this stream is closed, the resulting special file will
@@ -1869,12 +1657,6 @@ run_file_install(svn_wc__db_t *db,
       return SVN_NO_ERROR;
     }
 
-  /* Fetch all the translation bits.  */
-  SVN_ERR(svn_wc__get_eol_style(&style, &eol, db, local_abspath,
-                                scratch_pool, scratch_pool));
-  SVN_ERR(svn_wc__get_keywords(&keywords, db, local_abspath, NULL,
-                               scratch_pool, scratch_pool));
-
   if (svn_subst_translation_required(style, eol, keywords,
                                      FALSE /* special */,
                                      TRUE /* force_eol_check */))
@@ -1990,6 +1772,7 @@ svn_wc__wq_build_file_install(svn_skel_t
 static svn_error_t *
 run_file_remove(svn_wc__db_t *db,
                  const svn_skel_t *work_item,
+                 const char *wri_abspath,
                  svn_cancel_func_t cancel_func,
                  void *cancel_baton,
                  apr_pool_t *scratch_pool)
@@ -2021,6 +1804,164 @@ svn_wc__wq_build_file_remove(svn_skel_t 
   return SVN_NO_ERROR;
 }
 
+/* ------------------------------------------------------------------------ */
+
+/* OP_FILE_MOVE  */
+
+/* Process the OP_FILE_MOVE work item WORK_ITEM.
+ * See svn_wc__wq_build_file_move() which generates this work item.
+ * Implements (struct work_item_dispatch).func. */
+static svn_error_t *
+run_file_move(svn_wc__db_t *db,
+                 const svn_skel_t *work_item,
+                 const char *wri_abspath,
+                 svn_cancel_func_t cancel_func,
+                 void *cancel_baton,
+                 apr_pool_t *scratch_pool)
+{
+  const svn_skel_t *arg1 = work_item->children->next;
+  const char *src_abspath, *dst_abspath;
+  svn_error_t *err;
+
+  src_abspath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
+  dst_abspath = apr_pstrmemdup(scratch_pool, arg1->next->data,
+                               arg1->next->len);
+
+  /* Use svn_io_file_move() instead of svn_io_file_rename() to allow cross
+     device copies. We should not fail in the workqueue. */
+
+  err = svn_io_file_move(src_abspath, dst_abspath, scratch_pool);
+
+  /* If the source is not found, we assume the wq op is already handled */
+  if (err && APR_STATUS_IS_ENOENT(err->apr_err))
+    svn_error_clear(err);
+  else
+    SVN_ERR(err);
+
+  return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
+svn_wc__wq_build_file_move(svn_skel_t **work_item,
+                           svn_wc__db_t *db,
+                           const char *src_abspath,
+                           const char *dst_abspath,
+                           apr_pool_t *result_pool,
+                           apr_pool_t *scratch_pool)
+{
+  svn_node_kind_t kind;
+  *work_item = svn_skel__make_empty_list(result_pool);
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(src_abspath));
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath));
+
+  /* File must exist */
+  SVN_ERR(svn_io_check_path(src_abspath, &kind, result_pool));
+
+  if (kind == svn_node_none)
+    return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+                             _("'%s' not found"),
+                             svn_dirent_local_style(src_abspath,
+                                                    scratch_pool));
+
+  /* ### Once we move to a central DB we should try making
+     ### src_abspath and dst_abspath relative from the WCROOT. */
+
+  svn_skel__prepend_str(apr_pstrdup(result_pool, dst_abspath),
+                        *work_item, result_pool);
+  svn_skel__prepend_str(apr_pstrdup(result_pool, src_abspath),
+                        *work_item, result_pool);
+  svn_skel__prepend_str(OP_FILE_MOVE, *work_item, result_pool);
+
+  return SVN_NO_ERROR;
+}
+
+/* ------------------------------------------------------------------------ */
+
+/* OP_FILE_COPY_TRANSLATED */
+
+/* Process the OP_FILE_COPY_TRANSLATED work item WORK_ITEM.
+ * See run_file_copy_translated() which generates this work item.
+ * Implements (struct work_item_dispatch).func. */
+static svn_error_t *
+run_file_copy_translated(svn_wc__db_t *db,
+                         const svn_skel_t *work_item,
+                         const char *wri_abspath,
+                         svn_cancel_func_t cancel_func,
+                         void *cancel_baton,
+                         apr_pool_t *scratch_pool)
+{
+  const svn_skel_t *arg1 = work_item->children->next;
+  const char *local_abspath, *src_abspath, *dst_abspath;
+  svn_subst_eol_style_t style;
+  const char *eol;
+  apr_hash_t *keywords;
+  svn_boolean_t special;
+
+  local_abspath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
+  src_abspath = apr_pstrmemdup(scratch_pool, arg1->next->data,
+                               arg1->next->len);
+  dst_abspath = apr_pstrmemdup(scratch_pool, arg1->next->next->data,
+                                arg1->next->next->len);
+
+  SVN_ERR(svn_wc__get_translate_info(&style, &eol,
+                                     &keywords,
+                                     &special,
+                                     db, local_abspath,
+                                     scratch_pool, scratch_pool));
+
+  SVN_ERR(svn_subst_copy_and_translate4(src_abspath, dst_abspath,
+                                        eol, TRUE /* repair */,
+                                        keywords, TRUE /* expand */,
+                                        special,
+                                        cancel_func, cancel_baton,
+                                        scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
+svn_wc__wq_build_file_copy_translated(svn_skel_t **work_item,
+                                      svn_wc__db_t *db,
+                                      const char *local_abspath,
+                                      const char *src_abspath,
+                                      const char *dst_abspath,
+                                      apr_pool_t *result_pool,
+                                      apr_pool_t *scratch_pool)
+{
+  svn_node_kind_t kind;
+  *work_item = svn_skel__make_empty_list(result_pool);
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(src_abspath));
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath));
+
+  /* File must exist */
+  SVN_ERR(svn_io_check_path(src_abspath, &kind, result_pool));
+
+  if (kind == svn_node_none)
+    return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+                             _("'%s' not found"),
+                             svn_dirent_local_style(src_abspath,
+                                                    scratch_pool));
+
+  /* ### Once we move to a central DB we should try making
+     ### src_abspath, dst_abspath and info_abspath relative from
+     ### the WCROOT of info_abspath. */
+
+  svn_skel__prepend_str(apr_pstrdup(result_pool, dst_abspath),
+                        *work_item, result_pool);
+  svn_skel__prepend_str(apr_pstrdup(result_pool, src_abspath),
+                        *work_item, result_pool);
+  svn_skel__prepend_str(apr_pstrdup(result_pool, local_abspath),
+                        *work_item, result_pool);
+  svn_skel__prepend_str(OP_FILE_COPY_TRANSLATED, *work_item, result_pool);
+
+  return SVN_NO_ERROR;
+}
+
 
 /* ------------------------------------------------------------------------ */
 
@@ -2032,6 +1973,7 @@ svn_wc__wq_build_file_remove(svn_skel_t 
 static svn_error_t *
 run_sync_file_flags(svn_wc__db_t *db,
                     const svn_skel_t *work_item,
+                    const char *wri_abspath,
                     svn_cancel_func_t cancel_func,
                     void *cancel_baton,
                     apr_pool_t *scratch_pool)
@@ -2069,6 +2011,7 @@ svn_wc__wq_build_sync_file_flags(svn_ske
 static svn_error_t *
 run_prej_install(svn_wc__db_t *db,
                  const svn_skel_t *work_item,
+                 const char *wri_abspath,
                  svn_cancel_func_t cancel_func,
                  void *cancel_baton,
                  apr_pool_t *scratch_pool)
@@ -2131,98 +2074,45 @@ svn_wc__wq_build_prej_install(svn_skel_t
 
 /* ------------------------------------------------------------------------ */
 
-/* OP_WRITE_OLD_PROPS  */
+/* OP_RECORD_FILEINFO  */
 
 
 static svn_error_t *
-run_write_old_props(svn_wc__db_t *db,
+run_record_fileinfo(svn_wc__db_t *db,
                     const svn_skel_t *work_item,
+                    const char *wri_abspath,
                     svn_cancel_func_t cancel_func,
                     void *cancel_baton,
                     apr_pool_t *scratch_pool)
 {
   const svn_skel_t *arg1 = work_item->children->next;
-  const char *props_abspath;
-  svn_stream_t *stream;
-  apr_hash_t *props;
+  const char *local_abspath;
+  apr_time_t set_time = 0;
 
-  props_abspath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
+  local_abspath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
 
-  /* Torch whatever may be there.  */
-  SVN_ERR(svn_io_remove_file2(props_abspath, TRUE, scratch_pool));
+  if (arg1->next)
+    set_time = svn_skel__parse_int(arg1->next, scratch_pool);
 
-  if (arg1->next == NULL)
+  if (set_time != 0)
     {
-      /* PROPS == NULL means the file should be removed. Note that an
-         empty set of properties has an entirely different meaning.
-
-         The file has already been removed. Simply exit.  */
-      return SVN_NO_ERROR;
-    }
-  SVN_ERR(svn_skel__parse_proplist(&props, arg1->next, scratch_pool));
-
-  SVN_ERR(svn_stream_open_writable(&stream, props_abspath,
-                                   scratch_pool, scratch_pool));
-
-  /* An empty file is shorthand for an empty set of properties.  */
-  if (apr_hash_count(props) != 0)
-    SVN_ERR(svn_hash_write2(props, stream, SVN_HASH_TERMINATOR, scratch_pool));
+      svn_node_kind_t kind;
+      svn_boolean_t is_special;
 
-  SVN_ERR(svn_stream_close(stream));
-
-  SVN_ERR(svn_io_set_file_read_only(props_abspath,
-                                    FALSE /* ignore_enoent */,
-                                    scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-
-svn_error_t *
-svn_wc__wq_build_write_old_props(svn_skel_t **work_item,
-                                 const char *props_abspath,
-                                 apr_hash_t *props,
-                                 apr_pool_t *result_pool)
-{
-#if (SVN_WC__VERSION >= SVN_WC__PROPS_IN_DB)
-  *work_item = NULL;
-#else
-  *work_item = svn_skel__make_empty_list(result_pool);
-
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(props_abspath));
+      /* Do not set the timestamp on special files. */
+      SVN_ERR(svn_io_check_special_path(local_abspath, &kind, &is_special,
+                                        scratch_pool));
 
-  if (props != NULL)
-    {
-      svn_skel_t *props_skel;
+      /* Don't set affected time when local_abspath does not exist or is
+         a special file */
+      if (kind == svn_node_file && !is_special)
+        SVN_ERR(svn_io_set_file_affected_time(set_time, local_abspath,
+                                              scratch_pool));
 
-      SVN_ERR(svn_skel__unparse_proplist(&props_skel, props, result_pool));
-      svn_skel__prepend(props_skel, *work_item);
+      /* Note that we can't use the value we get here for recording as the
+         filesystem might have a different timestamp granularity */
     }
-  svn_skel__prepend_str(apr_pstrdup(result_pool, props_abspath),
-                        *work_item, result_pool);
-  svn_skel__prepend_str(OP_WRITE_OLD_PROPS, *work_item, result_pool);
-#endif
-
-  return SVN_NO_ERROR;
-}
-
-
-/* ------------------------------------------------------------------------ */
-
-/* OP_RECORD_FILEINFO  */
-
 
-static svn_error_t *
-run_record_fileinfo(svn_wc__db_t *db,
-                    const svn_skel_t *work_item,
-                    svn_cancel_func_t cancel_func,
-                    void *cancel_baton,
-                    apr_pool_t *scratch_pool)
-{
-  const svn_skel_t *arg1 = work_item->children->next;
-  const char *local_abspath;
-
-  local_abspath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
 
   return svn_error_return(get_and_record_fileinfo(db, local_abspath,
                                                   TRUE /* ignore_enoent */,
@@ -2233,12 +2123,16 @@ run_record_fileinfo(svn_wc__db_t *db,
 svn_error_t *
 svn_wc__wq_build_record_fileinfo(svn_skel_t **work_item,
                                  const char *local_abspath,
+                                 apr_time_t set_time,
                                  apr_pool_t *result_pool)
 {
   *work_item = svn_skel__make_empty_list(result_pool);
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
+  if (set_time)
+   svn_skel__prepend_int(set_time, *work_item, result_pool);
+
   svn_skel__prepend_str(apr_pstrdup(result_pool, local_abspath),
                         *work_item, result_pool);
   svn_skel__prepend_str(OP_RECORD_FILEINFO, *work_item, result_pool);
@@ -2254,6 +2148,7 @@ svn_wc__wq_build_record_fileinfo(svn_ske
 static svn_error_t *
 run_set_text_conflict_markers(svn_wc__db_t *db,
                     const svn_skel_t *work_item,
+                    const char *wri_abspath,
                     svn_cancel_func_t cancel_func,
                     void *cancel_baton,
                     apr_pool_t *scratch_pool)
@@ -2326,6 +2221,7 @@ svn_wc__wq_tmp_build_set_text_conflict_m
 static svn_error_t *
 run_set_property_conflict_marker(svn_wc__db_t *db,
                                  const svn_skel_t *work_item,
+                                 const char *wri_abspath,
                                  svn_cancel_func_t cancel_func,
                                  void *cancel_baton,
                                  apr_pool_t *scratch_pool)
@@ -2404,6 +2300,7 @@ pristine_get_translated(svn_wc__db_t *db
 static svn_error_t *
 run_pristine_get_translated(svn_wc__db_t *db,
                             const svn_skel_t *work_item,
+                            const char *wri_abspath,
                             svn_cancel_func_t cancel_func,
                             void *cancel_baton,
                             apr_pool_t *scratch_pool)
@@ -2459,25 +2356,22 @@ svn_wc__wq_build_pristine_get_translated
 
 static const struct work_item_dispatch dispatch_table[] = {
   { OP_REVERT, run_revert },
-  { OP_PREPARE_REVERT_FILES, run_prepare_revert_files },
-  { OP_KILLME, run_killme },
-  { OP_LOGGY, run_loggy },
   { OP_DELETION_POSTCOMMIT, run_deletion_postcommit },
   { OP_POSTCOMMIT, run_postcommit },
-  { OP_DELETE, run_delete },
   { OP_FILE_INSTALL, run_file_install },
   { OP_FILE_REMOVE, run_file_remove },
+  { OP_FILE_MOVE, run_file_move },
+  { OP_FILE_COPY_TRANSLATED, run_file_copy_translated },
   { OP_SYNC_FILE_FLAGS, run_sync_file_flags },
   { OP_PREJ_INSTALL, run_prej_install },
-  { OP_WRITE_OLD_PROPS, run_write_old_props },
   { OP_RECORD_FILEINFO, run_record_fileinfo },
+  { OP_BASE_REMOVE, run_base_remove },
   { OP_TMP_SET_TEXT_CONFLICT_MARKERS, run_set_text_conflict_markers },
   { OP_TMP_SET_PROPERTY_CONFLICT_MARKER, run_set_property_conflict_marker },
   { OP_PRISTINE_GET_TRANSLATED, run_pristine_get_translated },
 
-/* See props.h  */
-#ifdef SVN__SUPPORT_BASE_MERGE
-  { OP_INSTALL_PROPERTIES, run_install_properties },
+#ifndef SVN_WC__SINGLE_DB
+  { OP_KILLME, run_killme },
 #endif
 
   /* Sentinel.  */
@@ -2504,7 +2398,7 @@ dispatch_work_item(svn_wc__db_t *db,
 #ifdef DEBUG_WORK_QUEUE
           SVN_DBG(("dispatch: operation='%s'\n", scan->name));
 #endif
-          SVN_ERR((*scan->func)(db, work_item,
+          SVN_ERR((*scan->func)(db, work_item, wri_abspath,
                                 cancel_func, cancel_baton,
                                 scratch_pool));
           break;

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/workqueue.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/workqueue.h?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/workqueue.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/workqueue.h Wed Aug 11 16:43:22 2010
@@ -122,6 +122,33 @@ svn_wc__wq_build_file_remove(svn_skel_t 
                              apr_pool_t *result_pool,
                              apr_pool_t *scratch_pool);
 
+/* Set *WORK_ITEM to a new work item that describes a moves of
+   a file or directory from SRC_ABSPATH to DST_ABSPATH, ready for
+   storing in the working copy managing DST_ABSPATH.
+
+   Perform temporary allocations in SCRATCH_POOL and *WORK_ITEM in
+   RESULT_POOL.
+*/
+svn_error_t *
+svn_wc__wq_build_file_move(svn_skel_t **work_item,
+                           svn_wc__db_t *db,
+                           const char *src_abspath,
+                           const char *dst_abspath,
+                           apr_pool_t *result_pool,
+                           apr_pool_t *scratch_pool);
+
+/* Set *WORK_ITEM to a new work item that describes a copy from
+   SRC_ABSPATH to DST_ABSPATH, while translating the stream using
+   the information from LOCAL_ABSPATH. */
+svn_error_t *
+svn_wc__wq_build_file_copy_translated(svn_skel_t **work_item,
+                                      svn_wc__db_t *db,
+                                      const char *local_abspath,
+                                      const char *src_abspath,
+                                      const char *dst_abspath,
+                                      apr_pool_t *result_pool,
+                                      apr_pool_t *scratch_pool);
+
 
 /* Set *WORK_ITEM to a new work item that will synchronize the
    target node's readonly and executable flags with the values defined
@@ -146,26 +173,18 @@ svn_wc__wq_build_prej_install(svn_skel_t
                               apr_pool_t *result_pool,
                               apr_pool_t *scratch_pool);
 
-
-/* Set *WORK_ITEM to a new work item that will install PROPS at PROPS_ABSPATH.
-   If PROPS is NULL, then the target props file will will be removed.
-
-   ### this will go away when we fully move to in-db properties.  */
-svn_error_t *
-svn_wc__wq_build_write_old_props(svn_skel_t **work_item,
-                                 const char *props_abspath,
-                                 apr_hash_t *props,
-                                 apr_pool_t *result_pool);
-
-
 /* Set *WORK_ITEM to a new work item that will record file information of
    LOCAL_ABSPATH into the TRANSLATED_SIZE and LAST_MOD_TIME of the node via
    the svn_wc__db_global_record_fileinfo() function.
 
+   If SET_TIME is not 0, set LOCAL_ABSPATH's last modified time to this
+   time and after that record the actual file time.
+
    ### it is unclear whether this should survive.  */
 svn_error_t *
 svn_wc__wq_build_record_fileinfo(svn_skel_t **work_item,
                                  const char *local_abspath,
+                                 apr_time_t set_time,
                                  apr_pool_t *result_pool);
 
 
@@ -177,15 +196,24 @@ svn_wc__wq_add_revert(svn_boolean_t *wil
                       svn_boolean_t use_commit_times,
                       apr_pool_t *scratch_pool);
 
+/* Set *WORK_ITEM to a new work item that will remove all the data of
+   the BASE_NODE of LOCAL_ABSPATH and all it's descendants, but keeping
+   any WORKING_NODE data.
 
-/* Record a work item to prepare the "revert props" and "revert text base"
-   for LOCAL_ABSPATH.  */
-svn_error_t *
-svn_wc__wq_prepare_revert_files(svn_wc__db_t *db,
-                                const char *local_abspath,
-                                apr_pool_t *scratch_pool);
+   This function doesn't check for local modifications of the text files
+   as these would have triggered a tree conflict before.
 
+   ### This is only used from update_editor.c's do_entry_deletion().
+ */
+svn_error_t *
+svn_wc__wq_build_base_remove(svn_skel_t **work_item,
+                             svn_wc__db_t *db,
+                             const char *local_abspath,
+                             svn_boolean_t keep_not_present,
+                             apr_pool_t *result_pool,
+                             apr_pool_t *scratch_pool);
 
+#ifndef SVN_WC__SINGLE_DB
 /* Handle the old "KILLME" concept -- perform the actual deletion of a
    subdir (or just its admin area) during post-commit processing of a
    deleted subdir.  */
@@ -194,24 +222,7 @@ svn_wc__wq_add_killme(svn_wc__db_t *db,
                       const char *adm_abspath,
                       svn_boolean_t adm_only,
                       apr_pool_t *scratch_pool);
-
-
-/* ### temporary compat for mapping the old loggy into workqueue space.
-
-   Set *WORK_ITEM to a new work item ...
-
-   LOG_CONTENT may be NULL or reference an empty log.  Set *WORK_ITEM to
-   NULL in this case.
-
-   NOTE: ADM_ABSPATH and LOG_CONTENT must live at least as long as
-   RESULT_POOL (typically, they'll be allocated within RESULT_POOL).
-*/
-svn_error_t *
-svn_wc__wq_build_loggy(svn_skel_t **work_item,
-                       svn_wc__db_t *db,
-                       const char *adm_abspath,
-                       const svn_stringbuf_t *log_content,
-                       apr_pool_t *result_pool);
+#endif
 
 
 /* ### Temporary helper to store text conflict marker locations as a wq
@@ -281,43 +292,15 @@ svn_wc__wq_add_postcommit(svn_wc__db_t *
                           const char *local_abspath,
                           const char *tmp_text_base_abspath,
                           svn_revnum_t new_revision,
-                          apr_time_t new_date,
-                          const char *new_author,
+                          svn_revnum_t changed_rev,
+                          apr_time_t changed_date,
+                          const char *changed_author,
                           const svn_checksum_t *new_checksum,
                           apr_hash_t *new_dav_cache,
                           svn_boolean_t keep_changelist,
                           svn_boolean_t no_unlock,
                           apr_pool_t *scratch_pool);
 
-
-/* See props.h  */
-#ifdef SVN__SUPPORT_BASE_MERGE
-svn_error_t *
-svn_wc__wq_add_install_properties(svn_wc__db_t *db,
-                                  const char *local_abspath,
-                                  apr_hash_t *pristine_props,
-                                  apr_hash_t *actual_props,
-                                  apr_pool_t *scratch_pool);
-#endif
-
-/* Add a work item to delete a node.
-
-   ### LOCAL_ABSPATH is the node to be deleted and the queue exists in
-   PARENT_ABSPATH (because when LOCAL_ABSPATH is a directory it might
-   not exist on disk).  This use of PARENT_ABSPATH is inherited from
-   the log file conversion but perhaps we don't need to use a work
-   queue when deleting a directory that does not exist on disk.
- */
-svn_error_t *
-svn_wc__wq_add_delete(svn_wc__db_t *db,
-                      const char *parent_abspath,
-                      const char *local_abspath,
-                      svn_wc__db_kind_t kind,
-                      svn_boolean_t was_added,
-                      svn_boolean_t was_copied,
-                      svn_boolean_t was_replaced,
-                      apr_pool_t *scratch_pool);
-
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */