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

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

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_client/commit_util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_client/commit_util.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_client/commit_util.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_client/commit_util.c Tue Aug 10 20:55:56 2010
@@ -74,7 +74,7 @@ fixup_out_of_date_error(const char *path
 /* Add a new commit candidate (described by all parameters except
    `COMMITTABLES') to the COMMITTABLES hash.  All of the commit item's
    members are allocated out of the COMMITTABLES hash pool. */
-static void
+static svn_error_t *
 add_committable(apr_hash_t *committables,
                 const char *path,
                 svn_node_kind_t kind,
@@ -90,7 +90,7 @@ add_committable(apr_hash_t *committables
   svn_client_commit_item3_t *new_item;
 
   /* Sanity checks. */
-  assert(path && url);
+  SVN_ERR_ASSERT(path && url);
 
   /* ### todo: Get the canonical repository for this item, which will
      be the real key for the COMMITTABLES hash, instead of the above
@@ -121,6 +121,8 @@ add_committable(apr_hash_t *committables
 
   /* Now, add the commit item to the array. */
   APR_ARRAY_PUSH(array, svn_client_commit_item3_t *) = new_item;
+
+  return SVN_NO_ERROR;
 }
 
 
@@ -201,8 +203,9 @@ add_lock_token(const char *local_abspath
   /* I want every lock-token I can get my dirty hands on!
      If this entry is switched, so what.  We will send an irrelevant lock
      token. */
-  SVN_ERR(svn_wc__node_get_lock_token(&lock_token, altb->wc_ctx, local_abspath,
-                                      scratch_pool, scratch_pool));
+  SVN_ERR(svn_wc__node_get_lock_info(&lock_token, NULL, NULL, NULL,
+                                     altb->wc_ctx, local_abspath,
+                                     scratch_pool, scratch_pool));
   if (!lock_token)
     return SVN_NO_ERROR;
 
@@ -237,7 +240,7 @@ add_lock_token(const char *local_abspath
 static svn_error_t *
 bail_on_tree_conflicted_children(svn_wc_context_t *wc_ctx,
                                  const char *local_abspath,
-                                 const svn_wc_entry_t *entry,
+                                 svn_node_kind_t kind,
                                  svn_depth_t depth,
                                  apr_hash_t *changelists,
                                  apr_pool_t *pool)
@@ -246,17 +249,18 @@ bail_on_tree_conflicted_children(svn_wc_
   apr_hash_index_t *hi;
 
   if ((depth == svn_depth_empty)
-      || (entry->kind != svn_node_dir)
-      || (strcmp(entry->name, SVN_WC_ENTRY_THIS_DIR) != 0))
+      || (kind != svn_node_dir))
     /* There can't possibly be tree-conflicts information here. */
     return SVN_NO_ERROR;
 
-  SVN_ERR(svn_wc__read_tree_conflicts(&conflicts, entry->tree_conflict_data,
-                                      local_abspath, pool));
+  SVN_ERR(svn_wc__get_all_tree_conflicts(&conflicts, wc_ctx, local_abspath,
+                                         pool, pool));
+  if (!conflicts)
+    return SVN_NO_ERROR;
 
   for (hi = apr_hash_first(pool, conflicts); hi; hi = apr_hash_next(hi))
     {
-      const svn_wc_conflict_description_t *conflict =
+      const svn_wc_conflict_description2_t *conflict =
           svn__apr_hash_index_val(hi);
 
       if ((conflict->node_kind == svn_node_dir) &&
@@ -274,7 +278,7 @@ bail_on_tree_conflicted_children(svn_wc_
       return svn_error_createf(
                SVN_ERR_WC_FOUND_CONFLICT, NULL,
                _("Aborting commit: '%s' remains in conflict"),
-               svn_dirent_local_style(conflict->path, pool));
+               svn_dirent_local_style(conflict->local_abspath, pool));
     }
 
   return SVN_NO_ERROR;
@@ -327,10 +331,8 @@ bail_on_tree_conflicted_ancestor(svn_wc_
 
 
 /* Recursively search for commit candidates in (and under) LOCAL_ABSPATH
-   (with entry ENTRY and ancestry URL), and add those candidates to
-   COMMITTABLES.  If in ADDS_ONLY modes, only new additions are
-   recognized.  COPYFROM_URL is the default copyfrom-url for children
-   of copied directories.
+   and add those candidates to COMMITTABLES.  If in ADDS_ONLY modes, only
+   new additions are recognized.
 
    DEPTH indicates how to treat files and subdirectories of LOCAL_ABSPATH
    when LOCAL_ABSPATH is itself a directory; see
@@ -342,7 +344,10 @@ bail_on_tree_conflicted_ancestor(svn_wc_
 
    If in COPY_MODE, treat the entry as if it is destined to be added
    with history as URL, and add 'deleted' entries to COMMITTABLES as
-   items to delete in the copy destination.
+   items to delete in the copy destination.  URL must be NULL if not in
+   COPY_MODE.  COPY_MODE_ROOT should be set TRUE for the first call for
+   which COPY_MODE is TRUE, i.e. not for for the recursive calls, and FALSE
+   otherwise.
 
    If CHANGELISTS is non-NULL, it is a hash whose keys are const char *
    changelist names used as a restrictive filter
@@ -359,26 +364,31 @@ harvest_committables(apr_hash_t *committ
                      apr_hash_t *lock_tokens,
                      const char *local_abspath,
                      const char *url,
-                     const char *copyfrom_url,
-                     const svn_wc_entry_t *entry,
-                     const svn_wc_entry_t *parent_entry,
                      svn_boolean_t adds_only,
                      svn_boolean_t copy_mode,
+                     svn_boolean_t copy_mode_root,
                      svn_depth_t depth,
                      svn_boolean_t just_locked,
                      apr_hash_t *changelists,
                      svn_client_ctx_t *ctx,
                      apr_pool_t *scratch_pool)
 {
-  svn_boolean_t text_mod = FALSE, prop_mod = FALSE;
+  svn_boolean_t text_mod = FALSE;
+  svn_boolean_t prop_mod = FALSE;
   apr_byte_t state_flags = 0;
-  svn_node_kind_t kind;
+  svn_node_kind_t working_kind;
+  svn_node_kind_t db_kind;
+  const char *entry_url;
+  const char *entry_lock_token;
   const char *cf_url = NULL;
-  svn_revnum_t cf_rev = entry->copyfrom_rev;
+  svn_revnum_t entry_rev, cf_rev = SVN_INVALID_REVNUM;
   const svn_string_t *propval;
   svn_boolean_t is_special;
-  apr_pool_t *token_pool = (lock_tokens ? apr_hash_pool_get(lock_tokens)
-                            : NULL);
+  svn_boolean_t is_file_external;
+  svn_boolean_t is_added;
+  const char *node_copyfrom_url;
+  svn_revnum_t node_copyfrom_rev;
+  svn_boolean_t keep_local;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
@@ -386,8 +396,9 @@ harvest_committables(apr_hash_t *committ
   if (look_up_committable(committables, local_abspath, scratch_pool))
     return SVN_NO_ERROR;
 
-  SVN_ERR_ASSERT(entry);
-  SVN_ERR_ASSERT(url);
+  SVN_ERR_ASSERT((copy_mode && url) || (! copy_mode && ! url));
+  SVN_ERR_ASSERT((copy_mode_root && copy_mode) || ! copy_mode_root);
+  SVN_ERR_ASSERT((just_locked && lock_tokens) || !just_locked);
 
   if (ctx->cancel_func)
     SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
@@ -395,17 +406,23 @@ harvest_committables(apr_hash_t *committ
   /* Return error on unknown path kinds.  We check both the entry and
      the node itself, since a path might have changed kind since its
      entry was written. */
-  if ((entry->kind != svn_node_file) && (entry->kind != svn_node_dir))
+  SVN_ERR(svn_wc_read_kind(&db_kind, ctx->wc_ctx, local_abspath,
+                           TRUE, scratch_pool));
+  if ((db_kind != svn_node_file) && (db_kind != svn_node_dir))
     return svn_error_createf
       (SVN_ERR_NODE_UNKNOWN_KIND, NULL, _("Unknown entry kind for '%s'"),
        svn_dirent_local_style(local_abspath, scratch_pool));
 
-  SVN_ERR(svn_io_check_special_path(local_abspath, &kind, &is_special,
+  SVN_ERR(svn_io_check_special_path(local_abspath, &working_kind, &is_special,
                                     scratch_pool));
 
-  if ((kind != svn_node_file)
-      && (kind != svn_node_dir)
-      && (kind != svn_node_none))
+  /* ### In 1.6 an obstructed dir would fail when locking before we
+         got here.  Locking now doesn't fail so perhaps we should do
+         some sort of checking here. */
+
+  if ((working_kind != svn_node_file)
+      && (working_kind != svn_node_dir)
+      && (working_kind != svn_node_none))
     {
       return svn_error_createf
         (SVN_ERR_NODE_UNKNOWN_KIND, NULL,
@@ -422,7 +439,7 @@ harvest_committables(apr_hash_t *committ
 #ifdef HAVE_SYMLINK
        || ((propval) && (! is_special))
 #endif /* HAVE_SYMLINK */
-       ) && (kind != svn_node_none))
+       ) && (working_kind != svn_node_none))
     {
       return svn_error_createf
         (SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
@@ -430,28 +447,11 @@ harvest_committables(apr_hash_t *committ
          svn_dirent_local_style(local_abspath, scratch_pool));
     }
 
-  if (entry->file_external_path && copy_mode)
+  SVN_ERR(svn_wc__node_is_file_external(&is_file_external, ctx->wc_ctx,
+                                        local_abspath, scratch_pool));
+  if (is_file_external && copy_mode)
     return SVN_NO_ERROR;
 
-  if (entry->kind == svn_node_dir)
-    {
-      /* Read the dir's own entries for use when recursing. */
-      svn_error_t *err;
-      const svn_wc_entry_t *e = NULL;
-
-      err = svn_wc__maybe_get_entry(&e, ctx->wc_ctx,
-                                    local_abspath, svn_node_dir,
-                                    FALSE, FALSE,
-                                    scratch_pool, scratch_pool);
-
-      /* If we failed to get an entries hash for the directory, no
-         sweat.  Cleanup and move along.  */
-      if (err)
-        svn_error_clear(err);
-      else if (e != NULL)
-        entry = e;
-    }
-
   /* If ENTRY is in our changelist, then examine it for conflicts. We
      need to bail out if any conflicts exist.  */
   if (svn_wc__changelist_match(ctx->wc_ctx, local_abspath, changelists,
@@ -470,20 +470,20 @@ harvest_committables(apr_hash_t *committ
         }
     }
 
-  /* If the entry is deleted with "--keep-local", we can skip checking
-     for conflicts inside. */
-  if (entry->keep_local)
-    SVN_ERR_ASSERT(entry->schedule == svn_wc_schedule_delete);
-  else
+  SVN_ERR(svn_wc__temp_get_keep_local(&keep_local, ctx->wc_ctx,
+                                      local_abspath, scratch_pool));
+  if (! keep_local)
     SVN_ERR(bail_on_tree_conflicted_children(ctx->wc_ctx, local_abspath,
-                                             entry, depth, changelists,
+                                             db_kind, depth, changelists,
                                              scratch_pool));
 
-  /* If we have our own URL, and we're NOT in COPY_MODE, it wins over
-     the telescoping one(s).  In COPY_MODE, URL will always be the
-     URL-to-be of the copied item.  */
-  if ((entry->url) && (! copy_mode))
-    url = entry->url;
+  /* Our own URL wins if not in COPY_MODE.  In COPY_MODE the
+     telescoping URLs are used. */
+  SVN_ERR(svn_wc__node_get_url(&entry_url, ctx->wc_ctx, local_abspath,
+                               scratch_pool, scratch_pool));
+  if (! copy_mode)
+    url = entry_url;
+
 
   /* Check for the deletion case.  Deletes occur only when not in
      "adds-only mode".  We use the SVN_CLIENT_COMMIT_ITEM_DELETE flag
@@ -496,73 +496,136 @@ harvest_committables(apr_hash_t *committ
      - The entry is scheduled for deletion or replacement, which case
        we need to send a delete either way.
   */
-  if ((! adds_only)
-      && ((entry->deleted && entry->schedule == svn_wc_schedule_normal)
-          || (entry->schedule == svn_wc_schedule_delete)
-          || (entry->schedule == svn_wc_schedule_replace)))
+  if (! adds_only)
     {
-      state_flags |= SVN_CLIENT_COMMIT_ITEM_DELETE;
+      svn_boolean_t is_replaced;
+      svn_boolean_t is_status_deleted;
+      svn_boolean_t is_present;
+
+      /* ### There is room for optimization here, but let's keep it plain
+       * while this function is in flux. */
+      SVN_ERR(svn_wc__node_is_status_deleted(&is_status_deleted, ctx->wc_ctx,
+                                             local_abspath, scratch_pool));
+      SVN_ERR(svn_wc__node_is_replaced(&is_replaced, ctx->wc_ctx,
+                                       local_abspath, scratch_pool));
+      SVN_ERR(svn_wc__node_is_status_present(&is_present, ctx->wc_ctx,
+                                             local_abspath, scratch_pool));
+
+      /* ### Catch a mixed-rev copy that replaces. The mixed-rev children are
+       * each regarded as op-roots of the replace and result in currently
+       * unexpected behaviour. Model wc-1 behaviour, seeing only one copy
+       * target at the root of a mixed-rev copy, via
+       * svn_wc__node_get_copyfrom_info(). */
+      if (is_replaced)
+        {
+          const char *is_copy;
+          svn_boolean_t is_copy_target;
+          /* ### TODO: sensibly align this call of get_copyfrom_info() with
+           * the same call below (when checking added nodes). */
+          SVN_ERR(svn_wc__node_get_copyfrom_info(&is_copy, NULL,
+                                                 &is_copy_target, ctx->wc_ctx,
+                                                 local_abspath, scratch_pool,
+                                                 scratch_pool));
+          if (is_copy && ! is_copy_target)
+            is_replaced = FALSE;
+        }
+
+      if (is_status_deleted || is_replaced || ! is_present)
+        state_flags |= SVN_CLIENT_COMMIT_ITEM_DELETE;
     }
 
   /* Check for the trivial addition case.  Adds can be explicit
      (schedule == add) or implicit (schedule == replace ::= delete+add).
      We also note whether or not this is an add with history here.  */
-  if ((entry->schedule == svn_wc_schedule_add)
-      || (entry->schedule == svn_wc_schedule_replace))
-    {
-      state_flags |= SVN_CLIENT_COMMIT_ITEM_ADD;
-      if (entry->copyfrom_url)
+  SVN_ERR(svn_wc__node_is_added(&is_added, ctx->wc_ctx, local_abspath,
+                                scratch_pool));
+  if (is_added)
+    {
+      svn_boolean_t is_copy_target;
+
+      SVN_ERR(svn_wc__node_get_copyfrom_info(&node_copyfrom_url,
+                                             &node_copyfrom_rev,
+                                             &is_copy_target,
+                                             ctx->wc_ctx, local_abspath,
+                                             scratch_pool, scratch_pool));
+      if (is_copy_target)
         {
+          state_flags |= SVN_CLIENT_COMMIT_ITEM_ADD;
           state_flags |= SVN_CLIENT_COMMIT_ITEM_IS_COPY;
-          cf_url = entry->copyfrom_url;
+          cf_url = node_copyfrom_url;
+          cf_rev = node_copyfrom_rev;
           adds_only = FALSE;
         }
-      else
+      else if (!node_copyfrom_url)
         {
+          state_flags |= SVN_CLIENT_COMMIT_ITEM_ADD;
           adds_only = TRUE;
         }
-    }
-
-  /* Check for the copied-subtree addition case.  */
-  if ((entry->copied || copy_mode)
-      && (! entry->deleted)
-      && (entry->schedule == svn_wc_schedule_normal))
-    {
-      svn_revnum_t p_rev = entry->revision - 1; /* arbitrary non-equal value */
-      svn_boolean_t wc_root = FALSE;
-
-      /* If this is not a WC root then its parent's revision is
-         admissible for comparative purposes. */
-      SVN_ERR(svn_wc_is_wc_root2(&wc_root, ctx->wc_ctx, local_abspath,
-                                 scratch_pool));
-      if (! wc_root)
+      else
         {
-          if (parent_entry)
-            p_rev = parent_entry->revision;
+          /* ### svn_wc__node_get_copyfrom_info has pre-wc-ng
+             behaviour for is_copy_target.  In this case we really
+             want all the copy targets, even those where just the
+             copfrom revision is different. */
+          const char *parent_copyfrom_url;
+          svn_revnum_t parent_copyfrom_rev;
+          const char *parent_abspath = svn_dirent_dirname(local_abspath,
+                                                          scratch_pool);
+
+          SVN_ERR(svn_wc__node_get_copyfrom_info(&parent_copyfrom_url,
+                                                 &parent_copyfrom_rev,
+                                                 NULL,
+                                                 ctx->wc_ctx, parent_abspath,
+                                                 scratch_pool, scratch_pool));
+          if (parent_copyfrom_rev != node_copyfrom_rev)
+            {
+              state_flags |= SVN_CLIENT_COMMIT_ITEM_ADD;
+              state_flags |= SVN_CLIENT_COMMIT_ITEM_IS_COPY;
+              cf_url = node_copyfrom_url;
+              cf_rev = node_copyfrom_rev;
+              adds_only = FALSE;
+            }
         }
-      else if (! copy_mode)
-        return svn_error_createf
-          (SVN_ERR_WC_CORRUPT, NULL,
-           _("Did not expect '%s' to be a working copy root"),
-           svn_dirent_local_style(local_abspath, scratch_pool));
-
-      /* If the ENTRY's revision differs from that of its parent, we
-         have to explicitly commit ENTRY as a copy. */
-      if (entry->revision != p_rev)
+    }
+  else
+    {
+      node_copyfrom_url = NULL;
+      node_copyfrom_rev = SVN_INVALID_REVNUM;
+    }
+
+  SVN_ERR(svn_wc__node_get_base_rev(&entry_rev, ctx->wc_ctx, local_abspath,
+                                    scratch_pool));
+
+  /* Further additions occur in copy mode. */
+  if (copy_mode && !(state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE))
+    {
+      svn_revnum_t p_rev;
+
+      if (!copy_mode_root)
+        SVN_ERR(svn_wc__node_get_base_rev(&p_rev, ctx->wc_ctx,
+                                          svn_dirent_dirname(local_abspath,
+                                                             scratch_pool),
+                                          scratch_pool));
+
+      if (copy_mode_root || entry_rev != p_rev)
         {
           state_flags |= SVN_CLIENT_COMMIT_ITEM_ADD;
-          state_flags |= SVN_CLIENT_COMMIT_ITEM_IS_COPY;
-          adds_only = FALSE;
-          cf_rev = entry->revision;
-          if (copy_mode)
-            cf_url = entry->url;
-          else if (copyfrom_url)
-            cf_url = copyfrom_url;
-          else /* ### See issue #830 */
-            return svn_error_createf
-              (SVN_ERR_BAD_URL, NULL,
-               _("Commit item '%s' has copy flag but no copyfrom URL"),
-               svn_dirent_local_style(local_abspath, scratch_pool));
+          if (node_copyfrom_url)
+            {
+              state_flags |= SVN_CLIENT_COMMIT_ITEM_IS_COPY;
+              cf_url = node_copyfrom_url;
+              cf_rev = node_copyfrom_rev;
+              adds_only = FALSE;
+            }
+          else if (entry_rev != SVN_INVALID_REVNUM)
+            {
+              state_flags |= SVN_CLIENT_COMMIT_ITEM_IS_COPY;
+              cf_url = entry_url;
+              cf_rev = entry_rev;
+              adds_only = FALSE;
+            }
+          else
+            adds_only = TRUE;
         }
     }
 
@@ -570,12 +633,10 @@ harvest_committables(apr_hash_t *committ
      information about it. */
   if (state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)
     {
-      svn_node_kind_t working_kind;
       svn_boolean_t eol_prop_changed;
 
       /* First of all, the working file or directory must exist.
          See issue #3198. */
-      SVN_ERR(svn_io_check_path(local_abspath, &working_kind, scratch_pool));
       if (working_kind == svn_node_none)
         {
           return svn_error_createf
@@ -590,7 +651,7 @@ harvest_committables(apr_hash_t *committ
 
       /* Regular adds of files have text mods, but for copies we have
          to test for textual mods.  Directories simply don't have text! */
-      if (entry->kind == svn_node_file)
+      if (db_kind == svn_node_file)
         {
           /* Check for text mods.  If EOL_PROP_CHANGED is TRUE, then
              we need to force a translated byte-for-byte comparison
@@ -624,7 +685,7 @@ harvest_committables(apr_hash_t *committ
          bail out early.  Depending on how the svn:eol-style prop was
          changed, we might have to send new text to the server to
          match the new newline style.  */
-      if (entry->kind == svn_node_file)
+      if (db_kind == svn_node_file)
         SVN_ERR(svn_wc_text_modified_p2(&text_mod, ctx->wc_ctx, local_abspath,
                                         eol_prop_changed, scratch_pool));
     }
@@ -638,9 +699,15 @@ harvest_committables(apr_hash_t *committ
   /* If the entry has a lock token and it is already a commit candidate,
      or the caller wants unmodified locked items to be treated as
      such, note this fact. */
-  if (entry->lock_token
-      && (state_flags || just_locked))
-    state_flags |= SVN_CLIENT_COMMIT_ITEM_LOCK_TOKEN;
+  if (lock_tokens && (state_flags || just_locked))
+    {
+      SVN_ERR(svn_wc__node_get_lock_info(&entry_lock_token, NULL, NULL, NULL,
+                                         ctx->wc_ctx, local_abspath,
+                                         apr_hash_pool_get(lock_tokens),
+                                         scratch_pool));
+      if (entry_lock_token)
+        state_flags |= SVN_CLIENT_COMMIT_ITEM_LOCK_TOKEN;
+    }
 
   /* Now, if this is something to commit, add it to our list. */
   if (state_flags)
@@ -649,22 +716,22 @@ harvest_committables(apr_hash_t *committ
                                    scratch_pool))
         {
           /* Finally, add the committable item. */
-          add_committable(committables, local_abspath, entry->kind, url,
-                          entry->revision,
-                          cf_url,
-                          cf_rev,
-                          state_flags);
-          if (lock_tokens && entry->lock_token)
-            apr_hash_set(lock_tokens, apr_pstrdup(token_pool, url),
-                         APR_HASH_KEY_STRING,
-                         apr_pstrdup(token_pool, entry->lock_token));
+          SVN_ERR(add_committable(committables, local_abspath, db_kind, url,
+                                  entry_rev,
+                                  cf_url,
+                                  cf_rev,
+                                  state_flags));
+          if (state_flags & SVN_CLIENT_COMMIT_ITEM_LOCK_TOKEN)
+            apr_hash_set(lock_tokens,
+                         apr_pstrdup(apr_hash_pool_get(lock_tokens), url),
+                         APR_HASH_KEY_STRING, entry_lock_token);
         }
     }
 
   /* For directories, recursively handle each entry according to depth
      (except when the directory is being deleted, unless the deletion
      is part of a replacement ... how confusing).  */
-  if ((entry->kind == svn_node_dir) && (depth > svn_depth_empty)
+  if ((db_kind == svn_node_dir) && (depth > svn_depth_empty)
       && ((! (state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE))
           || (state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)))
     {
@@ -681,32 +748,17 @@ harvest_committables(apr_hash_t *committ
         {
           const char *this_abspath = APR_ARRAY_IDX(children, i, const char *);
           const char *name = svn_dirent_basename(this_abspath, NULL);
-          const svn_wc_entry_t *this_entry;
-          const char *full_path;
-          const char *used_url = NULL;
-          const char *this_cf_url = cf_url ? cf_url : copyfrom_url;
-          svn_error_t *err;
+          const char *this_url;
+          svn_depth_t this_depth;
+          svn_boolean_t is_replaced, this_is_deleted;
+          svn_node_kind_t this_kind;
 
           svn_pool_clear(iterpool);
 
-          err = svn_wc__get_entry_versioned(&this_entry, ctx->wc_ctx,
-                                            this_abspath, svn_node_unknown,
-                                            copy_mode, FALSE,
-                                            iterpool, iterpool);
-
-          if (err && err->apr_err == SVN_ERR_ENTRY_NOT_FOUND)
-            {
-              svn_error_clear(err);
-              SVN_ERR(svn_wc__get_entry_versioned(&this_entry, ctx->wc_ctx,
-                                                  this_abspath, svn_node_dir,
-                                                  copy_mode, TRUE,
-                                                  iterpool, iterpool));
-            }
-          else
-            SVN_ERR(err);
-
           /* Skip the excluded item. */
-          if (this_entry->depth == svn_depth_exclude)
+          SVN_ERR(svn_wc__node_get_depth(&this_depth, ctx->wc_ctx, this_abspath,
+                                         iterpool));
+          if (this_depth == svn_depth_exclude)
             continue;
 
           /* Issue #3281.
@@ -763,28 +815,23 @@ harvest_committables(apr_hash_t *committ
            * ### Note that, in trunk, the entry of post-replace deleted nodes
            * ### does not get blown away, so trunk is one step ahead of 1.6.x
            * ### already. */
-          if (entry->schedule == svn_wc_schedule_replace &&
-              this_entry->schedule == svn_wc_schedule_delete)
+          SVN_ERR(svn_wc__node_is_status_deleted(&this_is_deleted, ctx->wc_ctx,
+                                                 this_abspath, iterpool));
+          SVN_ERR(svn_wc__node_is_replaced(&is_replaced, ctx->wc_ctx,
+                                           local_abspath, iterpool));
+          if (is_replaced && this_is_deleted)
             continue;
 
-          full_path = svn_dirent_join(local_abspath, name, iterpool);
-          if (this_cf_url)
-            this_cf_url = svn_path_url_add_component2(this_cf_url, name,
-                                                      iterpool);
-
-          /* We'll use the entry's URL if it has one and if we aren't
-             in copy_mode, else, we'll just extend the parent's URL
-             with the entry's basename.
-
-             TODO: Do we even need this conditional with WC-NG?  Aren't we
-             always returning the URL in the entry struct? */
-          if (this_entry->url && !copy_mode)
-            used_url = this_entry->url;
+          if (! copy_mode)
+            SVN_ERR(svn_wc__node_get_url(&this_url, ctx->wc_ctx,
+                                         this_abspath, iterpool, iterpool));
           else
-            used_url = svn_path_url_add_component2(url, name, iterpool);
+            this_url = svn_path_url_add_component2(url, name, iterpool);
 
           /* Recurse. */
-          if (this_entry->kind == svn_node_dir)
+          SVN_ERR(svn_wc_read_kind(&this_kind, ctx->wc_ctx, this_abspath,
+                                   TRUE, iterpool));
+          if (this_kind == svn_node_dir)
             {
               if (depth <= svn_depth_files)
                 {
@@ -806,31 +853,26 @@ harvest_committables(apr_hash_t *committ
                       /* A missing, schedule-delete child dir is
                          allowable.  Just don't try to recurse. */
                       svn_node_kind_t childkind;
-                      err = svn_io_check_path(full_path,
-                                              &childkind,
-                                              iterpool);
-                      if (! err
-                          && (childkind == svn_node_none)
-                          && (this_entry->schedule
-                              == svn_wc_schedule_delete))
+                      SVN_ERR(svn_io_check_path(this_abspath,
+                                                &childkind,
+                                                iterpool));
+                      if (childkind == svn_node_none && this_is_deleted)
                         {
                           if (svn_wc__changelist_match(ctx->wc_ctx,
                                                        this_abspath,
                                                        changelists,
                                                        iterpool))
                             {
-                              add_committable(
-                                committables, full_path,
-                                this_entry->kind, used_url,
+                              SVN_ERR(add_committable(
+                                committables, this_abspath,
+                                this_kind, this_url,
                                 SVN_INVALID_REVNUM,
                                 NULL,
                                 SVN_INVALID_REVNUM,
-                                SVN_CLIENT_COMMIT_ITEM_DELETE);
+                                SVN_CLIENT_COMMIT_ITEM_DELETE));
                               continue; /* don't recurse! */
                             }
                         }
-                      else
-                        SVN_ERR(err);
                     }
                 }
             }
@@ -851,13 +893,11 @@ harvest_committables(apr_hash_t *committ
               depth_below_here = svn_depth_empty;
 
             SVN_ERR(harvest_committables
-                    (committables, lock_tokens, full_path,
-                     used_url ? used_url : this_entry->url,
-                     this_cf_url,
-                     this_entry,
-                     entry,
+                    (committables, lock_tokens, this_abspath,
+                     copy_mode ? this_url : NULL,
                      adds_only,
                      copy_mode,
+                     FALSE, /* COPY_MODE_ROOT */
                      depth_below_here,
                      just_locked,
                      changelists,
@@ -870,7 +910,7 @@ harvest_committables(apr_hash_t *committ
     }
 
   /* Fetch lock tokens for descendants of deleted directories. */
-  if (lock_tokens && entry->kind == svn_node_dir
+  if (lock_tokens && db_kind == svn_node_dir
       && (state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE))
     {
       struct add_lock_token_baton altb;
@@ -922,7 +962,7 @@ validate_dangler(void *baton,
 svn_error_t *
 svn_client__harvest_committables(apr_hash_t **committables,
                                  apr_hash_t **lock_tokens,
-                                 const char *dir_abspath,
+                                 const char *base_abspath,
                                  const apr_array_header_t *targets,
                                  svn_depth_t depth,
                                  svn_boolean_t just_locked,
@@ -930,8 +970,8 @@ svn_client__harvest_committables(apr_has
                                  svn_client_ctx_t *ctx,
                                  apr_pool_t *pool)
 {
-  int i = 0;
-  apr_pool_t *subpool = svn_pool_create(pool);
+  int i;
+  apr_pool_t *iterpool = svn_pool_create(pool);
   apr_hash_t *changelist_hash = NULL;
 
   /* It's possible that one of the named targets has a parent that is
@@ -958,7 +998,7 @@ svn_client__harvest_committables(apr_has
    */
   apr_hash_t *danglers = apr_hash_make(pool);
 
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(dir_abspath));
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(base_abspath));
 
   /* Create the COMMITTABLES hash. */
   *committables = apr_hash_make(pool);
@@ -971,64 +1011,60 @@ svn_client__harvest_committables(apr_has
   if (changelists && changelists->nelts)
     SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash, changelists, pool));
 
-  do
+  for (i = 0; i < targets->nelts; ++i)
     {
-      const svn_wc_entry_t *entry;
-      const char *target_abspath;
+      const char *url, *target_abspath;
+      svn_boolean_t is_added;
+      svn_node_kind_t kind;
       svn_error_t *err;
 
-      svn_pool_clear(subpool);
-
-      /* Add the relative portion of our full path (if there are no
-         relative paths, TARGET will just be PARENT_ADM for a single
-         iteration). */
-      if (targets->nelts)
-        target_abspath = svn_dirent_join(dir_abspath,
-                                         APR_ARRAY_IDX(targets, i,
-                                         const char *),
-                                         subpool);
-      else
-        target_abspath = dir_abspath;
+      svn_pool_clear(iterpool);
 
-      /* No entry?  This TARGET isn't even under version control! */
-      err = svn_wc__get_entry_versioned(&entry, ctx->wc_ctx, target_abspath,
-                                        svn_node_unknown, FALSE, FALSE,
-                                        subpool, subpool);
-      /* If a target of the commit is a tree-conflicted node that
-       * has no entry (e.g. locally deleted), issue a proper tree-
-       * conflicts error instead of a "not under version control". */
-      if (err && (err->apr_err == SVN_ERR_ENTRY_NOT_FOUND))
-        {
+      /* Add the relative portion to the base abspath.  */
+      target_abspath = svn_dirent_join(base_abspath,
+                                       APR_ARRAY_IDX(targets, i, const char *),
+                                       iterpool);
+
+      SVN_ERR(svn_wc_read_kind(&kind, ctx->wc_ctx, target_abspath,
+                               FALSE, /* show_hidden */
+                               iterpool));
+      if (kind == svn_node_none)
+        {
+          /* If a target of the commit is a tree-conflicted node that
+           * has no entry (e.g. locally deleted), issue a proper tree-
+           * conflicts error instead of a "not under version control". */
           const svn_wc_conflict_description2_t *conflict;
           svn_wc__get_tree_conflict(&conflict, ctx->wc_ctx, target_abspath,
-                                    pool, subpool);
+                                    pool, iterpool);
           if (conflict != NULL)
-            {
-              svn_error_clear(err);
-              return svn_error_createf(
+            return svn_error_createf(
                        SVN_ERR_WC_FOUND_CONFLICT, NULL,
                        _("Aborting commit: '%s' remains in conflict"),
                        svn_dirent_local_style(conflict->local_abspath, pool));
-            }
+          else
+            return svn_error_createf(
+                       SVN_ERR_ILLEGAL_TARGET, NULL,
+                       _("'%s' is not under version control"),
+                       svn_dirent_local_style(target_abspath, pool));
         }
-      SVN_ERR(err);
 
-      if (! entry->url)
+      SVN_ERR(svn_wc__node_get_url(&url, ctx->wc_ctx, target_abspath,
+                                   iterpool, iterpool));
+      if (! url)
         return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
                                  _("Entry for '%s' has no URL"),
                                  svn_dirent_local_style(target_abspath, pool));
 
-      /* We have to be especially careful around entries scheduled for
-         addition or replacement. */
-      if ((entry->schedule == svn_wc_schedule_add)
-          || (entry->schedule == svn_wc_schedule_replace))
+      /* Handle an added/replaced node. */
+      SVN_ERR(svn_wc__node_is_added(&is_added, ctx->wc_ctx, target_abspath,
+                                    iterpool));
+      if (is_added)
         {
+          /* This node is added. Is the parent also added? */
           const char *parent_abspath = svn_dirent_dirname(target_abspath,
-                                                          subpool);
-          svn_boolean_t is_added;
-
-          err = svn_wc__node_is_status_added(&is_added, ctx->wc_ctx,
-                                             parent_abspath, subpool);
+                                                          iterpool);
+          err = svn_wc__node_is_added(&is_added, ctx->wc_ctx, parent_abspath,
+                                      iterpool);
           if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
             {
               svn_error_clear(err);
@@ -1041,51 +1077,36 @@ svn_client__harvest_committables(apr_has
 
           if (is_added)
             {
-              /* Copy the parent and target into pool; subpool
+              /* Copy the parent and target into pool; iterpool
                  lasts only for this loop iteration, and we check
                  danglers after the loop is over. */
-              apr_hash_set(danglers, svn_dirent_dirname(target_abspath, pool),
+              apr_hash_set(danglers,
+                           apr_pstrdup(pool, parent_abspath),
                            APR_HASH_KEY_STRING,
                            apr_pstrdup(pool, target_abspath));
             }
         }
 
-      /* If this entry is marked as 'copied' but scheduled normally, then
-         it should be the child of something else marked for addition with
-         history. */
-      if ((entry->copied) && (entry->schedule == svn_wc_schedule_normal))
-        return svn_error_createf
-          (SVN_ERR_ILLEGAL_TARGET, NULL,
-           _("Entry for '%s' is marked as 'copied' but is not itself scheduled"
-             "\nfor addition.  Perhaps you're committing a target that is\n"
-             "inside an unversioned (or not-yet-versioned) directory?"),
-           svn_dirent_local_style(target_abspath, pool));
-
       /* Handle our TARGET. */
       /* Make sure this isn't inside a working copy subtree that is
        * marked as tree-conflicted. */
-      SVN_ERR(bail_on_tree_conflicted_ancestor(ctx->wc_ctx,
-                                               (entry->kind == svn_node_dir
-                                                ? target_abspath
-                                                : svn_dirent_dirname(
-                                                    target_abspath, subpool)),
-                                               subpool));
+      SVN_ERR(bail_on_tree_conflicted_ancestor(ctx->wc_ctx, target_abspath,
+                                               iterpool));
 
       SVN_ERR(harvest_committables(*committables, *lock_tokens, target_abspath,
-                                   entry->url, NULL,
-                                   entry, NULL, FALSE, FALSE, depth,
-                                   just_locked, changelist_hash,
-                                   ctx, subpool));
-
-      i++;
+                                   NULL,
+                                   FALSE, /* ADDS_ONLY */
+                                   FALSE, /* COPY_MODE */
+                                   FALSE, /* COPY_MODE_ROOT */
+                                   depth, just_locked, changelist_hash,
+                                   ctx, iterpool));
     }
-  while (i < targets->nelts);
 
   /* Make sure that every path in danglers is part of the commit. */
   SVN_ERR(svn_iter_apr_hash(NULL,
                             danglers, validate_dangler, *committables, pool));
 
-  svn_pool_destroy(subpool);
+  svn_pool_destroy(iterpool);
 
   return SVN_NO_ERROR;
 }
@@ -1100,24 +1121,22 @@ static svn_error_t *
 harvest_copy_committables(void *baton, void *item, apr_pool_t *pool)
 {
   struct copy_committables_baton *btn = baton;
-
-  const svn_wc_entry_t *entry;
-  svn_client__copy_pair_t *pair =
-    *(svn_client__copy_pair_t **)item;
-  const char *src_abspath;
+  svn_client__copy_pair_t *pair = *(svn_client__copy_pair_t **)item;
 
   /* Read the entry for this SRC. */
-  SVN_ERR(svn_dirent_get_absolute(&src_abspath, pair->src, pool));
-  SVN_ERR(svn_wc__get_entry_versioned(&entry, btn->ctx->wc_ctx, src_abspath,
-                                      svn_node_unknown, FALSE, FALSE,
-                                      pool, pool));
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(pair->src_abspath_or_url));
 
   /* Handle this SRC.  Because add_committable() uses the hash pool to
      allocate the new commit_item, we can safely use the iterpool here. */
-  return harvest_committables(btn->committables, NULL, pair->src,
-                              pair->dst, entry->url, entry,
-                              NULL, FALSE, TRUE, svn_depth_infinity,
-                              FALSE, NULL, btn->ctx, pool);
+  return harvest_committables(btn->committables, NULL,
+                              pair->src_abspath_or_url,
+                              pair->dst_abspath_or_url,
+                              FALSE, /* ADDS_ONLY */
+                              TRUE,  /* COPY_MODE */
+                              TRUE,  /* COPY_MODE_ROOT */
+                              svn_depth_infinity,
+                              FALSE,  /* JUST_LOCKED */
+                              NULL, btn->ctx, pool);
 }
 
 
@@ -1258,7 +1277,7 @@ svn_client__condense_commit_items(const 
 
 struct file_mod_t
 {
-  svn_client_commit_item3_t *item;
+  const svn_client_commit_item3_t *item;
   void *file_baton;
 };
 
@@ -1276,12 +1295,16 @@ struct path_driver_cb_baton
 };
 
 
-/* This implements svn_delta_path_driver_cb_func_t.
- * Act on the item of CALLBACK_BATON->commit_items keyed by PATH.
- * CALLBACK_BATON->commit_items is an input.
- * If the item is a file with text mods, then add a mapping of "item-url =>
- * (commit-item, file-baton)" into CALLBACK_BATON->file_mods.
- * (That is the sole use of CALLBACK_BATON->file_mods.) */
+/* Drive CALLBACK_BATON->editor with the change described by the item in
+ * CALLBACK_BATON->commit_items that is keyed by PATH.  If the change
+ * includes a text mod, however, call the editor's file_open() function
+ * but do not send the text mod to the editor; instead, add a mapping of
+ * "item-url => (commit-item, file-baton)" into CALLBACK_BATON->file_mods.
+ *
+ * Before driving the editor, call the cancellation and notification
+ * callbacks in CALLBACK_BATON->ctx, if present.
+ *
+ * This implements svn_delta_path_driver_cb_func_t. */
 static svn_error_t *
 do_item_commit(void **dir_baton,
                void *parent_baton,
@@ -1290,22 +1313,20 @@ do_item_commit(void **dir_baton,
                apr_pool_t *pool)
 {
   struct path_driver_cb_baton *cb_baton = callback_baton;
-  svn_client_commit_item3_t *item = apr_hash_get(cb_baton->commit_items,
-                                                 path, APR_HASH_KEY_STRING);
+  const svn_client_commit_item3_t *item = apr_hash_get(cb_baton->commit_items,
+                                                       path,
+                                                       APR_HASH_KEY_STRING);
   svn_node_kind_t kind = item->kind;
   void *file_baton = NULL;
-  const char *copyfrom_url = NULL;
   apr_pool_t *file_pool = NULL;
   const svn_delta_editor_t *editor = cb_baton->editor;
   apr_hash_t *file_mods = cb_baton->file_mods;
   svn_client_ctx_t *ctx = cb_baton->ctx;
-  svn_error_t *err = SVN_NO_ERROR;
+  svn_error_t *err;
   const char *local_abspath = NULL;
 
   /* Do some initializations. */
   *dir_baton = NULL;
-  if (item->copyfrom_url)
-    copyfrom_url = item->copyfrom_url;
   if (item->kind != svn_node_none && item->path)
     {
       /* We might not always get a local_abspath.
@@ -1331,7 +1352,7 @@ do_item_commit(void **dir_baton,
   /* Validation. */
   if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_IS_COPY)
     {
-      if (! copyfrom_url)
+      if (! item->copyfrom_url)
         return svn_error_createf
           (SVN_ERR_BAD_URL, NULL,
            _("Commit item '%s' has copy flag but no copyfrom URL"),
@@ -1412,7 +1433,8 @@ do_item_commit(void **dir_baton,
                                  parent_baton, pool);
 
       if (err)
-        return fixup_out_of_date_error(path, item->kind, err);
+        return svn_error_return(fixup_out_of_date_error(path, item->kind,
+                                                        err));
     }
 
   /* If this item is supposed to be added, do so. */
@@ -1422,16 +1444,16 @@ do_item_commit(void **dir_baton,
         {
           SVN_ERR_ASSERT(parent_baton);
           SVN_ERR(editor->add_file
-                  (path, parent_baton, copyfrom_url,
-                   copyfrom_url ? item->copyfrom_rev : SVN_INVALID_REVNUM,
+                  (path, parent_baton, item->copyfrom_url,
+                   item->copyfrom_url ? item->copyfrom_rev : SVN_INVALID_REVNUM,
                    file_pool, &file_baton));
         }
       else /* May be svn_node_none when adding parent dirs for a copy. */
         {
           SVN_ERR_ASSERT(parent_baton);
           SVN_ERR(editor->add_directory
-                  (path, parent_baton, copyfrom_url,
-                   copyfrom_url ? item->copyfrom_rev : SVN_INVALID_REVNUM,
+                  (path, parent_baton, item->copyfrom_url,
+                   item->copyfrom_url ? item->copyfrom_rev : SVN_INVALID_REVNUM,
                    pool, dir_baton));
         }
 
@@ -1471,7 +1493,8 @@ do_item_commit(void **dir_baton,
                                       file_pool, &file_baton);
 
               if (err)
-                return fixup_out_of_date_error(path, kind, err);
+                return svn_error_return(fixup_out_of_date_error(path, kind,
+                                                                err));
             }
         }
       else
@@ -1502,11 +1525,7 @@ do_item_commit(void **dir_baton,
               (kind == svn_node_dir) ? *dir_baton : file_baton, pool);
 
       if (err)
-        return fixup_out_of_date_error(path, kind, err);
-
-      SVN_ERR(svn_wc_transmit_prop_deltas2(
-                ctx->wc_ctx, local_abspath, editor,
-                (kind == svn_node_dir) ? *dir_baton : file_baton, pool));
+        return svn_error_return(fixup_out_of_date_error(path, kind, err));
 
       /* Make any additional client -> repository prop changes. */
       if (item->outgoing_prop_changes)
@@ -1548,7 +1567,8 @@ do_item_commit(void **dir_baton,
                                     file_pool, &file_baton);
 
           if (err)
-            return fixup_out_of_date_error(path, item->kind, err);
+            return svn_error_return(fixup_out_of_date_error(path, item->kind,
+                                                            err));
         }
 
       /* Add this file mod to the FILE_MODS hash. */
@@ -1584,7 +1604,8 @@ svn_client__do_commit(const char *base_u
                       void *edit_baton,
                       const char *notify_path_prefix,
                       apr_hash_t **new_text_base_abspaths,
-                      apr_hash_t **checksums,
+                      apr_hash_t **md5_checksums,
+                      apr_hash_t **sha1_checksums,
                       svn_client_ctx_t *ctx,
                       apr_pool_t *pool)
 {
@@ -1610,9 +1631,11 @@ svn_client__do_commit(const char *base_u
   if (new_text_base_abspaths)
     *new_text_base_abspaths = apr_hash_make(pool);
 
-  /* Ditto for the md5 checksums. */
-  if (checksums)
-    *checksums = apr_hash_make(pool);
+  /* Ditto for the checksums. */
+  if (md5_checksums)
+    *md5_checksums = apr_hash_make(pool);
+  if (sha1_checksums)
+    *sha1_checksums = apr_hash_make(pool);
 
   /* Build a hash from our COMMIT_ITEMS array, keyed on the
      URI-decoded relative paths (which come from the item URLs).  And
@@ -1642,18 +1665,16 @@ svn_client__do_commit(const char *base_u
   for (hi = apr_hash_first(pool, file_mods); hi; hi = apr_hash_next(hi))
     {
       struct file_mod_t *mod = svn__apr_hash_index_val(hi);
-      svn_client_commit_item3_t *item;
-      void *file_baton;
+      const svn_client_commit_item3_t *item = mod->item;
       const char *tempfile;
-      unsigned char digest[APR_MD5_DIGESTSIZE];
+      const svn_checksum_t *new_text_base_md5_checksum;
+      const svn_checksum_t *new_text_base_sha1_checksum;
       svn_boolean_t fulltext = FALSE;
       const char *item_abspath;
 
       svn_pool_clear(iterpool);
 
       /* Transmit the entry. */
-      item = mod->item;
-      file_baton = mod->file_baton;
       SVN_ERR(svn_dirent_get_absolute(&item_abspath, item->path, iterpool));
 
       if (ctx->cancel_func)
@@ -1675,16 +1696,20 @@ svn_client__do_commit(const char *base_u
 
       SVN_ERR(svn_wc_transmit_text_deltas3(new_text_base_abspaths ? &tempfile
                                                                   : NULL,
-                                           digest, ctx->wc_ctx, item_abspath,
-                                           fulltext, editor, file_baton,
-                                           iterpool, iterpool));
+                                           &new_text_base_md5_checksum,
+                                           &new_text_base_sha1_checksum,
+                                           ctx->wc_ctx, item_abspath,
+                                           fulltext, editor, mod->file_baton,
+                                           pool, iterpool));
       if (new_text_base_abspaths && tempfile)
         apr_hash_set(*new_text_base_abspaths, item->path, APR_HASH_KEY_STRING,
-                     apr_pstrdup(pool, tempfile));
-      if (checksums)
-        apr_hash_set(*checksums, item->path, APR_HASH_KEY_STRING,
-                     svn_checksum__from_digest(digest, svn_checksum_md5,
-                                               apr_hash_pool_get(*checksums)));
+                     tempfile);
+      if (md5_checksums)
+        apr_hash_set(*md5_checksums, item->path, APR_HASH_KEY_STRING,
+                     new_text_base_md5_checksum);
+      if (sha1_checksums)
+        apr_hash_set(*sha1_checksums, item->path, APR_HASH_KEY_STRING,
+                     new_text_base_sha1_checksum);
     }
 
   svn_pool_destroy(iterpool);
@@ -2007,9 +2032,9 @@ svn_client__get_log_msg(const char **log
          function.  Convert the commit_items list to the appropriate
          type, and forward call to it. */
       svn_error_t *err;
-      apr_pool_t *subpool = svn_pool_create(pool);
+      apr_pool_t *scratch_pool = svn_pool_create(pool);
       apr_array_header_t *old_commit_items =
-        apr_array_make(subpool, commit_items->nelts, sizeof(void*));
+        apr_array_make(scratch_pool, commit_items->nelts, sizeof(void*));
 
       int i;
       for (i = 0; i < commit_items->nelts; i++)
@@ -2020,7 +2045,7 @@ svn_client__get_log_msg(const char **log
           if (ctx->log_msg_func2)
             {
               svn_client_commit_item2_t *old_item =
-                apr_pcalloc(subpool, sizeof(*old_item));
+                apr_pcalloc(scratch_pool, sizeof(*old_item));
 
               old_item->path = item->path;
               old_item->kind = item->kind;
@@ -2037,7 +2062,7 @@ svn_client__get_log_msg(const char **log
           else /* ctx->log_msg_func */
             {
               svn_client_commit_item_t *old_item =
-                apr_pcalloc(subpool, sizeof(*old_item));
+                apr_pcalloc(scratch_pool, sizeof(*old_item));
 
               old_item->path = item->path;
               old_item->kind = item->kind;
@@ -2061,7 +2086,7 @@ svn_client__get_log_msg(const char **log
       else
         err = (*ctx->log_msg_func)(log_msg, tmp_file, old_commit_items,
                                    ctx->log_msg_baton, pool);
-      svn_pool_destroy(subpool);
+      svn_pool_destroy(scratch_pool);
       return err;
     }
   else