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 20:06:33 UTC

svn commit: r984153 [22/39] - in /subversion/branches/ignore-mergeinfo: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/hudson/ build/hudson/jobs/subversion-1.6.x-solaris/ build/hudson/jobs/subversion-1.6.x-ubuntu/ build/hu...

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_ops.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_ops.c Tue Aug 10 18:06:17 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. ***/
 
@@ -237,34 +247,6 @@ tweak_entries(svn_wc__db_t *db,
   return SVN_NO_ERROR;
 }
 
-
-static svn_error_t *
-remove_revert_files(svn_wc__db_t *db,
-                    const char *adm_abspath,
-                    const char *local_abspath,
-                    apr_pool_t *pool)
-{
-  svn_stringbuf_t *log_accum = svn_stringbuf_create("", pool);
-  const char *revert_file;
-  svn_node_kind_t kind;
-
-  SVN_ERR(svn_wc__text_revert_path(&revert_file, db, local_abspath, pool));
-
-  SVN_ERR(svn_io_check_path(revert_file, &kind, pool));
-  if (kind == svn_node_file)
-    SVN_ERR(svn_wc__loggy_remove(&log_accum, adm_abspath,
-                                 revert_file, pool, pool));
-  SVN_WC__FLUSH_LOG_ACCUM(db, adm_abspath, log_accum, pool);
-
-  SVN_ERR(svn_wc__loggy_props_delete(&log_accum, db, local_abspath,
-                                     adm_abspath,
-                                     svn_wc__props_revert, pool));
-
-  SVN_ERR(svn_wc__wq_add_loggy(db, adm_abspath, log_accum, pool));
-
-  return SVN_NO_ERROR;
-}
-
 svn_error_t *
 svn_wc__do_update_cleanup(svn_wc__db_t *db,
                           const char *local_abspath,
@@ -344,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,
@@ -362,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,
@@ -373,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,
@@ -394,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)
     {
@@ -409,64 +398,53 @@ process_committed_leaf(svn_wc__db_t *db,
       /* If the props or text revert file exists it needs to be deleted when
        * the file is committed. */
       /* ### don't directories have revert props? */
-      SVN_ERR(remove_revert_files(db, adm_abspath, local_abspath,
-                                  scratch_pool));
+      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));
 
