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/10 22:56:05 UTC

svn commit: r984206 [27/35] - in /subversion/branches/ignore-mergeinfo: ./ build/ build/generator/ build/generator/templates/ build/hudson/ build/hudson/jobs/subversion-1.6.x-solaris/ build/hudson/jobs/subversion-1.6.x-ubuntu/ build/hudson/jobs/subvers...

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=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/workqueue.c Tue Aug 10 20:55:56 2010
@@ -28,6 +28,7 @@
 #include "svn_dirent_uri.h"
 #include "svn_subst.h"
 #include "svn_hash.h"
+#include "svn_io.h"
 
 #include "wc.h"
 #include "wc_db.h"
@@ -49,7 +50,6 @@
 /* Workqueue operation names.  */
 #define OP_REVERT "revert"
 #define OP_PREPARE_REVERT_FILES "prep-rev-files"
-#define OP_REMOVE_REVERT_FILES "remove-rev-files"
 #define OP_KILLME "killme"
 #define OP_LOGGY "loggy"
 #define OP_DELETION_POSTCOMMIT "deletion-postcommit"
@@ -57,10 +57,18 @@
  *   (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"
+#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_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"
+
+
+/* For work queue debugging. Generates output about its operation.  */
+/* #define DEBUG_WORK_QUEUE */
 
 
 struct work_item_dispatch {
@@ -73,51 +81,67 @@ struct work_item_dispatch {
 };
 
 
-/* Ripped from the old loggy cp_and_translate operation.
-
-   SOURCE_ABSPATH specifies the source which is translated for
-   installation as the working file.
+/* ### forward declaration for this. Temporary hack so that a work item
+   ### can be constructed within another handler and dispatched
+   ### immediately. in most normal cases, appending a work item to the
+   ### queue should be fine. but for now... not so much. */
+static svn_error_t *
+dispatch_work_item(svn_wc__db_t *db,
+                   const char *wri_abspath,
+                   const svn_skel_t *work_item,
+                   svn_cancel_func_t cancel_func,
+                   void *cancel_baton,
+                   apr_pool_t *scratch_pool);
 
-   DEST_ABSPATH specifies the destination of the copy (typically the
-   working file).
 
-   VERSIONED_ABSPATH specifies the versioned file holding the properties
-   which specify the translation parameters.  */
 static svn_error_t *
-copy_and_translate(svn_wc__db_t *db,
-                   const char *source_abspath,
-                   const char *dest_abspath,
-                   const char *versioned_abspath,
-                   apr_pool_t *scratch_pool)
+sync_file_flags(svn_wc__db_t *db,
+                const char *local_abspath,
+                apr_pool_t *scratch_pool)
 {
-  svn_subst_eol_style_t style;
-  const char *eol;
-  apr_hash_t *keywords;
-  svn_boolean_t special;
+  /* ### right now, the maybe_set_* functions will only positively set those
+     ### values. we need to clear them first.  */
+  SVN_ERR(svn_io_set_file_read_write(local_abspath, FALSE, scratch_pool));
+  SVN_ERR(svn_io_set_file_executable(local_abspath, FALSE, FALSE,
+                                     scratch_pool));
 
-  SVN_ERR(svn_wc__get_eol_style(&style, &eol, db, versioned_abspath,
-                                scratch_pool, scratch_pool));
-  SVN_ERR(svn_wc__get_keywords(&keywords, db, versioned_abspath, NULL,
-                               scratch_pool, scratch_pool));
+  SVN_ERR(svn_wc__maybe_set_read_only(NULL, db, local_abspath, scratch_pool));
+  SVN_ERR(svn_wc__maybe_set_executable(NULL, db, local_abspath, scratch_pool));
 
-  /* ### eventually, we will not be called for special files...  */
-  SVN_ERR(svn_wc__get_special(&special, db, versioned_abspath,
-                              scratch_pool));
+  return SVN_NO_ERROR;
+}
 
-  SVN_ERR(svn_subst_copy_and_translate3(
-            source_abspath, dest_abspath,
-            eol, TRUE,
-            keywords, TRUE,
-            special,
-            scratch_pool));
 
-  /* ### this is a problem. DEST_ABSPATH is not necessarily versioned.  */
-  SVN_ERR(svn_wc__maybe_set_read_only(NULL, db, dest_abspath,
-                                      scratch_pool));
-  SVN_ERR(svn_wc__maybe_set_executable(NULL, db, dest_abspath,
-                                       scratch_pool));
+static svn_error_t *
+get_and_record_fileinfo(svn_wc__db_t *db,
+                        const char *local_abspath,
+                        svn_boolean_t ignore_enoent,
+                        apr_pool_t *scratch_pool)
+{
+  apr_time_t last_mod_time;
+  apr_finfo_t finfo;
+  svn_error_t *err;
 
-  return SVN_NO_ERROR;
+  err = svn_io_file_affected_time(&last_mod_time, local_abspath,
+                                  scratch_pool);
+  if (err)
+    {
+      if (!ignore_enoent || !APR_STATUS_IS_ENOENT(err->apr_err))
+        return svn_error_return(err);
+
+      /* No biggy. Just skip all this.  */
+      svn_error_clear(err);
+      return SVN_NO_ERROR;
+    }
+
+  SVN_ERR(svn_io_stat(&finfo, local_abspath,
+                      APR_FINFO_MIN | APR_FINFO_LINK,
+                      scratch_pool));
+
+  return svn_error_return(svn_wc__db_global_record_fileinfo(
+                            db, local_abspath,
+                            finfo.size, last_mod_time,
+                            scratch_pool));
 }
 
 
@@ -192,7 +216,7 @@ run_revert(svn_wc__db_t *db,
   const char *working_props_path;
   const char *parent_abspath;
   svn_boolean_t conflicted;
-  apr_uint64_t modify_flags = 0;
+  int modify_flags = 0;
   svn_wc_entry_t tmp_entry;
 
   /* We need a NUL-terminated path, so copy it out of the skel.  */
@@ -212,6 +236,7 @@ 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)
     {
@@ -235,23 +260,23 @@ run_revert(svn_wc__db_t *db,
                                                 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, scratch_pool));
+  SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, NULL, NULL, NULL,
+                                  scratch_pool));
 
   /* Deal with the working file, as needed.  */
   if (kind == svn_wc__db_kind_file)
     {
       svn_boolean_t magic_changed;
       svn_boolean_t reinstall_working;
-      const char *text_base_path;
-
-      SVN_ERR(svn_wc__text_base_path(&text_base_path, db, local_abspath,
-                                     FALSE, scratch_pool));
 
       magic_changed = svn_skel__parse_int(arg1->next->next, scratch_pool) != 0;
 
@@ -263,11 +288,21 @@ run_revert(svn_wc__db_t *db,
 
       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 and update the normal base checksum accordingly. */
           const char *revert_base_path;
+          const char *text_base_path;
           svn_checksum_t *checksum;
 
           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));
 
@@ -283,6 +318,7 @@ run_revert(svn_wc__db_t *db,
                                         svn_checksum_md5, scratch_pool));
           tmp_entry.checksum = svn_checksum_to_cstring(checksum, scratch_pool);
           modify_flags |= SVN_WC__ENTRY_MODIFY_CHECKSUM;
+#endif
         }
       else if (!reinstall_working)
         {
@@ -325,59 +361,19 @@ run_revert(svn_wc__db_t *db,
       if (reinstall_working)
         {
           svn_boolean_t use_commit_times;
-          apr_finfo_t finfo;
-
-          /* ### this should use OP_FILE_INSTALL.  */
-
-          /* Copy from the text base to the working file. The working file
-             specifies the params for translation.  */
-          SVN_ERR(copy_and_translate(db, text_base_path, local_abspath,
-                                     local_abspath, scratch_pool));
+          svn_skel_t *wi_file_install;
 
           use_commit_times = svn_skel__parse_int(arg1->next->next->next,
                                                  scratch_pool) != 0;
 
-          /* Possibly set the timestamp to last-commit-time, rather
-             than the 'now' time that already exists. */
-          if (use_commit_times)
-            {
-              apr_time_t changed_date;
-
-              /* Note: OP_REVERT is not used for a pure addition. There will
-                 always be a BASE node.  */
-              SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL,
-                                               NULL, NULL, NULL,
-                                               NULL, &changed_date, NULL,
-                                               NULL, NULL, NULL,
-                                               NULL, NULL, NULL,
-                                               db, local_abspath,
-                                               scratch_pool, scratch_pool));
-              if (changed_date)
-                {
-                  svn_boolean_t special;
-
-                  /* ### skip this test once db_kind_symlink is in use.  */
-                  SVN_ERR(svn_wc__get_special(&special, db, local_abspath,
-                                              scratch_pool));
-                  if (!special)
-                    SVN_ERR(svn_io_set_file_affected_time(changed_date,
-                                                          local_abspath,
-                                                          scratch_pool));
-                }
-            }
-
-          /* loggy_set_entry_timestamp_from_wc()  */
-          SVN_ERR(svn_io_file_affected_time(&tmp_entry.text_time,
-                                            local_abspath,
-                                            scratch_pool));
-          modify_flags |= SVN_WC__ENTRY_MODIFY_TEXT_TIME;
-
-          /* loggy_set_entry_working_size_from_wc()  */
-          SVN_ERR(svn_io_stat(&finfo, local_abspath,
-                              APR_FINFO_MIN | APR_FINFO_LINK,
-                              scratch_pool));
-          tmp_entry.working_size = finfo.size;
-          modify_flags |= SVN_WC__ENTRY_MODIFY_WORKING_SIZE;
+          SVN_ERR(svn_wc__wq_build_file_install(&wi_file_install,
+                                                db, local_abspath,
+                                                NULL /* source_abspath */,
+                                                use_commit_times,
+                                                TRUE /* record_fileinfo */,
+                                                scratch_pool, scratch_pool));
+          SVN_ERR(svn_wc__db_wq_add(db, local_abspath, wi_file_install,
+                                    scratch_pool));
         }
     }
   else if (kind == svn_wc__db_kind_symlink)
