You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by da...@apache.org on 2010/03/30 22:58:01 UTC

svn commit: r929279 [12/20] - in /subversion/branches/svn-patch-improvements: ./ build/ac-macros/ build/generator/ build/generator/templates/ contrib/client-side/emacs/ notes/feedback/ notes/meetings/ notes/wc-ng/ subversion/ subversion/bindings/javahl...

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/adm_files.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/adm_files.c?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/adm_files.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/adm_files.c Tue Mar 30 20:57:53 2010
@@ -223,33 +223,28 @@ make_adm_subdir(const char *path,
 /*** Syncing files in the adm area. ***/
 
 
-/* Rename a tmp text-base file to its real text-base name.
-   The file had better already be closed. */
 svn_error_t *
-svn_wc__sync_text_base(const char *path, apr_pool_t *pool)
+svn_wc__sync_text_base(const char *local_abspath,
+                       const char *tmp_text_base_abspath,
+                       apr_pool_t *pool)
 {
   const char *parent_path;
   const char *base_name;
-  const char *tmp_path;
   const char *base_path;
 
-  svn_dirent_split(path, &parent_path, &base_name, pool);
-
-  /* Extend tmp name. */
-  tmp_path = extend_with_adm_name(parent_path, SVN_WC__BASE_EXT, TRUE, pool,
-                                  SVN_WC__ADM_TEXT_BASE, base_name, NULL);
+  svn_dirent_split(local_abspath, &parent_path, &base_name, pool);
 
   /* Extend real name. */
   base_path = extend_with_adm_name(parent_path, SVN_WC__BASE_EXT, FALSE, pool,
                                    SVN_WC__ADM_TEXT_BASE, base_name, NULL);
 
   /* Rename. */
-  SVN_ERR(svn_io_file_rename(tmp_path, base_path, pool));
+  SVN_ERR(svn_io_file_rename(tmp_text_base_abspath, base_path, pool));
   return svn_io_set_file_read_only(base_path, FALSE, pool);
 }
 
 svn_error_t *
-svn_wc__text_base_path(const char **result_path,
+svn_wc__text_base_path(const char **result_abspath,
                        svn_wc__db_t *db,
                        const char *local_abspath,
                        svn_boolean_t tmp,
@@ -260,19 +255,19 @@ svn_wc__text_base_path(const char **resu
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
   svn_dirent_split(local_abspath, &newpath, &base_name, pool);
-  *result_path = extend_with_adm_name(newpath,
-                                      SVN_WC__BASE_EXT,
-                                      tmp,
-                                      pool,
-                                      SVN_WC__ADM_TEXT_BASE,
-                                      base_name,
-                                      NULL);
+  *result_abspath = extend_with_adm_name(newpath,
+                                         SVN_WC__BASE_EXT,
+                                         tmp,
+                                         pool,
+                                         SVN_WC__ADM_TEXT_BASE,
+                                         base_name,
+                                         NULL);
 
   return SVN_NO_ERROR;
 }
 
 svn_error_t *
-svn_wc__text_revert_path(const char **result_path,
+svn_wc__text_revert_path(const char **result_abspath,
                          svn_wc__db_t *db,
                          const char *local_abspath,
                          apr_pool_t *pool)
@@ -282,13 +277,13 @@ svn_wc__text_revert_path(const char **re
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
   svn_dirent_split(local_abspath, &newpath, &base_name, pool);
-  *result_path = extend_with_adm_name(newpath,
-                                      SVN_WC__REVERT_EXT,
-                                      FALSE,
-                                      pool,
-                                      SVN_WC__ADM_TEXT_BASE,
-                                      base_name,
-                                      NULL);
+  *result_abspath = extend_with_adm_name(newpath,
+                                         SVN_WC__REVERT_EXT,
+                                         FALSE,
+                                         pool,
+                                         SVN_WC__ADM_TEXT_BASE,
+                                         base_name,
+                                         NULL);
 
   return SVN_NO_ERROR;
 }
@@ -303,6 +298,8 @@ svn_wc__get_revert_contents(svn_stream_t
 {
   const char *revert_base;
 
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+
   SVN_ERR(svn_wc__text_revert_path(&revert_base, db, local_abspath,
                                    scratch_pool));
 
@@ -373,58 +370,6 @@ svn_wc__prop_path(const char **prop_path
 
 /*** Opening and closing files in the adm area. ***/
 
-/* Create and open a writable file in the admin temporary area of the WC
-   directory DIR_ABSPATH, in a subdirectory named SUBDIR (such as "text-base"),
-   with the name FNAME and extra EXTENSION (such as ".svn-base").  If the
-   file already exists, first delete it.  Set *STREAM to a writable stream
-   to this file, and (if SELECTED_ABSPATH is not NULL) set *SELECTED_PATH to
-   the path to this file, both allocated in RESULT_POOL.
-
-   Closing the stream will close (but not delete) the file. */
-static svn_error_t *
-open_adm_file(svn_stream_t **stream,
-              const char **selected_abspath,
-              const char *dir_abspath,
-              const char *subdir,
-              const char *fname,
-              const char *extension,
-              apr_pool_t *result_pool,
-              apr_pool_t *scratch_pool)
-{
-  svn_error_t *err;
-
-  /* Extend with tmp name. */
-  dir_abspath = extend_with_adm_name(dir_abspath, extension, TRUE, result_pool,
-                                     subdir, fname, NULL);
-  if (selected_abspath)
-    *selected_abspath = dir_abspath;  /* note: built in result_pool */
-
-  err = svn_stream_open_writable(stream, dir_abspath, result_pool, scratch_pool);
-  if (err && APR_STATUS_IS_EEXIST(err->apr_err))
-    {
-      /* Exclusive open failed, delete and retry */
-      svn_error_clear(err);
-      SVN_ERR(svn_io_remove_file2(dir_abspath, FALSE, scratch_pool));
-      err = svn_stream_open_writable(stream, dir_abspath, result_pool, scratch_pool);
-    }
-
-  /* Examine the error from the first and/or second attempt at opening. */
-  if (err && APR_STATUS_IS_ENOENT(err->apr_err))
-    {
-      /* If we receive a failure to open a file in our temporary directory,
-       * it may be because our temporary directories aren't created.
-       * Older SVN clients did not create these directories.
-       * 'svn cleanup' will fix this problem.
-       */
-      err = svn_error_quick_wrap(err,
-                                 _("Your .svn/tmp directory may be missing or "
-                                   "corrupt; run 'svn cleanup' and try again"));
-    }
-
-  return svn_error_return(err);
-}
-
-
 svn_error_t *
 svn_wc__open_adm_stream(svn_stream_t **stream,
                         const char *dir_abspath,
@@ -434,6 +379,8 @@ svn_wc__open_adm_stream(svn_stream_t **s
 {
   const char *local_abspath;
 
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(dir_abspath));
+
   local_abspath = svn_wc__adm_child(dir_abspath, fname, scratch_pool);
   return svn_error_return(svn_stream_open_readonly(stream, local_abspath,
                                                    result_pool, scratch_pool));
@@ -443,24 +390,24 @@ svn_wc__open_adm_stream(svn_stream_t **s
 svn_error_t *
 svn_wc__open_writable_base(svn_stream_t **stream,
                            const char **temp_base_abspath,
+                           svn_wc__db_t *db,
                            const char *local_abspath,
-                           svn_boolean_t need_revert_base,
                            apr_pool_t *result_pool,
                            apr_pool_t *scratch_pool)
 {
-  const char *parent_abspath;
-  const char *base_name;
-
-  svn_dirent_split(local_abspath, &parent_abspath, &base_name, scratch_pool);
+  const char *temp_dir_abspath;
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
-  return open_adm_file(stream, temp_base_abspath,
-                       parent_abspath,
-                       SVN_WC__ADM_TEXT_BASE,
-                       base_name,
-                       need_revert_base
-                         ? SVN_WC__REVERT_EXT
-                         : SVN_WC__BASE_EXT,
-                       result_pool, scratch_pool);
+  /* Select a directory in which to put a WC-1-style temp text-base file. */
+  /* See update_editor.c:get_pristine_tee_stream() for the WC-NG way. */
+  SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&temp_dir_abspath, db, local_abspath,
+                                         scratch_pool, scratch_pool));
+  SVN_ERR(svn_stream_open_unique(stream,
+                                 temp_base_abspath,
+                                 temp_dir_abspath,
+                                 svn_io_file_del_none,
+                                 result_pool, scratch_pool));
+  return SVN_NO_ERROR;
 }
 
 
@@ -468,6 +415,7 @@ svn_wc__open_writable_base(svn_stream_t 
 /*** Checking for and creating administrative subdirs. ***/
 
 
+/* */
 static svn_error_t *
 init_adm_tmp_area(const char *path, apr_pool_t *pool)
 {
@@ -623,6 +571,8 @@ svn_wc__adm_destroy(svn_wc__db_t *db,
 {
   const char *adm_abspath;
 
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(dir_abspath));
+
   SVN_ERR(svn_wc__write_check(db, dir_abspath, scratch_pool));
 
   /* Well, the coast is clear for blowing away the administrative
@@ -643,6 +593,8 @@ svn_wc__adm_cleanup_tmp_area(svn_wc__db_
 {
   const char *tmp_path;
 
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(adm_abspath));
+
   SVN_ERR(svn_wc__write_check(db, adm_abspath, scratch_pool));
 
   /* Get the path to the tmp area, and blow it away. */

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/adm_files.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/adm_files.h?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/adm_files.h (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/adm_files.h Tue Mar 30 20:57:53 2010
@@ -52,23 +52,27 @@ svn_boolean_t svn_wc__adm_area_exists(co
                                       apr_pool_t *pool);
 
 
-/* Atomically rename a temporary text-base file to its canonical
-   location.  PATH is the path of the working file whose text-base is
-   to be moved.  The tmp file should be closed already. */
+/* Atomically rename a temporary text-base file TMP_TEXT_BASE_ABSPATH to its
+   canonical location.  LOCAL_ABSPATH is the path of the working file whose
+   text-base is to be moved.  The tmp file should be closed already. */
 svn_error_t *
-svn_wc__sync_text_base(const char *path, apr_pool_t *pool);
+svn_wc__sync_text_base(const char *local_abspath,
+                       const char *tmp_text_base_path,
+                       apr_pool_t *pool);
 
 
-/* Set *RESULT_PATH to the absolute path to LOCAL_ABSPATH's text-base file,
+/* Set *RESULT_ABSPATH to the absolute path to LOCAL_ABSPATH's text-base file,
    or, if TMP is set, to its temporary text-base file. */
 svn_error_t *
-svn_wc__text_base_path(const char **result_path,
+svn_wc__text_base_path(const char **result_abspath,
                        svn_wc__db_t *db,
                        const char *local_abspath,
                        svn_boolean_t tmp,
                        apr_pool_t *pool);
 
-/* Set *CONTENTS to a readonly stream on the LOCAL_ABSPATH's base file. */
+/* Set *CONTENTS to a readonly stream on the LOCAL_ABSPATH's base file.
+ * For more detail, please see the description of
+ * svn_wc_get_pristine_contents2().*/
 svn_error_t *
 svn_wc__get_pristine_contents(svn_stream_t **contents,
                               svn_wc__db_t *db,
@@ -116,17 +120,17 @@ svn_error_t *svn_wc__open_adm_stream(svn
                                      apr_pool_t *scratch_pool);
 
 
-/* Open the normal or revert text base, associated with LOCAL_ABSPATH, for
-   writing.
-   The selection is based on NEED_REVERT_BASE. The opened stream will be
-   returned in STREAM and the selected path will be returned in,
-   TEMP_BASE_ABSPATH, and both will be allocated in RESULT_POOL. Any temporary
-   allocations will be performed in SCRATCH_POOL. */
+/* Open a writable stream to a temporary (normal or revert) text base,
+   associated with the versioned file LOCAL_ABSPATH in DB.  Set *STREAM to
+   the opened stream and *TEMP_BASE_ABSPATH to the path to the temporary
+   file, both allocated in RESULT_POOL.  The temporary file will have an
+   arbitrary unique name, in contrast to the deterministic name that
+   svn_wc__text_base_path(tmp=TRUE) returns. */
 svn_error_t *
 svn_wc__open_writable_base(svn_stream_t **stream,
                            const char **temp_base_abspath,
+                           svn_wc__db_t *db,
                            const char *local_abspath,
-                           svn_boolean_t need_revert_base,
                            apr_pool_t *result_pool,
                            apr_pool_t *scratch_pool);
 

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/adm_ops.c?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/adm_ops.c Tue Mar 30 20:57:53 2010
@@ -49,6 +49,7 @@
 #include "svn_xml.h"
 #include "svn_time.h"
 #include "svn_diff.h"
+#include "svn_sorts.h"
 
 #include "wc.h"
 #include "log.h"
@@ -68,15 +69,17 @@
 
 struct svn_wc_committed_queue_t
 {
+  /* The pool in which ->queue is allocated. */
   apr_pool_t *pool;
-  apr_array_header_t *queue;
+  /* Mapping (const char *) local_abspath to (committed_queue_item_t *). */
+  apr_hash_t *queue;
+  /* Is any item in the queue marked as 'recursive'? */
   svn_boolean_t have_recursive;
 };
 
 typedef struct
 {
-  const char *path;
-  const char *adm_abspath;
+  const char *local_abspath;
   svn_boolean_t recurse;
   svn_boolean_t no_unlock;
   svn_boolean_t keep_changelist;
@@ -85,6 +88,13 @@ typedef struct
 } committed_queue_item_t;
 
 
+apr_pool_t *
+svn_wc__get_committed_queue_pool(const struct svn_wc_committed_queue_t *queue)
+{
+  return queue->pool;
+}
+
+
 
 /*** Finishing updates and commits. ***/
 
@@ -316,6 +326,7 @@ svn_wc__do_update_cleanup(svn_wc__db_t *
 }
 
 
+/* */
 static svn_error_t *
 process_deletion_postcommit(svn_wc__db_t *db,
                             const char *adm_abspath,
@@ -334,10 +345,11 @@ process_deletion_postcommit(svn_wc__db_t
 }
 
 
+/* CHECKSUM is the checksum of the new text base for LOCAL_ABSPATH, and must
+ * be provided if there is one, else NULL. */
 static svn_error_t *
 process_committed_leaf(svn_wc__db_t *db,
-                       const char *adm_abspath,
-                       const char *path,
+                       const char *local_abspath,
                        svn_revnum_t new_revnum,
                        apr_time_t new_date,
                        const char *rev_author,
@@ -345,16 +357,15 @@ process_committed_leaf(svn_wc__db_t *db,
                        svn_boolean_t no_unlock,
                        svn_boolean_t keep_changelist,
                        const svn_checksum_t *checksum,
-                       const svn_wc_committed_queue_t *queue,
                        apr_pool_t *scratch_pool)
 {
-  const char *local_abspath;
   svn_wc__db_status_t status;
   svn_wc__db_kind_t kind;
   const svn_checksum_t *copied_checksum;
+  const char *adm_abspath;
+  const char *tmp_text_base_abspath;
 
-  SVN_ERR(svn_wc__write_check(db, adm_abspath, scratch_pool));
-  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
   SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL,
                                NULL, NULL, NULL,
@@ -366,6 +377,12 @@ process_committed_leaf(svn_wc__db_t *db,
                                db, local_abspath,
                                scratch_pool, scratch_pool));
 
+  if (kind == svn_wc__db_kind_dir)
+    adm_abspath = local_abspath;
+  else
+    adm_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
+  SVN_ERR(svn_wc__write_check(db, adm_abspath, scratch_pool));
+
   if (status == svn_wc__db_status_deleted
       || status == svn_wc__db_status_obstructed_delete)
     {
@@ -383,61 +400,51 @@ process_committed_leaf(svn_wc__db_t *db,
       /* ### don't directories have revert props? */
       SVN_ERR(svn_wc__wq_remove_revert_files(db, local_abspath, scratch_pool));
 
+      /* If we sent a delta (meaning: post-copy modification),
+         then this file will appear in the queue and so we should have
+         its checksum already. */
       if (checksum == NULL)
         {
-          /* checksum will be NULL for recursive commits, which means that
-             a directory was copied. When we recurse on that directory, the
-             checksum will be NULL for all files. */
-
-          /* If we sent a delta (meaning: post-copy modification),
-             then this file will appear in the queue.  See if we can
-             find it. */
-          int i;
-
-          /* ### this is inefficient. switch to hash. that's round #2 */
-
-          if (queue != NULL)
-            for (i = 0; i < queue->queue->nelts; i++)
-              {
-                const committed_queue_item_t *cqi
-                  = APR_ARRAY_IDX(queue->queue, i,
-                                  const committed_queue_item_t *);
-                if (strcmp(path, cqi->path) == 0)
-                  {
-                    checksum = cqi->checksum;
-                    break;
-                  }
-              }
-          if (checksum == NULL)
+          /* It was copied and not modified. We should have a text
+             base for it. And the entry should have a checksum. */
+          if (copied_checksum != NULL)
             {
-              /* It was copied and not modified. We should have a text
-                 base for it. And the entry should have a checksum. */
-              if (copied_checksum != NULL)
-                {
-                  checksum = copied_checksum;
-                }
+              checksum = copied_checksum;
+            }
 #ifdef SVN_DEBUG
-              else
-                {
-                  /* If we copy a deleted file, then it will become scheduled
-                     for deletion, but there is no base text for it. So we
-                     cannot get/compute a checksum for this file. */
-                  SVN_ERR_ASSERT(
-                    status == svn_wc__db_status_deleted
-                    || status == svn_wc__db_status_obstructed_delete);
+          else
+            {
+              /* If we copy a deleted file, then it will become scheduled
+                 for deletion, but there is no base text for it. So we
+                 cannot get/compute a checksum for this file. */
+              SVN_ERR_ASSERT(
+                status == svn_wc__db_status_deleted
+                || status == svn_wc__db_status_obstructed_delete);
 
-                  /* checksum will remain NULL in this one case. */
-                }
-#endif
+              /* checksum will remain NULL in this one case. */
             }
+#endif
         }
     }
 
   if (!no_unlock)
     SVN_ERR(svn_wc__loggy_delete_lock(db, adm_abspath,
-                                      path, scratch_pool));
+                                      local_abspath, scratch_pool));
+
+  /* Set TMP_TEXT_BASE_ABSPATH to the new text base to be installed, if any. */
+  {
+    svn_node_kind_t new_base_kind;
+
+    SVN_ERR(svn_wc__text_base_path(&tmp_text_base_abspath, db, local_abspath,
+                                   TRUE, scratch_pool));
+    SVN_ERR(svn_io_check_path(tmp_text_base_abspath, &new_base_kind,
+                              scratch_pool));
+    if (new_base_kind != svn_node_file)
+      tmp_text_base_abspath = NULL;
+  }
 
-  SVN_ERR(svn_wc__wq_add_postcommit(db, local_abspath, new_revnum,
+  SVN_ERR(svn_wc__wq_add_postcommit(db, local_abspath, tmp_text_base_abspath,
+                                    new_revnum,
                                     new_date, rev_author, checksum,
                                     new_dav_cache, keep_changelist,
                                     scratch_pool));
@@ -446,35 +453,29 @@ process_committed_leaf(svn_wc__db_t *db,
 }
 
 
-static svn_error_t *
-process_committed_internal(svn_wc__db_t *db,
-                           const char *adm_abspath,
-                           const char *path,
-                           svn_boolean_t recurse,
-                           svn_revnum_t new_revnum,
-                           apr_time_t new_date,
-                           const char *rev_author,
-                           apr_hash_t *new_dav_cache,
-                           svn_boolean_t no_unlock,
-                           svn_boolean_t keep_changelist,
-                           const svn_checksum_t *checksum,
-                           const svn_wc_committed_queue_t *queue,
-                           apr_pool_t *scratch_pool)
+svn_error_t *
+svn_wc__process_committed_internal(svn_wc__db_t *db,
+                                   const char *local_abspath,
+                                   svn_boolean_t recurse,
+                                   svn_revnum_t new_revnum,
+                                   apr_time_t new_date,
+                                   const char *rev_author,
+                                   apr_hash_t *new_dav_cache,
+                                   svn_boolean_t no_unlock,
+                                   svn_boolean_t keep_changelist,
+                                   const svn_checksum_t *checksum,
+                                   const svn_wc_committed_queue_t *queue,
+                                   apr_pool_t *scratch_pool)
 {
   svn_wc__db_kind_t kind;
-  const char *local_abspath;
-
-  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
 
   SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, TRUE, scratch_pool));
-  if (kind == svn_wc__db_kind_unknown)
-    return SVN_NO_ERROR;  /* deleted/absent. (?) ... nothing to do. */
 
-  SVN_ERR(process_committed_leaf(db, adm_abspath, path,
+  SVN_ERR(process_committed_leaf(db, local_abspath,
                                  new_revnum, new_date, rev_author,
                                  new_dav_cache,
                                  no_unlock, keep_changelist,
-                                 checksum, queue, scratch_pool));
+                                 checksum, scratch_pool));
 
   if (recurse && kind == svn_wc__db_kind_dir)
     {
@@ -499,7 +500,6 @@ process_committed_internal(svn_wc__db_t 
           const char *name = APR_ARRAY_IDX(children, i, const char *);
           const char *this_abspath;
           svn_wc__db_status_t status;
-          const char *this_path;
 
           svn_pool_clear(iterpool);
 
@@ -521,22 +521,20 @@ process_committed_internal(svn_wc__db_t 
           if (status == svn_wc__db_status_excluded)
             continue;
 
-          /* Create child path by telescoping the main path. */
-          this_path = svn_dirent_join(path, name, iterpool);
-
           /* Recurse, but only allow further recursion if the child is
              a directory.  Pass NULL for NEW_DAV_CACHE, because the
              ones present in the current call are only applicable to
              this one committed item. */
           if (kind == svn_wc__db_kind_dir)
             {
-              SVN_ERR(process_committed_internal(db, this_abspath, this_path,
-                                                 TRUE /* recurse */,
-                                                 new_revnum, new_date,
-                                                 rev_author,
-                                                 NULL, TRUE /* no_unlock */,
-                                                 keep_changelist, NULL,
-                                                 queue, iterpool));
+              SVN_ERR(svn_wc__process_committed_internal(db, this_abspath,
+                                                         TRUE /* recurse */,
+                                                         new_revnum, new_date,
+                                                         rev_author,
+                                                         NULL,
+                                                         TRUE /* no_unlock */,
+                                                         keep_changelist, NULL,
+                                                         queue, iterpool));
               SVN_ERR(svn_wc__wq_run(db, this_abspath, NULL, NULL, iterpool));
             }
           else
@@ -557,12 +555,24 @@ process_committed_internal(svn_wc__db_t 
                   if (replaced)
                     continue;
                 }
-              SVN_ERR(process_committed_leaf(db, adm_abspath, this_path,
+
+              checksum = NULL;
+              if (queue != NULL)
+                {
+                  const committed_queue_item_t *cqi
+                    = apr_hash_get(queue->queue, this_abspath,
+                                   APR_HASH_KEY_STRING);
+
+                  if (cqi != NULL)
+                    checksum = cqi->checksum;
+                }
+
+              SVN_ERR(process_committed_leaf(db, this_abspath,
                                              new_revnum,
                                              new_date, rev_author, NULL,
                                              TRUE /* no_unlock */,
                                              keep_changelist,
-                                             NULL, queue, iterpool));
+                                             checksum, iterpool));
             }
         }
 
@@ -573,28 +583,26 @@ process_committed_internal(svn_wc__db_t 
 }
 
 
-static apr_hash_t *
-convert_to_hash(const apr_array_header_t *wcprop_changes,
-                apr_pool_t *result_pool)
+apr_hash_t *
+svn_wc__prop_array_to_hash(const apr_array_header_t *props,
+                           apr_pool_t *result_pool)
 {
   int i;
-  apr_hash_t *dav_cache;
+  apr_hash_t *prophash;
 
-  if (wcprop_changes == NULL || wcprop_changes->nelts == 0)
+  if (props == NULL || props->nelts == 0)
     return NULL;
 
-  dav_cache = apr_hash_make(result_pool);
+  prophash = apr_hash_make(result_pool);
 
-  for (i = 0; i < wcprop_changes->nelts; i++)
+  for (i = 0; i < props->nelts; i++)
     {
-      const svn_prop_t *prop = APR_ARRAY_IDX(wcprop_changes, i,
-                                             const svn_prop_t *);
-
+      const svn_prop_t *prop = APR_ARRAY_IDX(props, i, const svn_prop_t *);
       if (prop->value != NULL)
-        apr_hash_set(dav_cache, prop->name, APR_HASH_KEY_STRING, prop->value);
+        apr_hash_set(prophash, prop->name, APR_HASH_KEY_STRING, prop->value);
     }
 
-  return dav_cache;
+  return prophash;
 }
 
 
@@ -605,16 +613,15 @@ svn_wc_committed_queue_create(apr_pool_t
 
   q = apr_palloc(pool, sizeof(*q));
   q->pool = pool;
-  q->queue = apr_array_make(pool, 1, sizeof(committed_queue_item_t *));
+  q->queue = apr_hash_make(pool);
   q->have_recursive = FALSE;
 
   return q;
 }
 
 svn_error_t *
-svn_wc_queue_committed2(svn_wc_committed_queue_t *queue,
-                        const char *path,
-                        svn_wc_adm_access_t *adm_access,
+svn_wc_queue_committed3(svn_wc_committed_queue_t *queue,
+                        const char *local_abspath,
                         svn_boolean_t recurse,
                         const apr_array_header_t *wcprop_changes,
                         svn_boolean_t remove_lock,
@@ -624,6 +631,8 @@ svn_wc_queue_committed2(svn_wc_committed
 {
   committed_queue_item_t *cqi;
 
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+
   queue->have_recursive |= recurse;
 
   /* Use the same pool as the one QUEUE was allocated in,
@@ -632,67 +641,41 @@ svn_wc_queue_committed2(svn_wc_committed
 
   /* Add to the array with paths and options */
   cqi = apr_palloc(queue->pool, sizeof(*cqi));
-  cqi->path = path;
-  cqi->adm_abspath = svn_wc__adm_access_abspath(adm_access);
+  cqi->local_abspath = local_abspath;
   cqi->recurse = recurse;
   cqi->no_unlock = !remove_lock;
   cqi->keep_changelist = !remove_changelist;
   cqi->checksum = checksum;
-  cqi->new_dav_cache = convert_to_hash(wcprop_changes, queue->pool);
+  cqi->new_dav_cache = svn_wc__prop_array_to_hash(wcprop_changes, queue->pool);
 
-  APR_ARRAY_PUSH(queue->queue, committed_queue_item_t *) = cqi;
+  apr_hash_set(queue->queue, local_abspath, APR_HASH_KEY_STRING, cqi);
 
   return SVN_NO_ERROR;
 }
 
-
-/* NOTE: this function doesn't move to deprecated.c because of its need
-   for the internals of svn_wc_committed_queue_t.  */
-svn_error_t *
-svn_wc_queue_committed(svn_wc_committed_queue_t **queue,
-                       const char *path,
-                       svn_wc_adm_access_t *adm_access,
-                       svn_boolean_t recurse,
-                       const apr_array_header_t *wcprop_changes,
-                       svn_boolean_t remove_lock,
-                       svn_boolean_t remove_changelist,
-                       const unsigned char *digest,
-                       apr_pool_t *pool)
-{
-  const svn_checksum_t *checksum;
-
-  if (digest)
-    checksum = svn_checksum__from_digest(digest, svn_checksum_md5,
-                                         (*queue)->pool);
-  else
-    checksum = NULL;
-
-  return svn_wc_queue_committed2(*queue, path, adm_access, recurse,
-                                 wcprop_changes, remove_lock,
-                                 remove_changelist,
-                                 checksum, pool);
-}
-
-
 /* Return TRUE if any item of QUEUE is a parent of ITEM and will be
    processed recursively, return FALSE otherwise.
+
+   The algorithmic complexity of this search implementation is O(queue
+   length), but it's quite quick.
 */
 static svn_boolean_t
-have_recursive_parent(apr_array_header_t *queue, int item)
+have_recursive_parent(apr_hash_t *queue,
+                      const committed_queue_item_t *item,
+                      apr_pool_t *scratch_pool)
 {
-  int i;
-  const char *path
-    = APR_ARRAY_IDX(queue, item, committed_queue_item_t *)->path;
+  apr_hash_index_t *hi;
+  const char *local_abspath = item->local_abspath;
 
-  for (i = 0; i < queue->nelts; i++)
+  for (hi = apr_hash_first(scratch_pool, queue); hi; hi = apr_hash_next(hi))
     {
-      const committed_queue_item_t *qi;
+      const committed_queue_item_t *qi = svn__apr_hash_index_val(hi);
 
-      if (i == item)
+      if (qi == item)
         continue;
 
-      qi = APR_ARRAY_IDX(queue, i, const committed_queue_item_t *);
-      if (qi->recurse && svn_dirent_is_child(qi->path, path, NULL))
+      if (qi->recurse && svn_dirent_is_child(qi->local_abspath, local_abspath,
+                                             NULL))
         return TRUE;
     }
 
@@ -700,113 +683,75 @@ have_recursive_parent(apr_array_header_t
 }
 
 svn_error_t *
-svn_wc_process_committed_queue(svn_wc_committed_queue_t *queue,
-                               svn_wc_adm_access_t *adm_access,
-                               svn_revnum_t new_revnum,
-                               const char *rev_date,
-                               const char *rev_author,
-                               apr_pool_t *pool)
+svn_wc_process_committed_queue2(svn_wc_committed_queue_t *queue,
+                                svn_wc_context_t *wc_ctx,
+                                svn_revnum_t new_revnum,
+                                const char *rev_date,
+                                const char *rev_author,
+                                apr_pool_t *scratch_pool)
 {
-  svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
+  apr_array_header_t *sorted_queue;
   int i;
-  apr_pool_t *iterpool = svn_pool_create(pool);
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   apr_time_t new_date;
 
   if (rev_date)
-    SVN_ERR(svn_time_from_cstring(&new_date, rev_date, pool));
+    SVN_ERR(svn_time_from_cstring(&new_date, rev_date, scratch_pool));
   else
     new_date = 0;
 
-  for (i = 0; i < queue->queue->nelts; i++)
-    {
-      const committed_queue_item_t *cqi
-        = APR_ARRAY_IDX(queue->queue, i, const committed_queue_item_t *);
+  /* Process the queued items in order of their paths.  (The requirement is
+   * probably just that a directory must be processed before its children.) */
+  sorted_queue = svn_sort__hash(queue->queue, svn_sort_compare_items_as_paths,
+                                scratch_pool);
+  for (i = 0; i < sorted_queue->nelts; i++)
+    {
+      const svn_sort__item_t *sort_item
+        = &APR_ARRAY_IDX(sorted_queue, i, svn_sort__item_t);
+      const committed_queue_item_t *cqi = sort_item->value;
 
       svn_pool_clear(iterpool);
 
-      /* If there are some recursive items, then see if this item is a
-         child of one, and will (implicitly) be accounted for. */
-      if (queue->have_recursive && have_recursive_parent(queue->queue, i))
+      /* Skip this item if it is a child of a recursive item, because it has
+         been (or will be) accounted for when that recursive item was (or
+         will be) processed. */
+      if (queue->have_recursive && have_recursive_parent(queue->queue, cqi,
+                                                         iterpool))
         continue;
 
-      SVN_ERR(process_committed_internal(db, cqi->adm_abspath, cqi->path,
-                                         cqi->recurse,
-                                         new_revnum, new_date, rev_author,
-                                         cqi->new_dav_cache,
-                                         cqi->no_unlock,
-                                         cqi->keep_changelist,
-                                         cqi->checksum, queue, iterpool));
+      SVN_ERR(svn_wc__process_committed_internal(wc_ctx->db, cqi->local_abspath,
+                                                 cqi->recurse, new_revnum,
+                                                 new_date, rev_author,
+                                                 cqi->new_dav_cache,
+                                                 cqi->no_unlock,
+                                                 cqi->keep_changelist,
+                                                 cqi->checksum, queue,
+                                                 iterpool));
 
-      SVN_ERR(svn_wc__wq_run(db, cqi->adm_abspath, NULL, NULL, iterpool));
+      SVN_ERR(svn_wc__wq_run(wc_ctx->db, cqi->local_abspath, NULL, NULL,
+                             iterpool));
     }
 
-  queue->queue->nelts = 0;
+  svn_hash__clear(queue->queue, scratch_pool);
 
   svn_pool_destroy(iterpool);
 
   return SVN_NO_ERROR;
 }
 
-svn_error_t *
-svn_wc_process_committed4(const char *path,
-                          svn_wc_adm_access_t *adm_access,
-                          svn_boolean_t recurse,
-                          svn_revnum_t new_revnum,
-                          const char *rev_date,
-                          const char *rev_author,
-                          const apr_array_header_t *wcprop_changes,
-                          svn_boolean_t remove_lock,
-                          svn_boolean_t remove_changelist,
-                          const unsigned char *digest,
-                          apr_pool_t *pool)
-{
-  svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
-  const char *adm_abspath = svn_wc__adm_access_abspath(adm_access);
-  const svn_checksum_t *checksum;
-  apr_time_t new_date;
-
-  if (rev_date)
-    SVN_ERR(svn_time_from_cstring(&new_date, rev_date, pool));
-  else
-    new_date = 0;
-
-  if (digest)
-    checksum = svn_checksum__from_digest(digest, svn_checksum_md5, pool);
-  else
-    checksum = NULL;
-
-  SVN_ERR(process_committed_internal(db, adm_abspath,
-                                     path, recurse,
-                                     new_revnum, new_date, rev_author,
-                                     convert_to_hash(wcprop_changes, pool),
-                                     !remove_lock,!remove_changelist,
-                                     checksum, NULL,
-                                     pool));
-
-  /* Run the log file(s) we just created. */
-  return svn_error_return(svn_wc__wq_run(db, adm_abspath, NULL, NULL, pool));
-}
-
-
 
-/* Recursively mark a tree LOCAL_ABSPATH with SCHEDULE svn_wc_schedule_delete
+/* Recursively mark a tree DIR_ABSPATH with schedule svn_wc_schedule_delete
    and a KEEP_LOCAL flag. */
-/* ### If the implementation looks familiar to mark_tree_copied(), that is not
-       strictly coincidence. The function was duplicated, to make it easier to
-       replace these two specific cases for WC-NG. */
 static svn_error_t *
 mark_tree_deleted(svn_wc__db_t *db,
                  const char *dir_abspath,
                  svn_boolean_t keep_local,
-                 svn_cancel_func_t cancel_func,
-                 void *cancel_baton,
                  svn_wc_notify_func2_t notify_func,
                  void *notify_baton,
                  apr_pool_t *pool)
 {
   apr_pool_t *iterpool = svn_pool_create(pool);
   const apr_array_header_t *children;
-  svn_wc__db_status_t status;
   int i;
 
   /* Read the entries file for this directory. */
@@ -832,17 +777,18 @@ mark_tree_deleted(svn_wc__db_t *db,
 
       SVN_ERR(svn_wc__db_read_kind(&kind, db, child_abspath, FALSE, iterpool));
 
-      /* If this is a directory, recurse. */
+      /* If this is a directory, recurse; otherwise, delete. */
       if (kind == svn_wc__db_kind_dir)
         {
           SVN_ERR(mark_tree_deleted(db, child_abspath,
                                     keep_local,
-                                    cancel_func, cancel_baton,
                                     notify_func, notify_baton,
                                     iterpool));
         }
-
-      SVN_ERR(svn_wc__db_temp_op_delete(db, child_abspath, pool));
+      else
+        {
+          SVN_ERR(svn_wc__db_temp_op_delete(db, child_abspath, pool));
+        }
 
       /* Tell someone what we've done. */
       if (notify_func != NULL)
@@ -853,25 +799,10 @@ mark_tree_deleted(svn_wc__db_t *db,
                     iterpool);
     }
 
-  /* Handle "this dir" for states that need it done post-recursion. */
-  SVN_ERR(svn_wc__db_read_info(&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, dir_abspath, iterpool, iterpool));
-  /* Uncommitted directories (schedule add) that are to be scheduled for
-     deletion are a special case, they don't need to be changed as they
-     will be removed from their parent's entry list.
-     The files and directories are left on the disk in this special
-     case, so KEEP_LOCAL doesn't need to be set either. */
-  if (!(status == svn_wc__db_status_added ||
-        status == svn_wc__db_status_obstructed_add))
-    {
-      SVN_ERR(svn_wc__db_temp_op_delete(db, dir_abspath, iterpool));
-
-      if (keep_local)
-        SVN_ERR(svn_wc__db_temp_set_keep_local(db, dir_abspath, TRUE, iterpool));
-    }
+  /* Handle directories now, after handling their kiddos. */
+  SVN_ERR(svn_wc__db_temp_op_delete(db, dir_abspath, iterpool));
+  if (keep_local)
+    SVN_ERR(svn_wc__db_temp_set_keep_local(db, dir_abspath, TRUE, iterpool));
 
   /* Destroy our per-iteration pool. */
   svn_pool_destroy(iterpool);
@@ -1034,7 +965,7 @@ erase_from_wc(svn_wc__db_t *db,
            hi;
            hi = apr_hash_next(hi))
         {
-          const char *name = svn_apr_hash_index_key(hi);
+          const char *name = svn__apr_hash_index_key(hi);
 
           svn_pool_clear(iterpool);
 
@@ -1165,7 +1096,6 @@ svn_wc_delete4(svn_wc_context_t *wc_ctx,
               SVN_ERR(mark_tree_deleted(wc_ctx->db,
                                         local_abspath,
                                         keep_local,
-                                        cancel_func, cancel_baton,
                                         notify_func, notify_baton,
                                         pool));
             }
@@ -1184,7 +1114,7 @@ svn_wc_delete4(svn_wc_context_t *wc_ctx,
 
       /* ### The following two operations should be inside one SqLite
              transaction. For even better behavior the tree operation
-             before this block needs the same handling. 
+             before this block needs the same handling.
              Luckily most of this is for free once properties and pristine
              are handled in the WC-NG way. */
       SVN_ERR(svn_wc__db_temp_op_delete(wc_ctx->db, local_abspath, pool));
@@ -1270,22 +1200,44 @@ svn_wc_get_ancestry2(const char **url,
                                   result_pool, scratch_pool));
 }
 
-/* Recursively mark a tree LOCAL_ABSPATH with a COPIED flag, skip items
-   scheduled for deletion. */
-/* ### If the implementation looks familiar to mark_tree_deleted(), that
-       is not strictly coincidence. The function was duplicated, to make it
-       easier to replace these two specific cases for WC-NG. */
+/* Helper for mark_tree_copied(), handling the property juggling and
+   state changes for a single item LOCAL_ABSPATH (of kind LOCAL_KIND). */
+static svn_error_t *
+mark_item_copied(svn_wc__db_t *db,
+                 const char *local_abspath,
+                 svn_wc__db_kind_t local_kind,
+                 apr_pool_t *scratch_pool)
+{
+  apr_hash_t *props;
+  svn_wc_entry_t tmp_entry;
+  svn_node_kind_t kind = 
+    local_kind == svn_wc__db_kind_dir ? svn_node_dir : svn_node_unknown;
+
+  /* Squirrel away the pristine properties to install them on
+     working, because we might delete the base table */
+  SVN_ERR(svn_wc__db_read_pristine_props(&props, db, local_abspath,
+                                         scratch_pool, scratch_pool));
+  tmp_entry.copied = TRUE;
+  SVN_ERR(svn_wc__entry_modify2(db, local_abspath, kind, FALSE, &tmp_entry,
+                                SVN_WC__ENTRY_MODIFY_COPIED, scratch_pool));
+
+  /* Reinstall the pristine properties on WORKING */
+  SVN_ERR(svn_wc__db_temp_working_set_props(db, local_abspath, props,
+                                            scratch_pool));
+  
+  return SVN_NO_ERROR;
+}
+
+/* Recursively mark a tree DIR_ABSPATH (whose status is DIR_STATUS)
+   with a COPIED flag, skip items scheduled for deletion. */
 static svn_error_t *
 mark_tree_copied(svn_wc__db_t *db,
                  const char *dir_abspath,
-                 svn_cancel_func_t cancel_func,
-                 void *cancel_baton,
+                 svn_wc__db_status_t dir_status,
                  apr_pool_t *pool)
 {
   apr_pool_t *iterpool = svn_pool_create(pool);
   const apr_array_header_t *children;
-  const svn_wc_entry_t *entry;
-  svn_wc_entry_t tmp_entry;
   int i;
 
   /* Read the entries file for this directory. */
@@ -1296,7 +1248,8 @@ mark_tree_copied(svn_wc__db_t *db,
     {
       const char *child_basename = APR_ARRAY_IDX(children, i, const char *);
       const char *child_abspath;
-      apr_hash_t *props;
+      svn_wc__db_status_t child_status;
+      svn_wc__db_kind_t child_kind;
       svn_boolean_t hidden;
 
       /* Clear our per-iteration pool. */
@@ -1309,64 +1262,38 @@ mark_tree_copied(svn_wc__db_t *db,
       if (hidden)
         continue;
 
-      SVN_ERR(svn_wc__get_entry(&entry, db, child_abspath, FALSE,
-                                svn_node_unknown, FALSE, iterpool, iterpool));
+      SVN_ERR(svn_wc__db_read_info(&child_status, &child_kind, 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));
 
       /* Skip deleted items. */
-      if (entry->schedule == svn_wc_schedule_delete)
+      if ((child_status == svn_wc__db_status_deleted) ||
+          (child_status == svn_wc__db_status_obstructed_delete))
         continue;
 
-      /* If this is a directory, recurse. */
-      if (entry->kind == svn_node_dir)
+      /* If this is a directory, recurse; otherwise, do real work. */
+      if (child_kind == svn_wc__db_kind_dir)
         {
-          SVN_ERR(mark_tree_copied(db, child_abspath,
-                            cancel_func, cancel_baton,
-                            iterpool));
+          SVN_ERR(mark_tree_copied(db, child_abspath, child_status, iterpool));
+        }
+      else
+        {
+          SVN_ERR(mark_item_copied(db, child_abspath, child_kind, iterpool));
         }
-
-      /* Store the pristine properties to install them on working, because
-         we might delete the base table */
-      if (entry->kind != svn_node_dir)
-        SVN_ERR(svn_wc__db_read_pristine_props(&props, db, child_abspath,
-                                               iterpool, iterpool));
-      tmp_entry.copied = TRUE;
-      SVN_ERR(svn_wc__entry_modify2(db, child_abspath, svn_node_unknown,
-                            TRUE, &tmp_entry,
-                            SVN_WC__ENTRY_MODIFY_COPIED,
-                            iterpool));
-
-      /* Reinstall the pristine properties on working */
-      if (entry->kind != svn_node_dir)
-        SVN_ERR(svn_wc__db_temp_op_set_pristine_props(db, child_abspath, props,
-                                                      TRUE, iterpool));
 
       /* Remove now obsolete dav cache values.  */
       SVN_ERR(svn_wc__db_base_set_dav_cache(db, child_abspath, NULL,
                                             iterpool));
     }
 
-  /* Handle "this dir" for states that need it done post-recursion. */
-  SVN_ERR(svn_wc__get_entry(&entry, db, dir_abspath, FALSE,
-                            svn_node_dir, FALSE, iterpool, iterpool));
-
-  /* If setting the COPIED flag, skip deleted items. */
-  if (entry->schedule != svn_wc_schedule_delete)
+  /* Here's where we handle directories. */
+  if (!((dir_status == svn_wc__db_status_deleted) ||
+        (dir_status == svn_wc__db_status_obstructed_delete)))
     {
-      apr_hash_t *props;
-      tmp_entry.copied = TRUE;
-
-      /* Store the pristine properties to install them on working, because
-         we might delete the base table */
-      SVN_ERR(svn_wc__db_read_pristine_props(&props, db, dir_abspath,
-                                               iterpool, iterpool));
-
-      SVN_ERR(svn_wc__entry_modify2(db, dir_abspath, svn_node_dir, FALSE,
-                                  &tmp_entry, SVN_WC__ENTRY_MODIFY_COPIED,
-                                  iterpool));
-
-      /* Reinstall the pristine properties on working */
-      SVN_ERR(svn_wc__db_temp_op_set_pristine_props(db, dir_abspath, props,
-                                                    TRUE, iterpool));
+      SVN_ERR(mark_item_copied(db, dir_abspath, svn_wc__db_kind_dir,
+                               iterpool));
     }
 
   /* Destroy our per-iteration pool. */
@@ -1543,8 +1470,14 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
      we might delete the base table */
   if ((exists && status != svn_wc__db_status_not_present)
       && !is_replace && copyfrom_url != NULL)
-    SVN_ERR(svn_wc__db_read_pristine_props(&props, db, local_abspath,
-                                           pool, pool));
+    {
+      /* NOTE: the conditions to reach here *exactly* match the
+         conditions used below when PROPS is referenced.
+         Be careful to keep these sets of conditionals aligned to avoid
+         an uninitialized PROPS value.  */
+      SVN_ERR(svn_wc__db_read_pristine_props(&props, db, local_abspath,
+                                             pool, pool));
+    }
 
   /* Now, add the entry for this item to the parent_dir's
      entries file, marking it for addition. */
@@ -1604,7 +1537,11 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
           /* When we are called with the copyfrom arguments set and with
              the admin directory already in existence, then the dir will
              contain the copyfrom settings.  So we need to pass the
-             copyfrom arguments to the ensure call. */
+             copyfrom arguments to the ensure call.
+
+             This creates a BASE_NODE for an added directory, really
+             it should create a WORKING_NODE.  It gets removed by the
+             next modify2 call. */
           SVN_ERR(svn_wc__internal_ensure_adm(db, local_abspath,
                                               copyfrom_url,
                                               parent_entry->repos,
@@ -1642,7 +1579,10 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
       /* We're making the same mods we made above, but this time we'll
          force the scheduling.  Also make sure to undo the
          'incomplete' flag which svn_wc__internal_ensure_adm() sets by
-         default. */
+         default.
+
+         This deletes the erroneous BASE_NODE for added directories and
+         adds a WORKING_NODE. */
       modify_flags |= SVN_WC__ENTRY_MODIFY_FORCE;
       modify_flags |= SVN_WC__ENTRY_MODIFY_INCOMPLETE;
       tmp_entry.schedule = is_replace
@@ -1680,7 +1620,7 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
 
           /* Recursively add the 'copied' existence flag as well!  */
           SVN_ERR(mark_tree_copied(db, local_abspath,
-                                   cancel_func, cancel_baton,
+                                   exists ? status : svn_wc__db_status_added,
                                    pool));
 
           /* Clean out the now-obsolete dav cache values.  */
@@ -1695,12 +1635,20 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
   if (exists && status != svn_wc__db_status_not_present)
     {
       if (!is_replace && copyfrom_url != NULL)
-        SVN_ERR(svn_wc__db_temp_op_set_pristine_props(db, local_abspath, props,
-                                                      TRUE, pool));
+        {
+          /* NOTE: the conditions to reach here *exactly* match the
+             conditions that were used to initialize the PROPS localvar.
+             Be careful to keep these sets of conditionals aligned to avoid
+             an uninitialized PROPS value.  */
+          SVN_ERR(svn_wc__db_temp_working_set_props(db, local_abspath, props,
+                                                    pool));
+        }
       else
-        SVN_ERR(svn_wc__db_temp_op_set_pristine_props(db, local_abspath,
-                                                      apr_hash_make(pool),
-                                                      TRUE, pool));
+        {
+          SVN_ERR(svn_wc__db_temp_working_set_props(db, local_abspath,
+                                                    apr_hash_make(pool),
+                                                    pool));
+        }
     }
 
   /* Report the addition to the caller. */
@@ -1766,6 +1714,7 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
 */
 
 
+/* */
 static svn_error_t *
 revert_admin_things(svn_boolean_t *reverted,
                     svn_wc__db_t *db,
@@ -2251,15 +2200,17 @@ svn_wc_get_pristine_copy_path(const char
                               const char **pristine_path,
                               apr_pool_t *pool)
 {
-  svn_wc_context_t *wc_ctx;
+  svn_wc__db_t *db;
   const char *local_abspath;
 
-  SVN_ERR(svn_wc_context_create(&wc_ctx, NULL, pool, pool));
+  SVN_ERR(svn_wc__db_open(&db, svn_wc__db_openmode_readonly, NULL,
+                          TRUE, TRUE, pool, pool));
   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
 
-  SVN_ERR(svn_wc__text_base_path(pristine_path, wc_ctx->db, local_abspath,
-                                          FALSE, pool));
-  return SVN_NO_ERROR;
+  SVN_ERR(svn_wc__text_base_path(pristine_path, db, local_abspath,
+                                 FALSE, pool));
+
+  return svn_error_return(svn_wc__db_close(db));
 }
 
 svn_error_t *
@@ -2283,19 +2234,76 @@ svn_wc__get_pristine_contents(svn_stream
                               apr_pool_t *result_pool,
                               apr_pool_t *scratch_pool)
 {
-  const char *text_base;
+  svn_wc__db_status_t status;
+  svn_wc__db_kind_t kind;
 
-  SVN_ERR(svn_wc__text_base_path(&text_base, db, local_abspath, FALSE,
-                                 scratch_pool));
+  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));
 
-  if (text_base == NULL)
+  /* Sanity */
+  if (kind != svn_wc__db_kind_file)
+    return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
+                             _("Can only get the pristine contents of files; "
+                               "'%s' is not a file"),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+
+  if (status == svn_wc__db_status_added)
     {
-      *contents = NULL;
-      return SVN_NO_ERROR;
+      /* For an added node, we return "no stream". Make sure this is not
+         copied-here or moved-here, in which case we return the copy/move
+         source's contents.  */
+      SVN_ERR(svn_wc__db_scan_addition(&status,
+                                       NULL, NULL, NULL, NULL, NULL, NULL,
+                                       NULL, NULL,
+                                       db, local_abspath,
+                                       scratch_pool, scratch_pool));
+      if (status == svn_wc__db_status_added)
+        {
+          /* Simply added. The pristine base does not exist. */
+          *contents = NULL;
+          return SVN_NO_ERROR;
+        }
     }
+  else if (status == svn_wc__db_status_not_present)
+    /* We know that the delete of this node has been committed.
+       This should be the same as if called on an unknown path. */
+    return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+                             _("Cannot get the pristine contents of '%s' "
+                               "because its delete is already committed"),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+  else if (status == svn_wc__db_status_absent
+      || status == svn_wc__db_status_excluded
+      || status == svn_wc__db_status_incomplete)
+    return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
+                             _("Cannot get the pristine contents of '%s' "
+                               "because it has an unexpected status"),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+  else
+    /* We know that it is a file, so we can't hit the _obstructed stati.
+       Also, we should never see _base_deleted here. */
+    SVN_ERR_ASSERT(status != svn_wc__db_status_obstructed
+                   && status != svn_wc__db_status_obstructed_add
+                   && status != svn_wc__db_status_obstructed_delete
+                   && status != svn_wc__db_status_base_deleted);
+
+  /* ### TODO 1.7: use pristine store instead of this block: */
+  {
+    const char *text_base;
+
+    SVN_ERR(svn_wc__text_base_path(&text_base, db, local_abspath, FALSE,
+                                   scratch_pool));
+    SVN_ERR_ASSERT(text_base != NULL);
 
-  return svn_stream_open_readonly(contents, text_base, result_pool,
-                                  scratch_pool);
+    return svn_error_return(svn_stream_open_readonly(contents, text_base,
+                                                     result_pool,
+                                                     scratch_pool));
+  }
 }
 
 

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/ambient_depth_filter_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/ambient_depth_filter_editor.c?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/ambient_depth_filter_editor.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/ambient_depth_filter_editor.c Tue Mar 30 20:57:53 2010
@@ -115,6 +115,7 @@ struct dir_baton
   void *wrapped_baton;
 };
 
+/* */
 static svn_error_t *
 make_dir_baton(struct dir_baton **d_p,
                const char *path,
@@ -206,6 +207,7 @@ make_dir_baton(struct dir_baton **d_p,
   return SVN_NO_ERROR;
 }
 
+/* */
 static svn_error_t *
 make_file_baton(struct file_baton **f_p,
                 struct dir_baton *pb,
@@ -264,6 +266,7 @@ make_file_baton(struct file_baton **f_p,
 
 /*** Editor Functions ***/
 
+/* */
 static svn_error_t *
 set_target_revision(void *edit_baton,
                     svn_revnum_t target_revision,
@@ -276,6 +279,7 @@ set_target_revision(void *edit_baton,
                                                 target_revision, pool);
 }
 
+/* */
 static svn_error_t *
 open_root(void *edit_baton,
           svn_revnum_t base_revision,
@@ -322,6 +326,7 @@ open_root(void *edit_baton,
                                        pool, &b->wrapped_baton);
 }
 
+/* */
 static svn_error_t *
 delete_entry(const char *path,
              svn_revnum_t base_revision,
@@ -361,6 +366,7 @@ delete_entry(const char *path,
                                           pb->wrapped_baton, pool);
 }
 
+/* */
 static svn_error_t *
 add_directory(const char *path,
               void *parent_baton,
@@ -406,6 +412,7 @@ add_directory(const char *path,
                                            pool, &b->wrapped_baton);
 }
 
+/* */
 static svn_error_t *
 open_directory(const char *path,
                void *parent_baton,
@@ -458,6 +465,7 @@ open_directory(const char *path,
   return SVN_NO_ERROR;
 }
 
+/* */
 static svn_error_t *
 add_file(const char *path,
          void *parent_baton,
@@ -481,6 +489,7 @@ add_file(const char *path,
                                       pool, &b->wrapped_baton);
 }
 
+/* */
 static svn_error_t *
 open_file(const char *path,
           void *parent_baton,
@@ -502,6 +511,7 @@ open_file(const char *path,
                                        &b->wrapped_baton);
 }
 
+/* */
 static svn_error_t *
 apply_textdelta(void *file_baton,
                 const char *base_checksum,
@@ -525,6 +535,7 @@ apply_textdelta(void *file_baton,
                                              handler, handler_baton);
 }
 
+/* */
 static svn_error_t *
 close_file(void *file_baton,
            const char *text_checksum,
@@ -540,6 +551,7 @@ close_file(void *file_baton,
                                         text_checksum, pool);
 }
 
+/* */
 static svn_error_t *
 absent_file(const char *path,
             void *parent_baton,
@@ -554,6 +566,7 @@ absent_file(const char *path,
   return eb->wrapped_editor->absent_file(path, pb->wrapped_baton, pool);
 }
 
+/* */
 static svn_error_t *
 close_directory(void *dir_baton,
                 apr_pool_t *pool)
@@ -567,6 +580,7 @@ close_directory(void *dir_baton,
   return eb->wrapped_editor->close_directory(db->wrapped_baton, pool);
 }
 
+/* */
 static svn_error_t *
 absent_directory(const char *path,
                  void *parent_baton,
@@ -582,6 +596,7 @@ absent_directory(const char *path,
   return eb->wrapped_editor->absent_directory(path, pb->wrapped_baton, pool);
 }
 
+/* */
 static svn_error_t *
 change_file_prop(void *file_baton,
                  const char *name,
@@ -598,6 +613,7 @@ change_file_prop(void *file_baton,
                                               name, value, pool);
 }
 
+/* */
 static svn_error_t *
 change_dir_prop(void *dir_baton,
                 const char *name,
@@ -614,6 +630,7 @@ change_dir_prop(void *dir_baton,
                                              name, value, pool);
 }
 
+/* */
 static svn_error_t *
 close_edit(void *edit_baton,
            apr_pool_t *pool)

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/conflicts.c?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/conflicts.c Tue Mar 30 20:57:53 2010
@@ -67,6 +67,7 @@ struct svn_wc_conflict_t
   /* ### TODO: Add more fields */
 };
 
+/* */
 static svn_error_t *
 conflict_alloc(svn_wc_conflict_t **conflict, apr_pool_t *result_pool)
 {
@@ -427,6 +428,7 @@ resolve_conflict_on_node(svn_wc__db_t *d
   return SVN_NO_ERROR;
 }
 
+/* */
 static svn_error_t *
 resolve_one_conflict(svn_wc__db_t *db,
                      const char *local_abspath,
@@ -545,6 +547,7 @@ resolve_one_conflict(svn_wc__db_t *db,
   return SVN_NO_ERROR;
 }
 
+/* */
 static svn_error_t *
 recursive_resolve_conflict(svn_wc__db_t *db,
                            const char *local_abspath,

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/copy.c?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/copy.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/copy.c Tue Mar 30 20:57:53 2010
@@ -60,8 +60,8 @@ copy_props(svn_wc__db_t *db,
                              scratch_pool, scratch_pool));
   for (hi = apr_hash_first(scratch_pool, props); hi; hi = apr_hash_next(hi))
     {
-      const char *propname = svn_apr_hash_index_key(hi);
-      svn_string_t *propval = svn_apr_hash_index_val(hi);
+      const char *propname = svn__apr_hash_index_key(hi);
+      svn_string_t *propval = svn__apr_hash_index_val(hi);
 
       SVN_ERR(svn_wc__internal_propset(db, dst_abspath, propname, propval,
                                        FALSE /* skip_checks */,
@@ -188,8 +188,8 @@ copy_added_dir_administratively(svn_wc_c
            hi;
            hi = apr_hash_next(hi))
         {
-          const char *name = svn_apr_hash_index_key(hi);
-          svn_io_dirent_t *dirent = svn_apr_hash_index_val(hi);
+          const char *name = svn__apr_hash_index_key(hi);
+          svn_io_dirent_t *dirent = svn__apr_hash_index_val(hi);
           const char *node_abspath;
           svn_wc__db_kind_t kind;
 
@@ -402,9 +402,16 @@ copy_file_administratively(svn_wc_contex
                             scratch_pool, scratch_pool));
 
   /* Sanity check 2: You cannot make a copy of something that's not
-     in the repository unless it's a copy of an uncommitted copy. */
-  if ((src_entry->schedule == svn_wc_schedule_add && (! src_entry->copied))
-      || (! src_entry->url))
+     in the repository unless it's a copy of an uncommitted copy.
+     Added files don't have a base, but replaced files have a revert-base.
+     ### TODO: svn_opt_revision_base currently means "commit-base", which
+     ### technically is none for replaced files. We currently have no way to
+     ### get at the revert-base and need a new svn_opt_revision_X for that.
+   */
+  if (((src_entry->schedule == svn_wc_schedule_add
+        || src_entry->schedule == svn_wc_schedule_replace)
+       && (!src_entry->copied))
+      || (!src_entry->url))
     return svn_error_createf
       (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
        _("Cannot copy or move '%s': it is not in the repository yet; "
@@ -484,6 +491,10 @@ copy_file_administratively(svn_wc_contex
                                         err, NULL);
               else if (err)
                 return svn_error_return(err);
+              
+              /* Above add/replace condition should have caught this already
+               * (-> error "Cannot copy..."). */
+              SVN_ERR_ASSERT(contents != NULL);
             }
           else if (err)
             return svn_error_return(err);
@@ -513,6 +524,9 @@ copy_file_administratively(svn_wc_contex
 
     SVN_ERR(svn_wc_get_pristine_contents2(&base_contents, wc_ctx, src_abspath,
                                           scratch_pool, scratch_pool));
+    /* Above add/replace condition should have caught this already
+     * (-> error "Cannot copy..."). */
+    SVN_ERR_ASSERT(base_contents != NULL);
 
     SVN_ERR(svn_wc_add_repos_file4(wc_ctx, dst_abspath,
                                    base_contents, contents,

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/deprecated.c?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/deprecated.c Tue Mar 30 20:57:53 2010
@@ -30,6 +30,7 @@
 #include "svn_subst.h"
 #include "svn_pools.h"
 #include "svn_props.h"
+#include "svn_time.h"
 #include "svn_dirent_uri.h"
 
 #include "private/svn_wc_private.h"
@@ -37,6 +38,7 @@
 #include "wc.h"
 #include "lock.h"
 #include "props.h"
+#include "workqueue.h"
 
 #include "svn_private_config.h"
 
@@ -163,6 +165,7 @@ struct wrap_3to2_report_baton {
   void *baton;
 };
 
+/* */
 static svn_error_t *wrap_3to2_set_path(void *report_baton,
                                        const char *path,
                                        svn_revnum_t revision,
@@ -177,6 +180,7 @@ static svn_error_t *wrap_3to2_set_path(v
                                  lock_token, pool);
 }
 
+/* */
 static svn_error_t *wrap_3to2_delete_path(void *report_baton,
                                           const char *path,
                                           apr_pool_t *pool)
@@ -186,6 +190,7 @@ static svn_error_t *wrap_3to2_delete_pat
   return wrb->reporter->delete_path(wrb->baton, path, pool);
 }
 
+/* */
 static svn_error_t *wrap_3to2_link_path(void *report_baton,
                                         const char *path,
                                         const char *url,
@@ -201,6 +206,7 @@ static svn_error_t *wrap_3to2_link_path(
                                   start_empty, lock_token, pool);
 }
 
+/* */
 static svn_error_t *wrap_3to2_finish_report(void *report_baton,
                                             apr_pool_t *pool)
 {
@@ -209,6 +215,7 @@ static svn_error_t *wrap_3to2_finish_rep
   return wrb->reporter->finish_report(wrb->baton, pool);
 }
 
+/* */
 static svn_error_t *wrap_3to2_abort_report(void *report_baton,
                                            apr_pool_t *pool)
 {
@@ -296,6 +303,7 @@ struct wrap_2to1_report_baton {
   void *baton;
 };
 
+/* */
 static svn_error_t *wrap_2to1_set_path(void *report_baton,
                                        const char *path,
                                        svn_revnum_t revision,
@@ -309,6 +317,7 @@ static svn_error_t *wrap_2to1_set_path(v
                                  pool);
 }
 
+/* */
 static svn_error_t *wrap_2to1_delete_path(void *report_baton,
                                           const char *path,
                                           apr_pool_t *pool)
@@ -318,6 +327,7 @@ static svn_error_t *wrap_2to1_delete_pat
   return wrb->reporter->delete_path(wrb->baton, path, pool);
 }
 
+/* */
 static svn_error_t *wrap_2to1_link_path(void *report_baton,
                                         const char *path,
                                         const char *url,
@@ -332,6 +342,7 @@ static svn_error_t *wrap_2to1_link_path(
                                   start_empty, pool);
 }
 
+/* */
 static svn_error_t *wrap_2to1_finish_report(void *report_baton,
                                             apr_pool_t *pool)
 {
@@ -340,6 +351,7 @@ static svn_error_t *wrap_2to1_finish_rep
   return wrb->reporter->finish_report(wrb->baton, pool);
 }
 
+/* */
 static svn_error_t *wrap_2to1_abort_report(void *report_baton,
                                            apr_pool_t *pool)
 {
@@ -537,6 +549,49 @@ svn_wc_get_pristine_contents(svn_stream_
 
 
 svn_error_t *
+svn_wc_process_committed4(const char *path,
+                          svn_wc_adm_access_t *adm_access,
+                          svn_boolean_t recurse,
+                          svn_revnum_t new_revnum,
+                          const char *rev_date,
+                          const char *rev_author,
+                          const apr_array_header_t *wcprop_changes,
+                          svn_boolean_t remove_lock,
+                          svn_boolean_t remove_changelist,
+                          const unsigned char *digest,
+                          apr_pool_t *pool)
+{
+  svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
+  const char *local_abspath;
+  const svn_checksum_t *checksum;
+  apr_time_t new_date;
+  apr_hash_t *wcprop_changes_hash;
+
+  if (rev_date)
+    SVN_ERR(svn_time_from_cstring(&new_date, rev_date, pool));
+  else
+    new_date = 0;
+
+  if (digest)
+    checksum = svn_checksum__from_digest(digest, svn_checksum_md5, pool);
+  else
+    checksum = NULL;
+
+  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
+
+  wcprop_changes_hash = svn_wc__prop_array_to_hash(wcprop_changes, pool);
+  SVN_ERR(svn_wc__process_committed_internal(db, local_abspath, recurse,
+                                             new_revnum, new_date, rev_author,
+                                             wcprop_changes_hash,
+                                             !remove_lock, !remove_changelist,
+                                             checksum, NULL, pool));
+
+  /* Run the log file(s) we just created. */
+  return svn_error_return(svn_wc__wq_run(db, local_abspath, NULL, NULL, pool));
+}
+
+
+svn_error_t *
 svn_wc_process_committed3(const char *path,
                           svn_wc_adm_access_t *adm_access,
                           svn_boolean_t recurse,
@@ -2171,6 +2226,7 @@ struct status4_wrapper_baton
   const char *anchor_relpath;
 };
 
+/* */
 static svn_error_t *
 status4_wrapper_func(void *baton,
                      const char *local_abspath,
@@ -2267,6 +2323,7 @@ struct status_editor3_compat_baton
   void *old_baton;
 };
 
+/* */
 static svn_error_t *
 status_editor3_compat_func(void *baton,
                            const char *path,
@@ -2289,7 +2346,7 @@ svn_wc_get_status_editor3(const svn_delt
                           svn_depth_t depth,
                           svn_boolean_t get_all,
                           svn_boolean_t no_ignore,
-                          apr_array_header_t *ignore_patterns,
+                          const apr_array_header_t *ignore_patterns,
                           svn_wc_status_func2_t status_func,
                           void *status_baton,
                           svn_cancel_func_t cancel_func,
@@ -2356,6 +2413,7 @@ struct old_status_func_cb_baton
   void *original_baton;
 };
 
+/* */
 static void old_status_func_cb(void *baton,
                                const char *path,
                                svn_wc_status2_t *status)
@@ -2671,7 +2729,7 @@ svn_wc_get_update_editor3(svn_revnum_t *
                           svn_wc_get_file_t fetch_func,
                           void *fetch_baton,
                           const char *diff3_cmd,
-                          apr_array_header_t *preserved_exts,
+                          const apr_array_header_t *preserved_exts,
                           const svn_delta_editor_t **editor,
                           void **edit_baton,
                           svn_wc_traversal_info_t *traversal_info,
@@ -2786,7 +2844,7 @@ svn_wc_get_switch_editor3(svn_revnum_t *
                           svn_wc_conflict_resolver_func_t conflict_func,
                           void *conflict_baton,
                           const char *diff3_cmd,
-                          apr_array_header_t *preserved_exts,
+                          const apr_array_header_t *preserved_exts,
                           const svn_delta_editor_t **editor,
                           void **edit_baton,
                           svn_wc_traversal_info_t *traversal_info,
@@ -3643,3 +3701,68 @@ svn_wc_crop_tree(svn_wc_adm_access_t *an
 
   return svn_error_return(svn_wc_context_destroy(wc_ctx));
 }
+
+svn_error_t *
+svn_wc_queue_committed2(svn_wc_committed_queue_t *queue,
+                        const char *path,
+                        svn_wc_adm_access_t *adm_access,
+                        svn_boolean_t recurse,
+                        const apr_array_header_t *wcprop_changes,
+                        svn_boolean_t remove_lock,
+                        svn_boolean_t remove_changelist,
+                        const svn_checksum_t *checksum,
+                        apr_pool_t *scratch_pool)
+{
+  const char *local_abspath;
+
+  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
+  return svn_wc_queue_committed3(queue, local_abspath, recurse, wcprop_changes,
+                                 remove_lock, remove_changelist, checksum,
+                                 scratch_pool);
+}
+
+svn_error_t *
+svn_wc_queue_committed(svn_wc_committed_queue_t **queue,
+                       const char *path,
+                       svn_wc_adm_access_t *adm_access,
+                       svn_boolean_t recurse,
+                       const apr_array_header_t *wcprop_changes,
+                       svn_boolean_t remove_lock,
+                       svn_boolean_t remove_changelist,
+                       const unsigned char *digest,
+                       apr_pool_t *pool)
+{
+  const svn_checksum_t *checksum;
+
+  if (digest)
+    checksum = svn_checksum__from_digest(
+                   digest, svn_checksum_md5,
+                   svn_wc__get_committed_queue_pool(*queue));
+  else
+    checksum = NULL;
+
+  return svn_wc_queue_committed2(*queue, path, adm_access, recurse,
+                                 wcprop_changes, remove_lock,
+                                 remove_changelist, checksum, pool);
+}
+
+svn_error_t *
+svn_wc_process_committed_queue(svn_wc_committed_queue_t *queue,
+                               svn_wc_adm_access_t *adm_access,
+                               svn_revnum_t new_revnum,
+                               const char *rev_date,
+                               const char *rev_author,
+                               apr_pool_t *pool)
+{
+  svn_wc_context_t *wc_ctx;
+
+  SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL,
+                                         svn_wc__adm_get_db(adm_access),
+                                         pool));
+  SVN_ERR(svn_wc_process_committed_queue2(queue, wc_ctx, new_revnum,
+                                          rev_date, rev_author, pool));
+  SVN_ERR(svn_wc_context_destroy(wc_ctx));
+
+  return SVN_NO_ERROR;
+}
+

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/diff.c?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/diff.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/diff.c Tue Mar 30 20:57:53 2010
@@ -514,7 +514,7 @@ get_working_mimetype(const char **mimety
  */
 static apr_hash_t *
 apply_propchanges(apr_hash_t *props,
-                  apr_array_header_t *propchanges)
+                  const apr_array_header_t *propchanges)
 {
   apr_hash_t *newprops = apr_hash_copy(apr_hash_pool_get(props), props);
   int i;
@@ -1501,6 +1501,8 @@ apply_textdelta(void *file_baton,
       /* The current text-base is the starting point if replacing */
       SVN_ERR(svn_wc__get_pristine_contents(&source, eb->db, fb->local_abspath,
                                             fb->pool, fb->pool));
+      if (source == NULL)
+        source = svn_stream_empty(fb->pool);
     }
 
   /* This is the file that will contain the pristine repository version. It
@@ -1549,7 +1551,6 @@ close_file(void *file_baton,
   const char *localfile;
   /* The path to the temporary copy of the pristine repository version. */
   const char *temp_file_path;
-  const char *temp_file_abspath;
   svn_boolean_t modified;
   /* The working copy properties at the base of the wc->repos
      comparison: either BASE or WORKING. */
@@ -1588,8 +1589,6 @@ close_file(void *file_baton,
   if (!temp_file_path)
     SVN_ERR(svn_wc__text_base_path(&temp_file_path, eb->db, fb->local_abspath,
                                    FALSE, fb->pool));
-  SVN_ERR(svn_dirent_get_absolute(&temp_file_abspath, temp_file_path,
-                                  fb->pool));
 
   /* If the file isn't in the working copy (either because it was added
      in the BASE->repos diff or because we're diffing against WORKING

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/entries.c?rev=929279&r1=929278&r2=929279&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/entries.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/entries.c Tue Mar 30 20:57:53 2010
@@ -114,6 +114,7 @@ typedef struct {
 /*** reading and writing the entries file ***/
 
 
+/* */
 static svn_wc_entry_t *
 alloc_entry(apr_pool_t *pool)
 {
@@ -179,6 +180,7 @@ take_from_entry(const svn_wc_entry_t *sr
     }
 }
 
+/* */
 static svn_error_t *
 fetch_wc_id(apr_int64_t *wc_id, svn_sqlite__db_t *sdb)
 {
@@ -756,7 +758,7 @@ read_entries_new(apr_hash_t **result_ent
 
               if (base_status == svn_wc__db_status_not_present)
                 {
-                  /* ### the underlying node is DELETED in this revision.  */
+                  /* The underlying node is DELETED in this revision.  */
                   entry->deleted = TRUE;
 
                   /* This is an add since there isn't a node to replace.  */
@@ -1081,6 +1083,7 @@ read_entries_new(apr_hash_t **result_ent
 }
 
 
+/* */
 static svn_error_t *
 read_entries(apr_hash_t **entries,
              svn_wc__db_t *db,
@@ -1487,7 +1490,7 @@ prune_deleted(apr_hash_t **entries_prune
       svn_boolean_t hidden;
 
       SVN_ERR(svn_wc__entry_is_hidden(&hidden,
-                                      svn_apr_hash_index_val(hi)));
+                                      svn__apr_hash_index_val(hi)));
       if (hidden)
         break;
     }
@@ -1505,8 +1508,8 @@ prune_deleted(apr_hash_t **entries_prune
        hi;
        hi = apr_hash_next(hi))
     {
-      const void *key = svn_apr_hash_index_key(hi);
-      const svn_wc_entry_t *entry = svn_apr_hash_index_val(hi);
+      const void *key = svn__apr_hash_index_key(hi);
+      const svn_wc_entry_t *entry = svn__apr_hash_index_val(hi);
       svn_boolean_t hidden;
 
       SVN_ERR(svn_wc__entry_is_hidden(&hidden, entry));
@@ -1607,6 +1610,7 @@ svn_wc__set_depth(svn_wc__db_t *db,
                                                            scratch_pool));
 }
 
+/* */
 static svn_error_t *
 insert_base_node(svn_sqlite__db_t *sdb,
                  const db_base_node_t *base_node,
@@ -1681,6 +1685,7 @@ insert_base_node(svn_sqlite__db_t *sdb,
   return svn_error_return(svn_sqlite__insert(NULL, stmt));
 }
 
+/* */
 static svn_error_t *
 insert_working_node(svn_sqlite__db_t *sdb,
                     const db_working_node_t *working_node,
@@ -1762,6 +1767,7 @@ insert_working_node(svn_sqlite__db_t *sd
   return svn_error_return(svn_sqlite__insert(NULL, stmt));
 }
 
+/* */
 static svn_error_t *
 insert_actual_node(svn_sqlite__db_t *sdb,
                    const db_actual_node_t *actual_node,
@@ -2254,8 +2260,8 @@ entries_write_new_cb(void *baton,
   for (hi = apr_hash_first(scratch_pool, ewb->entries); hi;
        hi = apr_hash_next(hi))
     {
-      const char *name = svn_apr_hash_index_key(hi);
-      const svn_wc_entry_t *this_entry = svn_apr_hash_index_val(hi);
+      const char *name = svn__apr_hash_index_key(hi);
+      const svn_wc_entry_t *this_entry = svn__apr_hash_index_val(hi);
       const char *child_abspath;
 
       svn_pool_clear(iterpool);
@@ -2459,6 +2465,7 @@ write_one_entry_cb(void *baton,
   return SVN_NO_ERROR;
 }
 
+/* */
 static svn_error_t *
 write_one_entry(svn_wc__db_t *db,
                 const char *local_abspath,
@@ -3190,8 +3197,8 @@ walker_helper(const char *dirpath,
   /* Loop over each of the other entries. */
   for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi))
     {
-      const char *name = svn_apr_hash_index_key(hi);
-      const svn_wc_entry_t *current_entry = svn_apr_hash_index_val(hi);
+      const char *name = svn__apr_hash_index_key(hi);
+      const svn_wc_entry_t *current_entry = svn__apr_hash_index_val(hi);
       const char *entrypath;
       const char *entry_abspath;
       svn_boolean_t hidden;
@@ -3358,36 +3365,60 @@ svn_wc_walk_entries3(const char *path,
 }
 
 svn_error_t *
-svn_wc_mark_missing_deleted(const char *path,
-                            svn_wc_adm_access_t *parent,
-                            apr_pool_t *pool)
+svn_wc__temp_mark_missing_not_present(const char *local_abspath,
+                                      svn_wc_context_t *wc_ctx,
+                                      apr_pool_t *scratch_pool)
 {
-  svn_node_kind_t pkind;
-  const char *local_abspath;
-  svn_wc__db_t *db = svn_wc__adm_get_db(parent);
-
-  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
-
-  SVN_ERR(svn_io_check_path(path, &pkind, pool));
+  svn_wc__db_status_t status;
+  svn_wc__db_kind_t kind;
 
-  if (pkind == svn_node_none)
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+  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,
+                               wc_ctx->db, local_abspath,
+                               scratch_pool, scratch_pool));
+  if (kind == svn_wc__db_kind_dir
+      && status == svn_wc__db_status_obstructed_delete)
     {
       svn_wc_entry_t tmp_entry;
 
       tmp_entry.deleted = TRUE;
       tmp_entry.schedule = svn_wc_schedule_normal;
 
-      return svn_error_return(
-        svn_wc__entry_modify2(db, local_abspath, svn_node_unknown, FALSE,
-                              &tmp_entry,
-                              (SVN_WC__ENTRY_MODIFY_DELETED
-                               | SVN_WC__ENTRY_MODIFY_SCHEDULE
-                               | SVN_WC__ENTRY_MODIFY_FORCE),
-                              pool));
+      SVN_ERR(svn_wc__entry_modify2(wc_ctx->db, local_abspath,
+                                    svn_node_dir, TRUE, &tmp_entry,
+                                    (SVN_WC__ENTRY_MODIFY_DELETED
+                                     | SVN_WC__ENTRY_MODIFY_SCHEDULE
+                                     | SVN_WC__ENTRY_MODIFY_FORCE),
+                                    scratch_pool));
+      return SVN_NO_ERROR;
     }
 
   return svn_error_createf(SVN_ERR_WC_PATH_FOUND, NULL,
                            _("Unexpectedly found '%s': "
                              "path is marked 'missing'"),
-                           svn_dirent_local_style(path, pool));
+                           svn_dirent_local_style(local_abspath, scratch_pool));
+}
+
+svn_error_t *
+svn_wc_mark_missing_deleted(const char *path,
+                            svn_wc_adm_access_t *parent,
+                            apr_pool_t *pool)
+{
+  const char *local_abspath;
+  svn_wc_context_t *wc_ctx;
+
+  SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL,
+                                         svn_wc__adm_get_db(parent), pool));
+
+  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
+
+  SVN_ERR(svn_wc__temp_mark_missing_not_present(local_abspath, wc_ctx, pool));
+
+  SVN_ERR(svn_wc_context_destroy(wc_ctx));
+
+  return SVN_NO_ERROR;
 }