-  SVN_ERR(svn_wc__wq_add_postcommit(db, local_abspath, new_revnum,
+  /* 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, tmp_text_base_abspath,
+                                    new_revnum,
                                     new_date, rev_author, checksum,
                                     new_dav_cache, keep_changelist,
                                     scratch_pool));
@@ -475,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)
     {
@@ -528,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);
 
@@ -550,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
@@ -586,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));
             }
         }
 
@@ -602,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;
 }
 
 
@@ -634,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,
@@ -653,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,
@@ -661,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;
     }
 
@@ -729,114 +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;
-  const svn_wc_entry_t *entry;
-  svn_wc_entry_t tmp_entry;
   int i;
 
   /* Read the entries file for this directory. */
@@ -848,6 +763,7 @@ mark_tree_deleted(svn_wc__db_t *db,
       const char *child_basename = APR_ARRAY_IDX(children, i, const char *);
       const char *child_abspath;
       svn_boolean_t hidden;
+      svn_wc__db_kind_t kind;
 
       /* Clear our per-iteration pool. */
       svn_pool_clear(iterpool);
@@ -859,36 +775,19 @@ mark_tree_deleted(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_kind(&kind, db, child_abspath, FALSE, iterpool));
 
-      /* If this is a directory, recurse. */
-      if (entry->kind == svn_node_dir)
+      /* 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));
         }
-
-      /* If this node has no function after the delete, remove it
-         directly. Otherwise svn_wc__entry_modify2 would do this for us,
-         but using the entries api would leave the db handle open */
-      /* ### BH: This check matches the only case in fold_scheduling()
-                 that removes the entry via delete scheduling */
-      if (entry->schedule == svn_wc_schedule_add && !entry->deleted)
-        {
-          SVN_ERR(svn_wc__entry_remove(db, child_abspath, pool));
-          SVN_ERR(svn_wc__db_temp_forget_directory(db, dir_abspath, pool));
-        }
       else
         {
-          tmp_entry.schedule = svn_wc_schedule_delete;
-          SVN_ERR(svn_wc__entry_modify2(db, child_abspath, svn_node_unknown,
-                                        TRUE, &tmp_entry,
-                                        SVN_WC__ENTRY_MODIFY_SCHEDULE,
-                                        iterpool));
+          SVN_ERR(svn_wc__db_temp_op_delete(db, child_abspath, pool));
         }
 
       /* Tell someone what we've done. */
@@ -900,26 +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__get_entry(&entry, db, dir_abspath, FALSE,
-                            svn_node_dir, FALSE, 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 (entry->schedule != svn_wc_schedule_add)
-    {
-      tmp_entry.schedule = svn_wc_schedule_delete;
-      tmp_entry.keep_local = keep_local;
-
-      SVN_ERR(svn_wc__entry_modify2(db, dir_abspath, svn_node_dir, FALSE,
-                                    &tmp_entry,
-                                    SVN_WC__ENTRY_MODIFY_SCHEDULE |
-                                    SVN_WC__ENTRY_MODIFY_KEEP_LOCAL,
-                                    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);
@@ -1082,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);
 
@@ -1123,7 +1006,6 @@ svn_wc_delete4(svn_wc_context_t *wc_ctx,
   svn_boolean_t was_copied = FALSE;
   svn_boolean_t was_deleted = FALSE; /* Silence a gcc uninitialized warning */
   svn_error_t *err;
-  const char *parent_abspath = svn_dirent_dirname(local_abspath, pool);
   svn_wc__db_status_t status;
   svn_wc__db_kind_t kind;
   svn_boolean_t base_shadowed;
@@ -1214,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));
             }
@@ -1229,63 +1110,20 @@ svn_wc_delete4(svn_wc_context_t *wc_ctx,
 
   if (kind != svn_wc__db_kind_dir || !was_add || was_deleted)
     {
-      /* We need to mark this entry for deletion in its parent's entries
-         file, so we split off base_name from the parent path, then fold in
-         the addition of a delete flag. */
-      svn_stringbuf_t *log_accum = svn_stringbuf_create("", pool);
-      svn_wc_entry_t tmp_entry;
-
-      /* Edit the entry to reflect the now deleted state.
-         entries.c:fold_entry() clears the values of copied, copyfrom_rev
-         and copyfrom_url. */
-      tmp_entry.schedule = svn_wc_schedule_delete;
-      SVN_ERR(svn_wc__loggy_entry_modify(&log_accum,
-                                         parent_abspath,
-                                         local_abspath, &tmp_entry,
-                                         SVN_WC__ENTRY_MODIFY_SCHEDULE,
-                                         pool, pool));
-      SVN_WC__FLUSH_LOG_ACCUM(db, parent_abspath, log_accum, pool);
-
-      /* is it a replacement with history? */
-      if (was_replace && was_copied)
-        {
-          const char *text_base, *text_revert;
-
-          SVN_ERR(svn_wc__text_base_path(&text_base, wc_ctx->db, local_abspath,
-                                         FALSE, pool));
-
-          SVN_ERR(svn_wc__text_revert_path(&text_revert, wc_ctx->db,
-                                           local_abspath, pool));
-
-          if (kind != svn_wc__db_kind_dir) /* Dirs don't have text-bases */
-            /* Restore the original text-base */
-            SVN_ERR(svn_wc__loggy_move(&log_accum,
-                                       parent_abspath,
-                                       text_revert, text_base,
-                                       pool, pool));
-          SVN_WC__FLUSH_LOG_ACCUM(db, parent_abspath, log_accum, pool);
-
-          SVN_ERR(svn_wc__loggy_revert_props_restore(&log_accum, wc_ctx->db,
-                                                     local_abspath,
-                                                     parent_abspath, pool));
-          SVN_WC__FLUSH_LOG_ACCUM(db, parent_abspath, log_accum, pool);
-        }
-      if (was_add)
-        {
-          SVN_ERR(svn_wc__loggy_props_delete(&log_accum, wc_ctx->db,
-                                             local_abspath, parent_abspath,
-                                             svn_wc__props_base, pool));
-          SVN_WC__FLUSH_LOG_ACCUM(db, parent_abspath, log_accum, pool);
+      const char *parent_abspath = svn_dirent_dirname(local_abspath, pool);
 
-          SVN_ERR(svn_wc__loggy_props_delete(&log_accum, wc_ctx->db,
-                                             local_abspath, parent_abspath,
-                                             svn_wc__props_working, pool));
-          SVN_WC__FLUSH_LOG_ACCUM(db, parent_abspath, log_accum, pool);
-        }
-
-      SVN_ERR(svn_wc__wq_add_loggy(db, parent_abspath, log_accum, pool));
+      /* ### The following two operations should be inside one SqLite
+             transaction. For even better behavior the tree operation
+             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));
+      SVN_ERR(svn_wc__wq_add_delete(wc_ctx->db, parent_abspath, local_abspath,
+                                    kind, was_add, was_copied, was_replace,
+                                    pool));
 
-      SVN_ERR(svn_wc__run_log2(db, parent_abspath, pool));
+      SVN_ERR(svn_wc__wq_run(db, parent_abspath, cancel_func, cancel_baton,
+                             pool));
     }
 
   /* Report the deletion to the caller. */
@@ -1362,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. */
@@ -1388,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. */
@@ -1401,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. */
@@ -1635,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. */
@@ -1685,7 +1526,11 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
                                                 pool);
 
           /* Make sure this new directory has an admistrative subdirectory
-             created inside of it */
+             created inside of it.
+
+             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,
                                               new_url, parent_entry->repos,
                                               parent_entry->uuid, 0,
@@ -1734,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
@@ -1772,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.  */
@@ -1787,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. */
@@ -1858,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,
@@ -1889,21 +1746,35 @@ static svn_error_t *
 revert_entry(svn_depth_t *depth,
              svn_wc__db_t *db,
              const char *local_abspath,
-             svn_node_kind_t kind,
-             const svn_wc_entry_t *entry,
+             svn_node_kind_t disk_kind,
              svn_boolean_t use_commit_times,
              svn_cancel_func_t cancel_func,
              void *cancel_baton,
              svn_boolean_t *did_revert,
              apr_pool_t *pool)
 {
+  svn_wc__db_status_t status;
+  svn_wc__db_kind_t kind;
+  svn_boolean_t replaced;
+
   /* Initialize this even though revert_admin_things() is guaranteed
      to set it, because we don't know that revert_admin_things() will
      be called. */
   svn_boolean_t reverted = FALSE;
 
+  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, pool, pool));
+
+  SVN_ERR(svn_wc__internal_is_replaced(&replaced, db, local_abspath, pool));
+
   /* Additions. */
-  if (entry->schedule == svn_wc_schedule_add)
+  if ((status == svn_wc__db_status_added
+       || status == svn_wc__db_status_obstructed_add)
+      && !replaced)
     {
       svn_revnum_t base_revision;
       const char *repos_relpath;
@@ -1925,9 +1796,9 @@ revert_entry(svn_depth_t *depth,
          ### shoved back into the database. this is why we need to record
          ### the repository information, and the BASE revision.  */
 
-      if (entry->kind == svn_node_file)
+      if (kind == svn_wc__db_kind_file)
         {
-          was_deleted = entry->deleted;
+          was_deleted = (status == svn_wc__db_status_not_present);
           if (was_deleted)
             {
               /* Remember the BASE revision.  */
@@ -1953,7 +1824,7 @@ revert_entry(svn_depth_t *depth,
                                                                 cancel_baton,
                                                                 pool));
         }
-      else if (entry->kind == svn_node_dir)
+      else if (kind == svn_wc__db_kind_dir)
         {
           const char *path;
           SVN_ERR(svn_wc__temp_get_relpath(&path, db, local_abspath,
@@ -1990,7 +1861,7 @@ revert_entry(svn_depth_t *depth,
                                                  pool, pool));
             }
 
-          if (kind == svn_node_none
+          if (disk_kind == svn_node_none
               || svn_wc__adm_missing(db, local_abspath, pool))
             {
               /* Schedule add but missing, just remove the entry
@@ -2035,26 +1906,23 @@ revert_entry(svn_depth_t *depth,
                     db, local_abspath,
                     repos_relpath, repos_root_url, repos_uuid,
                     base_revision,
-                    entry->kind == svn_node_dir
-                      ? svn_wc__db_kind_dir
-                      : svn_wc__db_kind_file,
+                    kind,
                     svn_wc__db_status_not_present,
                     pool));
         }
     }
   /* Regular prop and text edit. */
   /* Deletions and replacements. */
-  else if (entry->schedule == svn_wc_schedule_normal
-           || entry->schedule == svn_wc_schedule_delete
-           || entry->schedule == svn_wc_schedule_replace)
+  else if (status == svn_wc__db_status_normal
+           || status == svn_wc__db_status_deleted
+           || replaced)
     {
       /* Revert the prop and text mods (if any). */
       SVN_ERR(revert_admin_things(&reverted, db, local_abspath,
                                   use_commit_times, pool));
 
       /* Force recursion on replaced directories. */
-      if (entry->kind == svn_node_dir
-          && entry->schedule == svn_wc_schedule_replace)
+      if (kind == svn_wc__db_kind_dir && replaced)
         *depth = svn_depth_infinity;
     }
 
@@ -2082,8 +1950,10 @@ revert_internal(svn_wc__db_t *db,
                 void *notify_baton,
                 apr_pool_t *pool)
 {
-  svn_node_kind_t kind;
-  const svn_wc_entry_t *entry;
+  svn_node_kind_t disk_kind;
+  svn_wc__db_status_t status;
+  svn_wc__db_kind_t db_kind;
+  svn_boolean_t unversioned;
   const svn_wc_conflict_description2_t *tree_conflict;
   const char *path;
   svn_error_t *err;
@@ -2097,25 +1967,36 @@ revert_internal(svn_wc__db_t *db,
 
   /* Safeguard 1: the item must be versioned for any reversion to make sense,
      except that a tree conflict can exist on an unversioned item. */
-  err = svn_wc__get_entry(&entry, db, local_abspath, TRUE, svn_node_unknown,
-                          FALSE, pool, pool);
+  err = svn_wc__db_read_info(&status, &db_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, pool, pool);
 
-  if (err && err->apr_err == SVN_ERR_NODE_UNEXPECTED_KIND)
-    svn_error_clear(err);
+  if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+    {
+      svn_error_clear(err);
+      unversioned = TRUE;
+    }
+  else if (err)
+    return svn_error_return(err);
   else
-    SVN_ERR(err);
+    unversioned = FALSE;
 
   SVN_ERR(svn_wc__db_op_read_tree_conflict(&tree_conflict, db, local_abspath,
                                            pool, pool));
-  if (entry == NULL && tree_conflict == NULL)
+  if (unversioned && tree_conflict == NULL)
     return svn_error_createf(SVN_ERR_UNVERSIONED_RESOURCE, NULL,
                              _("Cannot revert unversioned item '%s'"), path);
 
   /* Safeguard 1.5:  is this a missing versioned directory? */
-  SVN_ERR(svn_io_check_path(local_abspath, &kind, pool));
-  if (entry && (entry->kind == svn_node_dir))
+  SVN_ERR(svn_io_check_path(local_abspath, &disk_kind, pool));
+  if (!unversioned && (db_kind == svn_wc__db_kind_dir))
     {
-      if ((kind != svn_node_dir) && (entry->schedule != svn_wc_schedule_add))
+      if ((disk_kind != svn_node_dir)
+          && (status != svn_wc__db_status_added)
+          && (status != svn_wc__db_status_obstructed_add))
         {
           /* When the directory itself is missing, we can't revert without
              hitting the network.  Someday a '--force' option will
@@ -2133,7 +2014,8 @@ revert_internal(svn_wc__db_t *db,
     }
 
   /* Safeguard 2:  can we handle this entry's recorded kind? */
-  if (entry && (entry->kind != svn_node_file) && (entry->kind != svn_node_dir))
+  if (!unversioned
+      && (db_kind != svn_wc__db_kind_file) && (db_kind != svn_wc__db_kind_dir))
     return svn_error_createf
       (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
        _("Cannot revert '%s': unsupported entry node kind"),
@@ -2141,9 +2023,9 @@ revert_internal(svn_wc__db_t *db,
 
   /* Safeguard 3:  can we deal with the node kind of PATH currently in
      the working copy? */
-  if ((kind != svn_node_none)
-      && (kind != svn_node_file)
-      && (kind != svn_node_dir))
+  if ((disk_kind != svn_node_none)
+      && (disk_kind != svn_node_file)
+      && (disk_kind != svn_node_dir))
     return svn_error_createf
       (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
        _("Cannot revert '%s': unsupported node kind in working copy"),
@@ -2169,8 +2051,8 @@ revert_internal(svn_wc__db_t *db,
 
       /* Actually revert this entry.  If this is a working copy root,
          we provide a base_name from the parent path. */
-      if (entry)
-        SVN_ERR(revert_entry(&depth, db, local_abspath, kind, entry,
+      if (!unversioned)
+        SVN_ERR(revert_entry(&depth, db, local_abspath, disk_kind,
                              use_commit_times,
                              cancel_func, cancel_baton,
                              &reverted, pool));
@@ -2184,7 +2066,7 @@ revert_internal(svn_wc__db_t *db,
     }
 
   /* Finally, recurse if requested. */
-  if (entry && entry->kind == svn_node_dir && depth > svn_depth_empty)
+  if (!unversioned && db_kind == svn_wc__db_kind_dir && depth > svn_depth_empty)
     {
       const apr_array_header_t *children;
       apr_hash_t *nodes = apr_hash_make(pool);
@@ -2203,7 +2085,7 @@ revert_internal(svn_wc__db_t *db,
           const char *name = APR_ARRAY_IDX(children, i, const char *);
           const char *node_abspath;
           svn_boolean_t hidden;
-          svn_wc__db_kind_t db_kind;
+          svn_wc__db_kind_t child_db_kind;
 
           svn_pool_clear(iterpool);
 
@@ -2216,13 +2098,13 @@ revert_internal(svn_wc__db_t *db,
 
           apr_hash_set(nodes, name, APR_HASH_KEY_STRING, name);
 
-          SVN_ERR(svn_wc__db_read_kind(&db_kind, db, node_abspath, FALSE,
+          SVN_ERR(svn_wc__db_read_kind(&child_db_kind, db, node_abspath, FALSE,
                                        iterpool));
 
           /* Skip subdirectories if we're called with depth-files. */
           if ((depth == svn_depth_files) &&
-              (db_kind != svn_wc__db_kind_file) &&
-              (db_kind != svn_wc__db_kind_symlink))
+              (child_db_kind != svn_wc__db_kind_file) &&
+              (child_db_kind != svn_wc__db_kind_symlink))
             continue;
 
           /* Revert the entry. */
@@ -2234,34 +2116,48 @@ revert_internal(svn_wc__db_t *db,
 
       /* Visit any unversioned children that are tree conflict victims. */
       {
-        apr_hash_t *conflicts;
-        apr_hash_index_t *hi2;
+        const apr_array_header_t *conflict_victims;
 
         /* Loop through all the tree conflict victims */
-        SVN_ERR(svn_wc__read_tree_conflicts(&conflicts,
-                                            entry->tree_conflict_data,
-                                            path, pool));
+        SVN_ERR(svn_wc__db_read_conflict_victims(&conflict_victims,
+                                                 db, local_abspath,
+                                                 pool, pool));
 
-        for (hi2 = apr_hash_first(pool, conflicts); hi2;
-                                                     hi2 = apr_hash_next(hi2))
+        for (i = 0; i < conflict_victims->nelts; ++i)
           {
-            const svn_wc_conflict_description2_t *conflict =
-                                                svn_apr_hash_index_val(hi2);
+            int j;
+            const apr_array_header_t *child_conflicts;
+            const char *child_name;
+            const char *child_abspath;
 
             svn_pool_clear(iterpool);
 
-            /* If this victim is not in this dir's entries ... */
-            if (apr_hash_get(nodes,
-                             svn_dirent_basename(conflict->local_abspath,
-                                                 pool),
-                             APR_HASH_KEY_STRING) == NULL)
+            child_name = APR_ARRAY_IDX(conflict_victims, i, const char *);
+
+            /* Skip if in this dir's entries, we only want unversioned */
+            if (apr_hash_get(nodes, child_name, APR_HASH_KEY_STRING))
+              continue;
+
+            child_abspath = svn_dirent_join(local_abspath, child_name,
+                                            iterpool);
+
+            SVN_ERR(svn_wc__db_read_conflicts(&child_conflicts,
+                                              db, child_abspath,
+                                              iterpool, iterpool));
+
+            for (j = 0; j < child_conflicts->nelts; ++j)
               {
-                /* Revert the entry. */
-                SVN_ERR(revert_internal(db, conflict->local_abspath,
-                                        svn_depth_empty,
-                                        use_commit_times, changelist_hash,
-                                        cancel_func, cancel_baton,
-                                        notify_func, notify_baton, iterpool));
+                const svn_wc_conflict_description2_t *conflict =
+                  APR_ARRAY_IDX(child_conflicts, j,
+                                const svn_wc_conflict_description2_t *);
+
+                if (conflict->kind == svn_wc_conflict_kind_tree)
+                  SVN_ERR(revert_internal(db, conflict->local_abspath,
+                                          svn_depth_empty,
+                                          use_commit_times, changelist_hash,
+                                          cancel_func, cancel_baton,
+                                          notify_func, notify_baton,
+                                          iterpool));
               }
           }
       }
@@ -2304,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 *
@@ -2336,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));
+
+  /* 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 (text_base == NULL)
+  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/ignore-mergeinfo/subversion/libsvn_wc/ambient_depth_filter_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/ambient_depth_filter_editor.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/ambient_depth_filter_editor.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/ambient_depth_filter_editor.c Tue Aug 10 18:06:17 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/ignore-mergeinfo/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/conflicts.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/conflicts.c Tue Aug 10 18:06:17 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/ignore-mergeinfo/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/copy.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/copy.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/copy.c Tue Aug 10 18:06:17 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/ignore-mergeinfo/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/deprecated.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/deprecated.c Tue Aug 10 18:06:17 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/ignore-mergeinfo/subversion/libsvn_wc/diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/diff.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/diff.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/diff.c Tue Aug 10 18:06:17 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