@@ -449,9 +445,9 @@ run_revert(svn_wc__db_t *db,
       node_kind = svn_node_file;
     }
 
-  SVN_ERR(svn_wc__entry_modify2(db, local_abspath, node_kind, FALSE,
-                                &tmp_entry, modify_flags,
-                                scratch_pool));
+  SVN_ERR(svn_wc__entry_modify(db, local_abspath, node_kind,
+                               &tmp_entry, modify_flags,
+                               scratch_pool));
 
   /* ### need to revert some bits in the parent stub. sigh.  */
   if (kind == svn_wc__db_kind_dir)
@@ -463,17 +459,18 @@ run_revert(svn_wc__db_t *db,
                                     db, local_abspath, scratch_pool));
       if (!is_wc_root && !is_switched)
         {
-          modify_flags = (SVN_WC__ENTRY_MODIFY_COPIED
-                          | SVN_WC__ENTRY_MODIFY_COPYFROM_URL
-                          | SVN_WC__ENTRY_MODIFY_COPYFROM_REV
-                          | SVN_WC__ENTRY_MODIFY_SCHEDULE);
           tmp_entry.copied = FALSE;
           tmp_entry.copyfrom_url = NULL;
           tmp_entry.copyfrom_rev = SVN_INVALID_REVNUM;
           tmp_entry.schedule = svn_wc_schedule_normal;
-          SVN_ERR(svn_wc__entry_modify2(db, local_abspath, svn_node_dir, TRUE,
-                                        &tmp_entry, modify_flags,
-                                        scratch_pool));
+          SVN_ERR(svn_wc__entry_modify_stub(
+                    db, local_abspath,
+                    &tmp_entry,
+                    SVN_WC__ENTRY_MODIFY_COPIED
+                      | SVN_WC__ENTRY_MODIFY_COPYFROM_URL
+                      | SVN_WC__ENTRY_MODIFY_COPYFROM_REV
+                      | SVN_WC__ENTRY_MODIFY_SCHEDULE,
+                    scratch_pool));
         }
     }
 
@@ -481,7 +478,9 @@ run_revert(svn_wc__db_t *db,
 }
 
 
-/* For issue #2101, we need to deliver this error. When the wc-ng pristine
+/* Return an APR_ENOENT error if LOCAL_ABSPATH has no text base.
+
+   For issue #2101, we need to deliver this error. When the wc-ng pristine
    handling comes into play, the issue should be fixed, and this code can
    go away.  */
 static svn_error_t *
@@ -489,21 +488,44 @@ verify_pristine_present(svn_wc__db_t *db
                         const char *local_abspath,
                         apr_pool_t *scratch_pool)
 {
-  const char *base_abspath;
-  svn_node_kind_t check_kind;
+#ifdef SVN_EXPERIMENTAL_PRISTINE
+  const svn_checksum_t *base_checksum;
 
-  /* Verify that one of the two text bases are present.  */
-  SVN_ERR(svn_wc__text_base_path(&base_abspath, db, local_abspath, FALSE,
-                                 scratch_pool));
-  SVN_ERR(svn_io_check_path(base_abspath, &check_kind, scratch_pool));
-  if (check_kind == svn_node_file)
+  SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, NULL, NULL, NULL,
+                                   NULL, NULL, NULL, NULL, NULL,
+                                   &base_checksum, NULL, NULL, NULL,
+                                   db, local_abspath,
+                                   scratch_pool, scratch_pool));
+  if (base_checksum != NULL)
     return SVN_NO_ERROR;
 
-  SVN_ERR(svn_wc__text_revert_path(&base_abspath, db, local_abspath,
-                                   scratch_pool));
-  SVN_ERR(svn_io_check_path(base_abspath, &check_kind, scratch_pool));
-  if (check_kind == svn_node_file)
+  SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, &base_checksum,
+                               NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL,
+                               db, local_abspath,
+                               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
@@ -557,9 +579,12 @@ svn_wc__wq_add_revert(svn_boolean_t *wil
       apr_hash_t *working_props;
       apr_array_header_t *prop_diffs;
 
-      SVN_ERR(svn_wc__load_props(&base_props, &working_props,
-                                 db, local_abspath,
-                                 scratch_pool, scratch_pool));
+      SVN_ERR(svn_wc__get_pristine_props(&base_props,
+                                         db, local_abspath,
+                                         scratch_pool, scratch_pool));
+      SVN_ERR(svn_wc__get_actual_props(&working_props,
+                                       db, local_abspath,
+                                       scratch_pool, scratch_pool));
       SVN_ERR(svn_prop_diffs(&prop_diffs, working_props, base_props,
                              scratch_pool));
       magic_changed = svn_wc__has_magic_property(prop_diffs);
@@ -656,21 +681,27 @@ run_prepare_revert_files(svn_wc__db_t *d
 
   /* 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, FALSE,
+      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,
@@ -694,6 +725,7 @@ run_prepare_revert_files(svn_wc__db_t *d
       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
@@ -728,60 +760,6 @@ svn_wc__wq_prepare_revert_files(svn_wc__
 
 /* ------------------------------------------------------------------------ */
 
-/* OP_REMOVE_REVERT_FILES  */
-
-
-/* Process the OP_REMOVE_REVERT_FILES work item WORK_ITEM.
- * See svn_wc__wq_remove_revert_files() which generates this work item.
- * Implements (struct work_item_dispatch).func. */
-static svn_error_t *
-run_remove_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;
-  const char *revert_file;
-  svn_node_kind_t kind;
-
-  /* We need a NUL-terminated path, so copy it out of the skel.  */
-  local_abspath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
-
-  SVN_ERR(svn_wc__text_revert_path(&revert_file, db, local_abspath,
-                                   scratch_pool));
-
-  SVN_ERR(svn_io_check_path(revert_file, &kind, scratch_pool));
-  if (kind == svn_node_file)
-    SVN_ERR(svn_io_remove_file2(revert_file, FALSE, scratch_pool));
-
-  SVN_ERR(svn_wc__props_delete(db, local_abspath, svn_wc__props_revert,
-                               scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_wc__wq_remove_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_REMOVE_REVERT_FILES, work_item, scratch_pool);
-
-  SVN_ERR(svn_wc__db_wq_add(db, local_abspath, work_item, scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-
-/* ------------------------------------------------------------------------ */
-
 /* OP_KILLME  */
 
 /* Process the OP_KILLME work item WORK_ITEM.
@@ -877,6 +855,7 @@ run_killme(svn_wc__db_t *db,
                 repos_relpath, repos_root_url, repos_uuid,
                 original_revision, svn_wc__db_kind_dir,
                 svn_wc__db_status_not_present,
+                NULL, NULL,
                 scratch_pool));
     }
 
@@ -932,20 +911,25 @@ run_loggy(svn_wc__db_t *db,
 
 
 svn_error_t *
-svn_wc__wq_add_loggy(svn_wc__db_t *db,
-                     const char *adm_abspath,
-                     const svn_stringbuf_t *log_content,
-                     apr_pool_t *scratch_pool)
+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)
 {
-  svn_skel_t *work_item = svn_skel__make_empty_list(scratch_pool);
+  if (log_content == NULL || svn_stringbuf_isempty(log_content))
+    {
+      *work_item = NULL;
+      return SVN_NO_ERROR;
+    }
 
-  /* The skel still points at ADM_ABSPATH and LOG_CONTENT, but the skel will
-     be serialized just below in the wq_add call.  */
-  svn_skel__prepend_str(log_content->data, work_item, scratch_pool);
-  svn_skel__prepend_str(adm_abspath, work_item, scratch_pool);
-  svn_skel__prepend_str(OP_LOGGY, work_item, scratch_pool);
+  *work_item = svn_skel__make_empty_list(result_pool);
 
-  SVN_ERR(svn_wc__db_wq_add(db, adm_abspath, work_item, scratch_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);
 
   return SVN_NO_ERROR;
 }
@@ -1004,11 +988,11 @@ run_deletion_postcommit(svn_wc__db_t *db
              the directory can also place a 'deleted' dir entry in the
              parent. */
           tmp_entry.revision = new_revision;
-          SVN_ERR(svn_wc__entry_modify2(db, local_abspath,
-                                        svn_node_dir, FALSE,
-                                        &tmp_entry,
-                                        SVN_WC__ENTRY_MODIFY_REVISION,
-                                        scratch_pool));
+          SVN_ERR(svn_wc__entry_modify(db, local_abspath,
+                                       svn_node_dir,
+                                       &tmp_entry,
+                                       SVN_WC__ENTRY_MODIFY_REVISION,
+                                       scratch_pool));
 
           SVN_ERR(svn_wc__db_temp_determine_keep_local(&keep_local, db,
                                                        local_abspath,
@@ -1052,6 +1036,7 @@ run_deletion_postcommit(svn_wc__db_t *db
                     repos_relpath, repos_root_url, repos_uuid,
                     new_revision, svn_wc__db_kind_file,
                     svn_wc__db_status_not_present,
+                    NULL, NULL,
                     scratch_pool));
         }
     }
@@ -1119,6 +1104,8 @@ install_committed_file(svn_boolean_t *ov
                        const char *tmp_text_base_abspath,
                        svn_boolean_t remove_executable,
                        svn_boolean_t remove_read_only,
+                       svn_cancel_func_t cancel_func,
+                       void *cancel_baton,
                        apr_pool_t *scratch_pool)
 {
   svn_boolean_t same, did_set;
@@ -1165,6 +1152,7 @@ install_committed_file(svn_boolean_t *ov
     SVN_ERR(svn_wc__internal_translated_file(&tmp_wfile, tmp, db,
                                              file_abspath,
                                              SVN_WC_TRANSLATE_FROM_NF,
+                                             cancel_func, cancel_baton,
                                              scratch_pool, scratch_pool));
 
     /* If the translation is a no-op, the text base and the working copy
@@ -1189,6 +1177,9 @@ install_committed_file(svn_boolean_t *ov
       *overwrote_working = TRUE;
     }
 
+  /* ### should be using OP_SYNC_FILE_FLAGS, or an internal version of
+     ### that here. do we need to set *OVERWROTE_WORKING?  */
+
   if (remove_executable)
     {
       /* No need to chmod -x on a new file: new files don't have it. */
@@ -1232,8 +1223,15 @@ install_committed_file(svn_boolean_t *ov
     }
 
   /* 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(file_abspath, tmp_text_base_abspath, scratch_pool));
+    SVN_ERR(svn_wc__sync_text_base(db, file_abspath, tmp_text_base_abspath,
+                                   scratch_pool));
+#endif
 
   return SVN_NO_ERROR;
 }
@@ -1258,40 +1256,59 @@ log_do_committed(svn_wc__db_t *db,
                  const svn_checksum_t *new_checksum,
                  apr_hash_t *new_dav_cache,
                  svn_boolean_t keep_changelist,
+                 svn_cancel_func_t cancel_func,
+                 void *cancel_baton,
                  apr_pool_t *scratch_pool)
 {
-  svn_error_t *err;
   apr_pool_t *pool = scratch_pool;
-  int is_this_dir;
+  svn_wc__db_kind_t kind;
+  svn_wc__db_status_t status;
   svn_boolean_t remove_executable = FALSE;
   svn_boolean_t set_read_write = FALSE;
-  const svn_wc_entry_t *orig_entry;
   svn_boolean_t prop_mods;
 
-  /*** Perform sanity checking operations ***/
+  /* ### this gets the *intended* kind. for now, this also matches any
+     ### potential BASE kind since we cannot change kinds.  */
+  SVN_ERR(svn_wc__db_read_info(
+            &status, &kind, NULL,
+            NULL, NULL, NULL, NULL, NULL, NULL,
+            NULL, NULL, NULL, NULL, NULL, NULL,
+            NULL, NULL, NULL, NULL,
+            NULL, NULL, NULL,
+            NULL, NULL,
+            db, local_abspath,
+            scratch_pool, scratch_pool));
 
-  /* Read the entry for the affected item.  If we can't find the
-     entry, or if the entry states that our item is not either "this
-     dir" or a file kind, perhaps this isn't really the entry our log
-     creator was expecting.  */
-  SVN_ERR(svn_wc__get_entry(&orig_entry, db, local_abspath, FALSE,
-                            svn_node_unknown, FALSE, pool, pool));
-
-  /* We should never be running a commit on a DELETED node, so if we see
-     this, then it (probably) means that a prior run has deleted this node.
-     There isn't anything more to do.  */
-  if (orig_entry->schedule == svn_wc_schedule_normal && orig_entry->deleted)
+  /* We should never be running a commit on a not-present node. If we see
+     this, then it (probably) means that a prior run has deleted this node,
+     and left the not-present behind. There isn't anything more to do.  */
+  if (status == svn_wc__db_status_not_present)
     return SVN_NO_ERROR;
 
-  is_this_dir = orig_entry->kind == svn_node_dir;
-
-  /* We shouldn't be in this function for schedule-delete nodes.  */
-  SVN_ERR_ASSERT(orig_entry->schedule != svn_wc_schedule_delete);
-
+  /* We shouldn't be in this function for deleted nodes. They are handled
+     by other processes.  */
+  SVN_ERR_ASSERT(status != svn_wc__db_status_deleted);
 
   /*** Mark the committed item committed-to-date ***/
 
-  /* If "this dir" has been replaced (delete + add), remove those of
+  /* ### this comment is quite old. originally, we looked for
+     ### schedule_replace here. that definition is:
+     ###
+     ### ((status == svn_wc__db_status_added
+     ###   || status == svn_wc__db_status_obstructed_add)
+     ###  && base_shadowed
+     ###  && base_status != svn_wc__db_status_not_present)
+     ###
+     ### An obstructed add cannot be committed, so we don't have to
+     ### worry about that.
+     ###
+     ### If the BASE node is not-present, then it has no children which
+     ### may be marked for deletion, so that won't contribute to this
+     ### loop either (ie. we won't accidentally remove something)
+     ###
+     ### Thus, we're simply looking for status == svn_wc__db_status_added
+
+     If "this dir" has been replaced (delete + add), remove those of
      its children that are marked for deletion.
 
      All its immmediate children *must* be either scheduled for deletion
@@ -1305,7 +1322,8 @@ log_do_committed(svn_wc__db_t *db,
      individual commit targets, and thus will be re-visited by
      log_do_committed().  Children which were marked for deletion,
      however, need to be outright removed from revision control.  */
-  if ((orig_entry->schedule == svn_wc_schedule_replace) && is_this_dir)
+
+  if (status == svn_wc__db_status_added && kind == svn_wc__db_kind_dir)
     {
       /* Loop over all children entries, look for items scheduled for
          deletion. */
@@ -1316,39 +1334,33 @@ log_do_committed(svn_wc__db_t *db,
       SVN_ERR(svn_wc__db_read_children(&children, db, local_abspath,
                                        pool, pool));
 
-      for(i = 0; i < children->nelts; i++)
+      for (i = 0; i < children->nelts; i++)
         {
           const char *child_name = APR_ARRAY_IDX(children, i, const char*);
           const char *child_abspath;
-          svn_wc__db_kind_t kind;
-          svn_wc__db_status_t status;
-          svn_boolean_t is_file;
+          svn_wc__db_status_t child_status;
 
           apr_pool_clear(iterpool);
           child_abspath = svn_dirent_join(local_abspath, child_name, iterpool);
 
-          SVN_ERR(svn_wc__db_read_kind(&kind, db, child_abspath, TRUE,
-                                       iterpool));
-
-          is_file = (kind == svn_wc__db_kind_file ||
-                     kind == svn_wc__db_kind_symlink);
-
-          SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL,
+          SVN_ERR(svn_wc__db_read_info(&child_status,
+                                       NULL, NULL, NULL, NULL, NULL,
                                        NULL, NULL, NULL, NULL, NULL, NULL,
                                        NULL, NULL, NULL, NULL, NULL, NULL,
                                        NULL, NULL, NULL, NULL, NULL, NULL,
                                        db, child_abspath, iterpool, iterpool));
 
-          if (! (status == svn_wc__db_status_deleted
-                || status == svn_wc__db_status_obstructed_delete) )
-            continue;
-
-          /* ### We pass NULL, NULL for cancel_func and cancel_baton below.
-             ### If they were available, it would be nice to use them. */
-          SVN_ERR(svn_wc__internal_remove_from_revision_control(
-                                    db, child_abspath,
-                                    FALSE, FALSE,
-                                    NULL, NULL, iterpool));
+          /* Committing a deletion should remove the local nodes.  */
+          if (child_status == svn_wc__db_status_deleted
+              || child_status == svn_wc__db_status_obstructed_delete)
+            {
+              SVN_ERR(svn_wc__internal_remove_from_revision_control(
+                        db, child_abspath,
+                        FALSE /* destroy_wf */,
+                        FALSE /* instant_error */,
+                        cancel_func, cancel_baton,
+                        iterpool));
+            }
         }
     }
 
@@ -1357,7 +1369,7 @@ log_do_committed(svn_wc__db_t *db,
   SVN_ERR(svn_wc__props_modified(&prop_mods, db, local_abspath, pool));
   if (prop_mods)
     {
-      if (orig_entry->kind == svn_node_file)
+      if (kind == svn_wc__db_kind_file)
         {
           /* Examine propchanges here before installing the new
              propbase.  If the executable prop was -deleted-, remember
@@ -1388,7 +1400,7 @@ log_do_committed(svn_wc__db_t *db,
     }
 
   /* If it's a file, install the tree changes and the file's text. */
-  if (orig_entry->kind == svn_node_file)
+  if (kind == svn_wc__db_kind_file)
     {
       svn_boolean_t overwrote_working;
       apr_finfo_t finfo;
@@ -1401,6 +1413,7 @@ log_do_committed(svn_wc__db_t *db,
                                        NULL /* new_children */,
                                        new_dav_cache,
                                        keep_changelist,
+                                       NULL /* work_items */,
                                        pool));
 
       /* Install the new file, which may involve expanding keywords.
@@ -1413,20 +1426,14 @@ log_do_committed(svn_wc__db_t *db,
          timestamp of the copy of this file in `tmp/text-base' (which
          by then will have moved to `text-base'. */
 
-      if ((err = install_committed_file(&overwrote_working, db,
-                                        local_abspath, tmp_text_base_abspath,
-                                        remove_executable, set_read_write,
-                                        pool)))
-        return svn_error_createf
-          (SVN_ERR_WC_BAD_ADM_LOG, err,
-           _("Error replacing text-base of '%s'"),
-           svn_dirent_local_style(local_abspath, pool));
-
-      if ((err = svn_io_stat(&finfo, local_abspath,
-                             APR_FINFO_MIN | APR_FINFO_LINK, pool)))
-        return svn_error_createf(SVN_ERR_WC_BAD_ADM_LOG, err,
-                                 _("Error getting 'affected time' of '%s'"),
-                                 svn_dirent_local_style(local_abspath, pool));
+      SVN_ERR(install_committed_file(&overwrote_working, db,
+                                     local_abspath, tmp_text_base_abspath,
+                                     remove_executable, set_read_write,
+                                     cancel_func, cancel_baton,
+                                     pool));
+
+      SVN_ERR(svn_io_stat(&finfo, local_abspath,
+                          APR_FINFO_MIN | APR_FINFO_LINK, pool));
 
       /* We will compute and modify the size and timestamp */
 
@@ -1441,23 +1448,15 @@ log_do_committed(svn_wc__db_t *db,
           /* The working copy file hasn't been overwritten, meaning
              we need to decide which timestamp to use. */
 
-          const char *base_abspath;
           apr_finfo_t basef_finfo;
           svn_boolean_t modified;
 
           /* If the working file was overwritten (due to re-translation)
              or touched (due to +x / -x), then use *that* textual
              timestamp instead. */
-          SVN_ERR(svn_wc__text_base_path(&base_abspath, db,
-                                         local_abspath, FALSE, pool));
-          err = svn_io_stat(&basef_finfo, base_abspath,
-                            APR_FINFO_MIN | APR_FINFO_LINK,
-                            pool);
-          if (err)
-            return svn_error_createf
-              (SVN_ERR_WC_BAD_ADM_LOG, err,
-               _("Error getting 'affected time' for '%s'"),
-               svn_dirent_local_style(base_abspath, pool));
+          SVN_ERR(svn_wc__get_pristine_text_status(&basef_finfo,
+                                                   db, local_abspath,
+                                                   pool, pool));
 
           /* Verify that the working file is the same as the base file
              by comparing file sizes, then timestamps and the contents
@@ -1469,16 +1468,14 @@ log_do_committed(svn_wc__db_t *db,
           modified = finfo.size != basef_finfo.size;
           if (finfo.mtime != basef_finfo.mtime && ! modified)
             {
-              err = svn_wc__internal_versioned_file_modcheck(&modified,
-                                                             db, local_abspath,
-                                                             base_abspath,
-                                                             FALSE, pool);
-              if (err)
-                return svn_error_createf
-                  (SVN_ERR_WC_BAD_ADM_LOG, err,
-                   _("Error comparing '%s' and '%s'"),
-                   svn_dirent_local_style(local_abspath, pool),
-                   svn_dirent_local_style(base_abspath, pool));
+              /* Compare the texts.  Don't use
+                 svn_wc__internal_text_modified_p's ability to compare
+                 against the *recorded* size and time stamp because that's
+                 not what we are interested in right here. */
+              SVN_ERR(svn_wc__internal_text_modified_p(
+                        &modified, db, local_abspath,
+                        TRUE /* force_comparison */,
+                        FALSE /* compare_textbases */, pool));
             }
           /* If they are the same, use the working file's timestamp,
              else use the base file's timestamp. */
@@ -1499,6 +1496,7 @@ log_do_committed(svn_wc__db_t *db,
                                    NULL /* new_children */,
                                    new_dav_cache,
                                    keep_changelist,
+                                   NULL /* work_items */,
                                    pool));
 
   /* For directories, we also have to reset the state in the parent's
@@ -1515,15 +1513,10 @@ log_do_committed(svn_wc__db_t *db,
       return SVN_NO_ERROR;
   }
 
-  /* Make sure our entry exists in the parent. */
+  /* Make sure we have a parent stub in a clean/unmodified state.  */
   {
-    const svn_wc_entry_t *dir_entry;
     svn_wc_entry_t tmp_entry;
 
-    /* Check if we have a valid record in our parent */
-    SVN_ERR(svn_wc__get_entry(&dir_entry, db, local_abspath,
-                              FALSE, svn_node_dir, TRUE, pool, pool));
-
     tmp_entry.schedule = svn_wc_schedule_normal;
     tmp_entry.copied = FALSE;
     tmp_entry.deleted = FALSE;
@@ -1531,16 +1524,13 @@ log_do_committed(svn_wc__db_t *db,
 
            If this fails for you in the transition to one DB phase, please
            run svn cleanup one level higher. */
-    err = svn_wc__entry_modify2(db, local_abspath, svn_node_dir,
-                                TRUE, &tmp_entry,
-                                (SVN_WC__ENTRY_MODIFY_SCHEDULE
-                                 | SVN_WC__ENTRY_MODIFY_COPIED
-                                 | SVN_WC__ENTRY_MODIFY_DELETED
-                                 | SVN_WC__ENTRY_MODIFY_FORCE),
-                                pool);
-    if (err != NULL)
-      return svn_error_createf(SVN_ERR_WC_BAD_ADM_LOG, err,
-                               _("Error modifying entry of '%s'"), "");
+    SVN_ERR(svn_wc__entry_modify_stub(db, local_abspath,
+                                      &tmp_entry,
+                                      (SVN_WC__ENTRY_MODIFY_SCHEDULE
+                                       | SVN_WC__ENTRY_MODIFY_COPIED
+                                       | SVN_WC__ENTRY_MODIFY_DELETED
+                                       | SVN_WC__ENTRY_MODIFY_FORCE),
+                                      pool));
   }
 
   return SVN_NO_ERROR;
@@ -1567,6 +1557,7 @@ run_postcommit(svn_wc__db_t *db,
   apr_hash_t *new_dav_cache;
   svn_boolean_t keep_changelist;
   const char *tmp_text_base_abspath;
+  svn_error_t *err;
 
   local_abspath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
   new_revision = (svn_revnum_t)svn_skel__parse_int(arg1->next, scratch_pool);
@@ -1593,6 +1584,10 @@ run_postcommit(svn_wc__db_t *db,
     SVN_ERR(svn_skel__parse_proplist(&new_dav_cache, arg5->next,
                                      scratch_pool));
   keep_changelist = svn_skel__parse_int(arg5->next->next, scratch_pool) != 0;
+
+  /* Before r927056, this WQ item didn't have this next field.  Catch any
+   * attempt to run this code on a WC having a stale WQ item in it. */
+  SVN_ERR_ASSERT(arg5->next->next->next != NULL);
   if (arg5->next->next->next->len == 0)
     tmp_text_base_abspath = NULL;
   else
@@ -1600,11 +1595,17 @@ run_postcommit(svn_wc__db_t *db,
                                            arg5->next->next->next->data,
                                            arg5->next->next->next->len);
 
-  SVN_ERR(log_do_committed(db, local_abspath, tmp_text_base_abspath,
-                           new_revision, new_date,
-                           new_author, new_checksum, new_dav_cache,
-                           keep_changelist,
-                           scratch_pool));
+  err = log_do_committed(db, local_abspath, tmp_text_base_abspath,
+                         new_revision, new_date,
+                         new_author, new_checksum, new_dav_cache,
+                         keep_changelist,
+                         cancel_func, cancel_baton,
+                         scratch_pool);
+  if (err)
+    return svn_error_createf(SVN_ERR_WC_BAD_ADM_LOG, err,
+                             _("Error processing post-commit work for '%s'"),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -1659,6 +1660,9 @@ 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. */
@@ -1673,9 +1677,6 @@ run_install_properties(svn_wc__db_t *db,
   const char *local_abspath;
   apr_hash_t *base_props;
   apr_hash_t *actual_props;
-  svn_wc__db_kind_t kind;
-  const char *prop_abspath;
-  svn_boolean_t force_base_install;
 
   /* We need a NUL-terminated path, so copy it out of the skel.  */
   local_abspath = apr_pstrmemdup(scratch_pool, arg->data, arg->len);
@@ -1692,36 +1693,10 @@ run_install_properties(svn_wc__db_t *db,
   else
     SVN_ERR(svn_skel__parse_proplist(&actual_props, arg, scratch_pool));
 
-  arg = arg->next;
-  force_base_install = arg && svn_skel__parse_int(arg, scratch_pool);
-
-  SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, FALSE, scratch_pool));
   if (base_props != NULL)
     {
-      SVN_ERR(svn_wc__prop_path(&prop_abspath, local_abspath, kind,
-                                svn_wc__props_base, scratch_pool));
-
-      SVN_ERR(svn_io_remove_file2(prop_abspath, TRUE, scratch_pool));
-
-      if (apr_hash_count(base_props) > 0)
-        {
-          svn_stream_t *propfile;
-
-          SVN_ERR(svn_stream_open_writable(&propfile, prop_abspath,
-                                           scratch_pool, scratch_pool));
-
-          SVN_ERR(svn_hash_write2(base_props, propfile, SVN_HASH_TERMINATOR,
-                                  scratch_pool));
-
-          SVN_ERR(svn_stream_close(propfile));
-
-          SVN_ERR(svn_io_set_file_read_only(prop_abspath, FALSE, scratch_pool));
-        }
-
-      {
         svn_boolean_t written = FALSE;
 
-        if (!force_base_install)
           {
             svn_error_t *err;
 
@@ -1746,31 +1721,11 @@ run_install_properties(svn_wc__db_t *db,
         if (!written)
           SVN_ERR(svn_wc__db_temp_base_set_props(db, local_abspath,
                                                  base_props, scratch_pool));
-      }
-    }
-
-
-  SVN_ERR(svn_wc__prop_path(&prop_abspath, local_abspath, kind,
-                            svn_wc__props_working, scratch_pool));
-
-  SVN_ERR(svn_io_remove_file2(prop_abspath, TRUE, scratch_pool));
-
-  if (actual_props != NULL)
-    {
-      svn_stream_t *propfile;
-
-      SVN_ERR(svn_stream_open_writable(&propfile, prop_abspath,
-                                       scratch_pool, scratch_pool));
-
-      SVN_ERR(svn_hash_write2(actual_props, propfile, SVN_HASH_TERMINATOR,
-                              scratch_pool));
-
-      SVN_ERR(svn_stream_close(propfile));
-      SVN_ERR(svn_io_set_file_read_only(prop_abspath, FALSE, scratch_pool));
     }
 
+  /* Okay. It's time to save the ACTUAL props.  */
   SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, actual_props,
-                                  scratch_pool));
+                                  NULL, NULL, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -1781,14 +1736,11 @@ svn_wc__wq_add_install_properties(svn_wc
                                   const char *local_abspath,
                                   apr_hash_t *base_props,
                                   apr_hash_t *actual_props,
-                                  svn_boolean_t force_base_install,
                                   apr_pool_t *scratch_pool)
 {
   svn_skel_t *work_item = svn_skel__make_empty_list(scratch_pool);
   svn_skel_t *props;
 
-  svn_skel__prepend_int(force_base_install, work_item, scratch_pool);
-
   if (actual_props != NULL)
     {
       SVN_ERR(svn_skel__unparse_proplist(&props, actual_props, scratch_pool));
@@ -1813,6 +1765,8 @@ svn_wc__wq_add_install_properties(svn_wc
   return SVN_NO_ERROR;
 }
 
+#endif /* SVN__SUPPORT_BASE_MERGE  */
+
 
 /* ------------------------------------------------------------------------ */
 
@@ -1845,6 +1799,7 @@ run_delete(svn_wc__db_t *db,
 
   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,
@@ -1852,18 +1807,22 @@ run_delete(svn_wc__db_t *db,
       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,
-                                         FALSE, scratch_pool));
+                                         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;
@@ -1876,6 +1835,7 @@ run_delete(svn_wc__db_t *db,
       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;
 }
@@ -2016,8 +1976,7 @@ run_file_install(svn_wc__db_t *db,
   SVN_ERR(svn_io_file_rename(dst_abspath, local_abspath, scratch_pool));
 
   /* Tweak the on-disk file according to its properties.  */
-  SVN_ERR(svn_wc__maybe_set_read_only(NULL, db, local_abspath, scratch_pool));
-  SVN_ERR(svn_wc__maybe_set_executable(NULL, db, local_abspath, scratch_pool));
+  SVN_ERR(sync_file_flags(db, local_abspath, scratch_pool));
 
   if (use_commit_times)
     {
@@ -2040,24 +1999,11 @@ run_file_install(svn_wc__db_t *db,
   /* ### this should happen before we rename the file into place.  */
   if (record_fileinfo)
     {
-      apr_time_t last_mod_time;
-      apr_finfo_t finfo;
-
-      /* loggy_set_entry_timestamp_from_wc()  */
-      SVN_ERR(svn_io_file_affected_time(&last_mod_time,
-                                        local_abspath,
-                                        scratch_pool));
-
-      /* loggy_set_entry_working_size_from_wc()  */
-      SVN_ERR(svn_io_stat(&finfo, local_abspath,
-                          APR_FINFO_MIN | APR_FINFO_LINK,
-                          scratch_pool));
-
-      SVN_ERR(svn_wc__db_global_record_fileinfo(db, local_abspath,
-                                                finfo.size, last_mod_time,
-                                                scratch_pool));
+      SVN_ERR(get_and_record_fileinfo(db, local_abspath,
+                                      FALSE /* ignore_enoent */,
+                                      scratch_pool));
 
-      /* ### there used to be a call to entry_modify2() here, to set the
+      /* ### there used to be a call to entry_modify() above, to set the
          ### TRANSLATED_SIZE and LAST_MOD_TIME values. that function elided
          ### copyfrom information that snuck into the database. it should
          ### not be there in the first place, but we can manually get rid
@@ -2070,7 +2016,7 @@ run_file_install(svn_wc__db_t *db,
 
 
 svn_error_t *
-svn_wc__wq_build_file_install(const svn_skel_t **work_item,
+svn_wc__wq_build_file_install(svn_skel_t **work_item,
                               svn_wc__db_t *db,
                               const char *local_abspath,
                               const char *source_abspath,
@@ -2079,22 +2025,19 @@ svn_wc__wq_build_file_install(const svn_
                               apr_pool_t *result_pool,
                               apr_pool_t *scratch_pool)
 {
-  svn_skel_t *build_item = svn_skel__make_empty_list(result_pool);
+  *work_item = svn_skel__make_empty_list(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.  */
   if (source_abspath != NULL)
     svn_skel__prepend_str(apr_pstrdup(result_pool, source_abspath),
-                          build_item, result_pool);
+                          *work_item, result_pool);
 
-  svn_skel__prepend_int(record_fileinfo, build_item, result_pool);
-  svn_skel__prepend_int(use_commit_times, build_item, result_pool);
+  svn_skel__prepend_int(record_fileinfo, *work_item, result_pool);
+  svn_skel__prepend_int(use_commit_times, *work_item, result_pool);
   svn_skel__prepend_str(apr_pstrdup(result_pool, local_abspath),
-                        build_item, result_pool);
-  svn_skel__prepend_str(OP_FILE_INSTALL, build_item, result_pool);
-
-  /* Done. Assign to the const-ful WORK_ITEM.  */
-  *work_item = build_item;
+                        *work_item, result_pool);
+  svn_skel__prepend_str(OP_FILE_INSTALL, *work_item, result_pool);
 
   return SVN_NO_ERROR;
 }
@@ -2126,20 +2069,242 @@ run_file_remove(svn_wc__db_t *db,
 
 
 svn_error_t *
-svn_wc__wq_build_file_remove(const svn_skel_t **work_item,
+svn_wc__wq_build_file_remove(svn_skel_t **work_item,
                              svn_wc__db_t *db,
                              const char *local_abspath,
                              apr_pool_t *result_pool,
                              apr_pool_t *scratch_pool)
 {
-  svn_skel_t *build_item = svn_skel__make_empty_list(result_pool);
+  *work_item = svn_skel__make_empty_list(result_pool);
 
   svn_skel__prepend_str(apr_pstrdup(result_pool, local_abspath),
-                        build_item, result_pool);
-  svn_skel__prepend_str(OP_FILE_REMOVE, build_item, result_pool);
+                        *work_item, result_pool);
+  svn_skel__prepend_str(OP_FILE_REMOVE, *work_item, result_pool);
+
+  return SVN_NO_ERROR;
+}
+
+
+/* ------------------------------------------------------------------------ */
+
+/* OP_SYNC_FILE_FLAGS  */
+
+/* Process the OP_SYNC_FILE_FLAGS work item WORK_ITEM.
+ * See svn_wc__wq_build_sync_file_flags() which generates this work item.
+ * Implements (struct work_item_dispatch).func. */
+static svn_error_t *
+run_sync_file_flags(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(sync_file_flags(db, local_abspath, scratch_pool));
+}
+
+
+svn_error_t *
+svn_wc__wq_build_sync_file_flags(svn_skel_t **work_item,
+                                 svn_wc__db_t *db,
+                                 const char *local_abspath,
+                                 apr_pool_t *result_pool,
+                                 apr_pool_t *scratch_pool)
+{
+  *work_item = svn_skel__make_empty_list(result_pool);
+
+  svn_skel__prepend_str(apr_pstrdup(result_pool, local_abspath),
+                        *work_item, result_pool);
+  svn_skel__prepend_str(OP_SYNC_FILE_FLAGS, *work_item, result_pool);
+
+  return SVN_NO_ERROR;
+}
+
+
+/* ------------------------------------------------------------------------ */
 
-  /* Done. Assign to the const-ful WORK_ITEM.  */
-  *work_item = build_item;
+/* OP_PREJ_INSTALL  */
+
+static svn_error_t *
+run_prej_install(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;
+  const svn_skel_t *conflict_skel;
+  const char *tmp_prejfile_abspath;
+  const char *prejfile_abspath;
+
+  local_abspath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
+  if (arg1->next != NULL)
+    conflict_skel = arg1->next;
+  else
+    SVN_ERR_MALFUNCTION();  /* ### wc_db can't provide it ... yet.  */
+
+  /* Construct a property reject file in the temporary area.  */
+  SVN_ERR(svn_wc__create_prejfile(&tmp_prejfile_abspath,
+                                  db, local_abspath,
+                                  conflict_skel,
+                                  scratch_pool, scratch_pool));
+
+  /* Get the (stored) name of where it should go.  */
+  SVN_ERR(svn_wc__get_prejfile_abspath(&prejfile_abspath, db, local_abspath,
+                                       scratch_pool, scratch_pool));
+  SVN_ERR_ASSERT(prejfile_abspath != NULL);
+
+  /* ... and atomically move it into place.  */
+  SVN_ERR(svn_io_file_rename(tmp_prejfile_abspath,
+                             prejfile_abspath,
+                             scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
+svn_wc__wq_build_prej_install(svn_skel_t **work_item,
+                              svn_wc__db_t *db,
+                              const char *local_abspath,
+                              const svn_skel_t *conflict_skel,
+                              apr_pool_t *result_pool,
+                              apr_pool_t *scratch_pool)
+{
+  *work_item = svn_skel__make_empty_list(result_pool);
+
+  /* ### gotta have this, today  */
+  SVN_ERR_ASSERT(conflict_skel != NULL);
+
+  if (conflict_skel != NULL)
+    /* ### woah! this needs to dup the skel into RESULT_POOL  */
+    svn_skel__prepend((svn_skel_t *)conflict_skel, *work_item);
+  svn_skel__prepend_str(apr_pstrdup(result_pool, local_abspath),
+                        *work_item, result_pool);
+  svn_skel__prepend_str(OP_PREJ_INSTALL, *work_item, result_pool);
+
+  return SVN_NO_ERROR;
+}
+
+
+/* ------------------------------------------------------------------------ */
+
+/* OP_WRITE_OLD_PROPS  */
+
+
+static svn_error_t *
+run_write_old_props(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 *props_abspath;
+  svn_stream_t *stream;
+  apr_hash_t *props;
+
+  props_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 == NULL)
+    {
+      /* 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_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));
+
+  if (props != NULL)
+    {
+      svn_skel_t *props_skel;
+
+      SVN_ERR(svn_skel__unparse_proplist(&props_skel, props, result_pool));
+      svn_skel__prepend(props_skel, *work_item);
+    }
+  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 */,
+                                                  scratch_pool));
+}
+
+
+svn_error_t *
+svn_wc__wq_build_record_fileinfo(svn_skel_t **work_item,
+                                 const char *local_abspath,
+                                 apr_pool_t *result_pool)
+{
+  *work_item = svn_skel__make_empty_list(result_pool);
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+
+  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);
 
   return SVN_NO_ERROR;
 }
@@ -2150,21 +2315,74 @@ svn_wc__wq_build_file_remove(const svn_s
 static const struct work_item_dispatch dispatch_table[] = {
   { OP_REVERT, run_revert },
   { OP_PREPARE_REVERT_FILES, run_prepare_revert_files },
-  { OP_REMOVE_REVERT_FILES, run_remove_revert_files },
   { OP_KILLME, run_killme },
   { OP_LOGGY, run_loggy },
   { OP_DELETION_POSTCOMMIT, run_deletion_postcommit },
   { OP_POSTCOMMIT, run_postcommit },
-  { OP_INSTALL_PROPERTIES, run_install_properties },
   { OP_DELETE, run_delete },
   { OP_FILE_INSTALL, run_file_install },
   { OP_FILE_REMOVE, run_file_remove },
+  { 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 },
+
+/* See props.h  */
+#ifdef SVN__SUPPORT_BASE_MERGE
+  { OP_INSTALL_PROPERTIES, run_install_properties },
+#endif
 
   /* Sentinel.  */
   { NULL }
 };
 
 
+static svn_error_t *
+dispatch_work_item(svn_wc__db_t *db,
+                   const char *wri_abspath,
+                   const svn_skel_t *work_item,
+                   svn_cancel_func_t cancel_func,
+                   void *cancel_baton,
+                   apr_pool_t *scratch_pool)
+{
+  const struct work_item_dispatch *scan;
+
+  /* Scan the dispatch table for a function to handle this work item.  */
+  for (scan = &dispatch_table[0]; scan->name != NULL; ++scan)
+    {
+      if (svn_skel__matches_atom(work_item->children, scan->name))
+        {
+
+#ifdef DEBUG_WORK_QUEUE
+          SVN_DBG(("dispatch: operation='%s'\n", scan->name));
+#endif
+          SVN_ERR((*scan->func)(db, work_item,
+                                cancel_func, cancel_baton,
+                                scratch_pool));
+          break;
+        }
+    }
+
+  if (scan->name == NULL)
+    {
+      /* We should know about ALL possible work items here. If we do not,
+         then something is wrong. Most likely, some kind of format/code
+         skew. There is nothing more we can do. Erasing or ignoring this
+         work item could leave the WC in an even more broken state.
+
+         Contrary to issue #1581, we cannot simply remove work items and
+         continue, so bail out with an error.  */
+      return svn_error_createf(SVN_ERR_WC_BAD_ADM_LOG, NULL,
+                               _("Unrecognized work item in the queue "
+                                 "associated with '%s'"),
+                               svn_dirent_local_style(wri_abspath,
+                                                      scratch_pool));
+    }
+
+  return SVN_NO_ERROR;
+}
+
+
 svn_error_t *
 svn_wc__wq_run(svn_wc__db_t *db,
                const char *wri_abspath,
@@ -2174,12 +2392,15 @@ svn_wc__wq_run(svn_wc__db_t *db,
 {
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
 
+#ifdef DEBUG_WORK_QUEUE
+  SVN_DBG(("wq_run: wri='%s'\n", wri_abspath));
+#endif
+
   while (TRUE)
     {
       svn_wc__db_kind_t kind;
       apr_uint64_t id;
       svn_skel_t *work_item;
-      const struct work_item_dispatch *scan;
 
       /* Stop work queue processing, if requested. A future 'svn cleanup'
          should be able to continue the processing.  */
@@ -2201,37 +2422,61 @@ svn_wc__wq_run(svn_wc__db_t *db,
       if (work_item == NULL)
         break;
 
-      /* Scan the dispatch table for a function to handle this work item.  */
-      for (scan = &dispatch_table[0]; scan->name != NULL; ++scan)
-        {
-          if (svn_skel__matches_atom(work_item->children, scan->name))
-            {
-              SVN_ERR((*scan->func)(db, work_item,
-                                    cancel_func, cancel_baton,
-                                    iterpool));
-              break;
-            }
-        }
-
-      if (scan->name == NULL)
-        {
-          /* We should know about ALL possible work items here. If we do not,
-             then something is wrong. Most likely, some kind of format/code
-             skew. There is nothing more we can do. Erasing or ignoring this
-             work item could leave the WC in an even more broken state.
-
-             Contrary to issue #1581, we cannot simply remove work items and
-             continue, so bail out with an error.  */
-          return svn_error_createf(SVN_ERR_WC_BAD_ADM_LOG, NULL,
-                                   _("Unrecognized work item in the queue "
-                                     "associated with '%s'"),
-                                   svn_dirent_local_style(wri_abspath,
-                                                          iterpool));
-        }
+      SVN_ERR(dispatch_work_item(db, wri_abspath, work_item,
+                                 cancel_func, cancel_baton, iterpool));
 
+      /* The work item finished without error. Mark it completed.  */
       SVN_ERR(svn_wc__db_wq_completed(db, wri_abspath, id, iterpool));
     }
 
   svn_pool_destroy(iterpool);
   return SVN_NO_ERROR;
 }
+
+
+svn_skel_t *
+svn_wc__wq_merge(svn_skel_t *work_item1,
+                 svn_skel_t *work_item2,
+                 apr_pool_t *result_pool)
+{
+  /* If either argument is NULL, then just return the other.  */
+  if (work_item1 == NULL)
+    return work_item2;
+  if (work_item2 == NULL)
+    return work_item1;
+
+  /* We have two items. Figure out how to join them.  */
+  if (SVN_WC__SINGLE_WORK_ITEM(work_item1))
+    {
+      if (SVN_WC__SINGLE_WORK_ITEM(work_item2))
+        {
+          /* Both are singular work items. Construct a list, then put
+             both work items into it (in the proper order).  */
+
+          svn_skel_t *result = svn_skel__make_empty_list(result_pool);
+
+          svn_skel__prepend(work_item2, result);
+          svn_skel__prepend(work_item1, result);
+          return result;
+        }
+
+      /* WORK_ITEM2 is a list of work items. We can simply shove WORK_ITEM1
+         in the front to keep the ordering.  */
+      svn_skel__prepend(work_item1, work_item2);
+      return work_item2;
+    }
+  /* WORK_ITEM1 is a list of work items.  */
+
+  if (SVN_WC__SINGLE_WORK_ITEM(work_item2))
+    {
+      /* Put WORK_ITEM2 onto the end of the WORK_ITEM1 list.  */
+      svn_skel__append(work_item1, work_item2);
+      return work_item1;
+    }
+
+  /* We have two lists of work items. We need to chain all of the work
+     items into one big list. We will leave behind the WORK_ITEM2 skel,
+     as we only want its children.  */
+  svn_skel__append(work_item1, work_item2->children);
+  return work_item1;
+}

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=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/workqueue.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/workqueue.h Tue Aug 10 20:55:56 2010
@@ -52,6 +52,34 @@ extern "C" {
 #endif /* __cplusplus */
 
 
+/* Returns TRUE if WI refers to a single work item. Returns FALSE if
+   WI is a list of work items. WI must not be NULL.
+
+   A work item looks like: (OP_CODE arg1 arg2 ...)
+
+   If we see OP_CODE (an atom) as WI's first child, then this is a
+   single work item. Otherwise, it is a list of work items.  */
+#define SVN_WC__SINGLE_WORK_ITEM(wi) ((wi)->children->is_atom)
+
+
+/* Combine WORK_ITEM1 and WORK_ITEM2 into a single, resulting work item.
+
+   Each of the WORK_ITEM parameters may have one of three values:
+
+     NULL                          no work item
+     (OPCODE arg1 arg2 ...)        single work item
+     ((OPCODE ...) (OPCODE ...))   multiple work items
+
+   These will be combined as appropriate, and returned in one of the
+   above three styles.
+
+   The resulting list will be ordered: WORK_ITEM1 first, then WORK_ITEM2  */
+svn_skel_t *
+svn_wc__wq_merge(svn_skel_t *work_item1,
+                 svn_skel_t *work_item2,
+                 apr_pool_t *result_pool);
+
+
 /* For the WCROOT identified by the DB and WRI_ABSPATH pair, run any
    work items that may be present in its workqueue.  */
 svn_error_t *
@@ -62,7 +90,7 @@ svn_wc__wq_run(svn_wc__db_t *db,
                apr_pool_t *scratch_pool);
 
 
-/* Build a work item (returned in *WORK_ITEM) that will install the working
+/* Set *WORK_ITEM to a new work item that will install the working
    copy file at LOCAL_ABSPATH. If USE_COMMIT_TIMES is TRUE, then the newly
    installed file will use the nodes CHANGE_DATE for the file timestamp.
    If RECORD_FILEINFO is TRUE, then the resulting LAST_MOD_TIME and
@@ -75,7 +103,7 @@ svn_wc__wq_run(svn_wc__db_t *db,
    temporary file, and an OP_FILE_REMOVE will be queued to later remove it.
 */
 svn_error_t *
-svn_wc__wq_build_file_install(const svn_skel_t **work_item,
+svn_wc__wq_build_file_install(svn_skel_t **work_item,
                               svn_wc__db_t *db,
                               const char *local_abspath,
                               const char *source_abspath,
@@ -85,16 +113,62 @@ svn_wc__wq_build_file_install(const svn_
                               apr_pool_t *scratch_pool);
 
 
-/* Build a work item (returned in *WORK_ITEM) that will remove a single
+/* Set *WORK_ITEM to a new work item that will remove a single
    file.  */
 svn_error_t *
-svn_wc__wq_build_file_remove(const svn_skel_t **work_item,
+svn_wc__wq_build_file_remove(svn_skel_t **work_item,
                              svn_wc__db_t *db,
                              const char *local_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
+   by its properties and lock status.  */
+svn_error_t *
+svn_wc__wq_build_sync_file_flags(svn_skel_t **work_item,
+                                 svn_wc__db_t *db,
+                                 const char *local_abspath,
+                                 apr_pool_t *result_pool,
+                                 apr_pool_t *scratch_pool);
+
+
+/* Set *WORK_ITEM to a new work item that will install a property reject
+   file for LOCAL_ABSPATH into the working copy. The propety conflicts will
+   be taken from CONFLICT_SKEL, or if NULL, then from wc_db for the
+   given DB/LOCAL_ABSPATH.  */
+svn_error_t *
+svn_wc__wq_build_prej_install(svn_skel_t **work_item,
+                              svn_wc__db_t *db,
+                              const char *local_abspath,
+                              const svn_skel_t *conflict_skel,
+                              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.
+
+   ### 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_pool_t *result_pool);
+
+
 /* Record a work item to revert LOCAL_ABSPATH.  */
 svn_error_t *
 svn_wc__wq_add_revert(svn_boolean_t *will_revert,
@@ -111,13 +185,6 @@ svn_wc__wq_prepare_revert_files(svn_wc__
                                 const char *local_abspath,
                                 apr_pool_t *scratch_pool);
 
-/* Record a work item to remove the "revert props" and "revert text base"
-   for LOCAL_ABSPATH.  */
-svn_error_t *
-svn_wc__wq_remove_revert_files(svn_wc__db_t *db,
-                               const char *local_abspath,
-                               apr_pool_t *scratch_pool);
-
 
 /* Handle the old "KILLME" concept -- perform the actual deletion of a
    subdir (or just its admin area) during post-commit processing of a
@@ -129,12 +196,22 @@ svn_wc__wq_add_killme(svn_wc__db_t *db,
                       apr_pool_t *scratch_pool);
 
 
-/* ### temporary compat for mapping the old loggy into workqueue space.  */
+/* ### 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_add_loggy(svn_wc__db_t *db,
-                     const char *adm_abspath,
-                     const svn_stringbuf_t *log_content,
-                     apr_pool_t *scratch_pool);
+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);
 
 
 svn_error_t *
@@ -157,13 +234,16 @@ svn_wc__wq_add_postcommit(svn_wc__db_t *
                           svn_boolean_t keep_changelist,
                           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,
-                                  svn_boolean_t force_base_install,
                                   apr_pool_t *scratch_pool);
+#endif
 
 /* Add a work item to delete a node.
 

Modified: subversion/branches/ignore-mergeinfo/subversion/mod_authz_svn/mod_authz_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/mod_authz_svn/mod_authz_svn.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/mod_authz_svn/mod_authz_svn.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/mod_authz_svn/mod_authz_svn.c Tue Aug 10 20:55:56 2010
@@ -66,6 +66,9 @@ create_authz_svn_dir_config(apr_pool_t *
   authz_svn_config_rec *conf = apr_pcalloc(p, sizeof(*conf));
   conf->base_path = d;
 
+  if (d)
+    conf->base_path = svn_uri_canonicalize(d, p);
+
   /* By default keep the fortress secure */
   conf->authoritative = 1;
   conf->anonymous = 1;
@@ -210,6 +213,7 @@ req_check_access(request_rec *r,
   svn_authz_t *access_conf = NULL;
   svn_error_t *svn_err;
   char errbuf[256];
+  const char *canonicalized_uri;
   const char *username_to_authorize = get_username_to_authorize(r, conf);
 
   switch (r->method_number)
@@ -249,6 +253,22 @@ req_check_access(request_rec *r,
         break;
     }
 
+  canonicalized_uri = svn_uri_canonicalize(r->uri, r->pool);
+  if (strcmp(canonicalized_uri, conf->base_path) == 0)
+    {
+      /* Do no access control when conf->base_path(as configured in <Location>)
+       * and given uri are same. The reason for such relaxation of access
+       * control is "This module is meant to control access inside the
+       * repository path, in this case inside PATH is empty and hence
+       * dav_svn_split_uri fails saying no repository name present".
+       * One may ask it will allow access to '/' inside the repository if
+       * repository is served via SVNPath instead of SVNParentPath.
+       * It does not, The other methods(PROPFIND, MKACTIVITY) for
+       * accomplishing the operation takes care of making a request to
+       * proper URL */
+      return OK;
+    }
+
   dav_err = dav_svn_split_uri(r,
                               r->uri,
                               conf->base_path,
@@ -554,7 +574,7 @@ access_checker(request_rec *r)
 {
   authz_svn_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                     &authz_svn_module);
-  const char *repos_path;
+  const char *repos_path = NULL;
   const char *dest_repos_path = NULL;
   int status;
 
@@ -611,7 +631,7 @@ check_user_id(request_rec *r)
 {
   authz_svn_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                     &authz_svn_module);
-  const char *repos_path;
+  const char *repos_path = NULL;
   const char *dest_repos_path = NULL;
   int status;
 
@@ -639,7 +659,7 @@ auth_checker(request_rec *r)
 {
   authz_svn_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                     &authz_svn_module);
-  const char *repos_path;
+  const char *repos_path = NULL;
   const char *dest_repos_path = NULL;
   int status;
 

Modified: subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/dav_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/dav_svn.h?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/dav_svn.h Tue Aug 10 20:55:56 2010
@@ -271,6 +271,9 @@ struct dav_resource_private {
      interface (ie: /path/to/item?p=PEGREV]? */
   svn_boolean_t pegged;
 
+  /* Cache any revprop change error */
+  svn_error_t *revprop_error;
+
   /* Pool to allocate temporary data from */
   apr_pool_t *pool;
 };

Modified: subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/deadprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/deadprops.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/deadprops.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/deadprops.c Tue Aug 10 20:55:56 2010
@@ -54,8 +54,7 @@ struct dav_db {
 
 
 struct dav_deadprop_rollback {
-  dav_prop_name name;
-  svn_string_t value;
+  int dummy;
 };
 
 
@@ -219,6 +218,19 @@ save_value(dav_db *db, const dav_prop_na
                                                db->authz_read_baton,
                                                resource->pool);
 
+          /* Prepare any hook failure message to get sent over the wire */
+          serr = svn_error_purge_tracing(serr);
+          if (serr && serr->apr_err == SVN_ERR_REPOS_HOOK_FAILURE)
+            serr->message = apr_xml_quote_string(serr->pool, serr->message, 1);
+
+          /* mod_dav doesn't handle the returned error very well, it
+             generates its own generic error that will be returned to
+             the client.  Cache the detailed error here so that it can
+             be returned a second time when the rollback mechanism
+             triggers. */
+          if (serr)
+            resource->info->revprop_error = svn_error_dup(serr);
+
           /* Tell the logging subsystem about the revprop change. */
           dav_svn__operational_log(resource->info,
                                    svn_log__change_rev_prop(
@@ -661,19 +673,14 @@ db_get_rollback(dav_db *db,
                 const dav_prop_name *name,
                 dav_deadprop_rollback **prollback)
 {
-  dav_error *err;
-  dav_deadprop_rollback *ddp;
-  svn_string_t *propval;
-
-  if ((err = get_value(db, name, &propval)) != NULL)
-    return err;
+  /* This gets called by mod_dav in preparation for a revprop change.
+     mod_dav_svn doesn't need to make any changes during rollback, but
+     we want the rollback mechanism to trigger.  Making changes in
+     response to post-revprop-change hook errors would be positively
+     wrong. */
 
-  ddp = apr_palloc(db->p, sizeof(*ddp));
-  ddp->name = *name;
-  ddp->value.data = propval ? propval->data : NULL;
-  ddp->value.len = propval ? propval->len : 0;
+  *prollback = apr_palloc(db->p, sizeof(dav_deadprop_rollback));
 
-  *prollback = ddp;
   return NULL;
 }
 
@@ -681,12 +688,20 @@ db_get_rollback(dav_db *db,
 static dav_error *
 db_apply_rollback(dav_db *db, dav_deadprop_rollback *rollback)
 {
-  if (rollback->value.data == NULL)
-    {
-      return db_remove(db, &rollback->name);
-    }
+  dav_error *derr;
+
+  if (! db->resource->info->revprop_error)
+    return NULL;
+  
+  /* Returning the original revprop change error here will cause this
+     detailed error to get returned to the client in preference to the
+     more generic error created by mod_dav. */
+  derr = dav_svn__convert_err(db->resource->info->revprop_error,
+                              HTTP_INTERNAL_SERVER_ERROR, NULL,
+                              db->resource->pool);
+  db->resource->info->revprop_error = NULL;
 
-  return save_value(db, &rollback->name, &rollback->value);
+  return derr;
 }
 
 

Modified: subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/mirror.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/mirror.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/mirror.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/mirror.c Tue Aug 10 20:55:56 2010
@@ -163,9 +163,8 @@ apr_status_t dav_svn__location_in_filter
 
     /* We are url encoding the current url and the master url
        as incoming(from client) request body has it encoded already. */
-    canonicalized_uri = (char *) svn_path_uri_encode(canonicalized_uri,
-                                                     r->pool);
-    root_dir = (char *) svn_path_uri_encode(root_dir, r->pool);
+    canonicalized_uri = svn_path_uri_encode(canonicalized_uri, r->pool);
+    root_dir = svn_path_uri_encode(root_dir, r->pool);
     if (!f->ctx) {
         ctx = f->ctx = apr_pcalloc(r->pool, sizeof(*ctx));
         ctx->remotepath = canonicalized_uri;
@@ -224,7 +223,7 @@ apr_status_t dav_svn__location_header_fi
     /* Don't filter if we're in a subrequest or we aren't setup to
        proxy anything. */
     master_uri = dav_svn__get_master_uri(r);
-    master_uri = (char *) svn_path_uri_encode(master_uri, r->pool);
+    master_uri = svn_path_uri_encode(master_uri, r->pool);
     if (r->main || !master_uri) {
         ap_remove_output_filter(f);
         return ap_pass_brigade(f->next, bb);
@@ -242,7 +241,7 @@ apr_status_t dav_svn__location_header_fi
                                                dav_svn__get_root_dir(r), "/",
                                                start_foo, NULL),
                                    r);
-        new_uri = (char *) svn_path_uri_encode(new_uri, r->pool);
+        new_uri = svn_path_uri_encode(new_uri, r->pool);
         apr_table_set(r->headers_out, "Location", new_uri);
     }
     return ap_pass_brigade(f->next, bb);
@@ -286,9 +285,8 @@ apr_status_t dav_svn__location_body_filt
 
     /* We are url encoding the current url and the master url
        as incoming(from master) request body has it encoded already. */
-    canonicalized_uri = (char *) svn_path_uri_encode(canonicalized_uri,
-                                                     r->pool);
-    root_dir = (char *) svn_path_uri_encode(root_dir, r->pool);
+    canonicalized_uri = svn_path_uri_encode(canonicalized_uri, r->pool);
+    root_dir = svn_path_uri_encode(root_dir, r->pool);
     if (!f->ctx) {
         ctx = f->ctx = apr_pcalloc(r->pool, sizeof(*ctx));
         ctx->remotepath = canonicalized_uri;

Modified: subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/reports/dated-rev.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/reports/dated-rev.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/reports/dated-rev.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/reports/dated-rev.c Tue Aug 10 20:55:56 2010
@@ -1,5 +1,5 @@
 /*
- * version.c: mod_dav_svn versioning provider functions for Subversion
+ * dated-rev.c: mod_dav_svn REPORT handler for mapping a date to a revision
  *
  * ====================================================================
  *    Licensed to the Apache Software Foundation (ASF) under one

Modified: subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/reports/deleted-rev.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/reports/deleted-rev.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/reports/deleted-rev.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/reports/deleted-rev.c Tue Aug 10 20:55:56 2010
@@ -1,5 +1,6 @@
 /*
- * deleted-rev :  routine for getting the revision a path was deleted.
+ * deleted-rev.c: mod_dav_svn REPORT handler for getting the rev in
+ *                which a path was deleted
  *
  * ====================================================================
  *    Licensed to the Apache Software Foundation (ASF) under one

Modified: subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/reports/file-revs.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/reports/file-revs.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/reports/file-revs.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/reports/file-revs.c Tue Aug 10 20:55:56 2010
@@ -1,5 +1,6 @@
 /*
- * file_revs.c: handle the file-revs-report request and response
+ * file-revs.c: mod_dav_svn REPORT handler for transmitting a chain of
+ *              file revisions
  *
  * ====================================================================
  *    Licensed to the Apache Software Foundation (ASF) under one

Modified: subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/reports/get-location-segments.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/reports/get-location-segments.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/reports/get-location-segments.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/reports/get-location-segments.c Tue Aug 10 20:55:56 2010
@@ -1,6 +1,7 @@
 /*
- * get-location-segments.c: mod_dav_svn versioning provider functions
- *                          for Subversion's get-location-segments RA API.
+ * get-location-segments.c: mod_dav_svn REPORT handler for mapping
+ *                          revision ranges to path locations along
+ *                          the history of an object
  *
  * ====================================================================
  *    Licensed to the Apache Software Foundation (ASF) under one

Modified: subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/reports/get-locations.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/reports/get-locations.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/reports/get-locations.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/reports/get-locations.c Tue Aug 10 20:55:56 2010
@@ -1,5 +1,6 @@
 /*
- * get-locations.c:  generate the 'get locations' report response.
+ * get-locations.c: mod_dav_svn REPORT handler for finding repos locations
+ *                  (path/revision pairs) in an object's history.
  *
  * ====================================================================
  *    Licensed to the Apache Software Foundation (ASF) under one

Modified: subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/reports/get-locks.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/reports/get-locks.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/reports/get-locks.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/mod_dav_svn/reports/get-locks.c Tue Aug 10 20:55:56 2010
@@ -1,5 +1,5 @@
 /*
- * version.c: mod_dav_svn versioning provider functions for Subversion
+ * get-locks.c: mod_dav_svn REPORT handler for querying filesystem locks
  *
  * ====================================================================
  *    Licensed to the Apache Software Foundation (ASF) under one