/*
 * commit_util.c:  Driver for the WC commit process.
 *
 * ====================================================================
 *    Licensed to the Apache Software Foundation (ASF) under one
 *    or more contributor license agreements.  See the NOTICE file
 *    distributed with this work for additional information
 *    regarding copyright ownership.  The ASF licenses this file
 *    to you under the Apache License, Version 2.0 (the
 *    "License"); you may not use this file except in compliance
 *    with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing,
 *    software distributed under the License is distributed on an
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *    KIND, either express or implied.  See the License for the
 *    specific language governing permissions and limitations
 *    under the License.
 * ====================================================================
 */

/* ==================================================================== */


#include <string.h>

#include <apr_pools.h>
#include <apr_hash.h>
#include <apr_md5.h>

#include "client.h"
#include "svn_dirent_uri.h"
#include "svn_path.h"
#include "svn_types.h"
#include "svn_pools.h"
#include "svn_props.h"
#include "svn_iter.h"
#include "svn_hash.h"

#include <assert.h>

#include "svn_private_config.h"
#include "private/svn_wc_private.h"
#include "private/svn_client_private.h"
#include "private/svn_sorts_private.h"

/*** Uncomment this to turn on commit driver debugging. ***/
/*
#define SVN_CLIENT_COMMIT_DEBUG
*/

/* Wrap an RA error in a nicer error if one is available. */
static svn_error_t *
fixup_commit_error(const char *local_abspath,
                   const char *base_url,
                   const char *path,
                   svn_node_kind_t kind,
                   svn_error_t *err,
                   svn_client_ctx_t *ctx,
                   apr_pool_t *scratch_pool)
{
  if (err->apr_err == SVN_ERR_FS_NOT_FOUND
      || err->apr_err == SVN_ERR_FS_CONFLICT
      || err->apr_err == SVN_ERR_FS_ALREADY_EXISTS
      || err->apr_err == SVN_ERR_FS_TXN_OUT_OF_DATE
      || err->apr_err == SVN_ERR_RA_DAV_PATH_NOT_FOUND
      || err->apr_err == SVN_ERR_RA_DAV_ALREADY_EXISTS
      || err->apr_err == SVN_ERR_RA_DAV_PRECONDITION_FAILED
      || svn_error_find_cause(err, SVN_ERR_RA_OUT_OF_DATE))
    {
      if (ctx->notify_func2)
        {
          svn_wc_notify_t *notify;

          if (local_abspath)
            notify = svn_wc_create_notify(local_abspath,
                                          svn_wc_notify_failed_out_of_date,
                                          scratch_pool);
          else
            notify = svn_wc_create_notify_url(
                                svn_path_url_add_component2(base_url, path,
                                                            scratch_pool),
                                svn_wc_notify_failed_out_of_date,
                                scratch_pool);

          notify->kind = kind;
          notify->err = err;

          ctx->notify_func2(ctx->notify_baton2, notify, scratch_pool);
        }

      return svn_error_createf(SVN_ERR_WC_NOT_UP_TO_DATE, err,
                               (kind == svn_node_dir
                                 ? _("Directory '%s' is out of date")
                                 : _("File '%s' is out of date")),
                               local_abspath
                                  ? svn_dirent_local_style(local_abspath,
                                                           scratch_pool)
                                  : svn_path_url_add_component2(base_url,
                                                                path,
                                                                scratch_pool));
    }
  else if (svn_error_find_cause(err, SVN_ERR_FS_NO_LOCK_TOKEN)
           || err->apr_err == SVN_ERR_FS_LOCK_OWNER_MISMATCH
           || err->apr_err == SVN_ERR_FS_BAD_LOCK_TOKEN
           || err->apr_err == SVN_ERR_RA_NOT_LOCKED)
    {
      if (ctx->notify_func2)
        {
          svn_wc_notify_t *notify;

          if (local_abspath)
            notify = svn_wc_create_notify(local_abspath,
                                          svn_wc_notify_failed_locked,
                                          scratch_pool);
          else
            notify = svn_wc_create_notify_url(
                                svn_path_url_add_component2(base_url, path,
                                                            scratch_pool),
                                svn_wc_notify_failed_locked,
                                scratch_pool);

          notify->kind = kind;
          notify->err = err;

          ctx->notify_func2(ctx->notify_baton2, notify, scratch_pool);
        }

      return svn_error_createf(SVN_ERR_CLIENT_NO_LOCK_TOKEN, err,
                   (kind == svn_node_dir
                     ? _("Directory '%s' is locked in another working copy")
                     : _("File '%s' is locked in another working copy")),
                   local_abspath
                      ? svn_dirent_local_style(local_abspath,
                                               scratch_pool)
                      : svn_path_url_add_component2(base_url,
                                                    path,
                                                    scratch_pool));
    }
  else if (svn_error_find_cause(err, SVN_ERR_RA_DAV_FORBIDDEN)
           || err->apr_err == SVN_ERR_AUTHZ_UNWRITABLE)
    {
      if (ctx->notify_func2)
        {
          svn_wc_notify_t *notify;

          if (local_abspath)
            notify = svn_wc_create_notify(
                                    local_abspath,
                                    svn_wc_notify_failed_forbidden_by_server,
                                    scratch_pool);
          else
            notify = svn_wc_create_notify_url(
                                svn_path_url_add_component2(base_url, path,
                                                            scratch_pool),
                                svn_wc_notify_failed_forbidden_by_server,
                                scratch_pool);

          notify->kind = kind;
          notify->err = err;

          ctx->notify_func2(ctx->notify_baton2, notify, scratch_pool);
        }

      return svn_error_createf(SVN_ERR_CLIENT_FORBIDDEN_BY_SERVER, err,
                   (kind == svn_node_dir
                     ? _("Changing directory '%s' is forbidden by the server")
                     : _("Changing file '%s' is forbidden by the server")),
                   local_abspath
                      ? svn_dirent_local_style(local_abspath,
                                               scratch_pool)
                      : svn_path_url_add_component2(base_url,
                                                    path,
                                                    scratch_pool));
    }
  else
    return err;
}


/*** Harvesting Commit Candidates ***/


/* 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 RESULT_POOL.

   If the state flag specifies that a lock must be used, store the token in LOCK
   in lock_tokens.
 */
static svn_error_t *
add_committable(svn_client__committables_t *committables,
                const char *local_abspath,
                svn_node_kind_t kind,
                const char *repos_root_url,
                const char *repos_relpath,
                svn_revnum_t revision,
                const char *copyfrom_relpath,
                svn_revnum_t copyfrom_rev,
                const char *moved_from_abspath,
                apr_byte_t state_flags,
                apr_hash_t *lock_tokens,
                const svn_lock_t *lock,
                apr_pool_t *result_pool,
                apr_pool_t *scratch_pool)
{
  apr_array_header_t *array;
  svn_client_commit_item3_t *new_item;

  /* Sanity checks. */
  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
  SVN_ERR_ASSERT(repos_root_url && repos_relpath);

  /* ### todo: Get the canonical repository for this item, which will
     be the real key for the COMMITTABLES hash, instead of the above
     bogosity. */
  array = svn_hash_gets(committables->by_repository, repos_root_url);

  /* E-gads!  There is no array for this repository yet!  Oh, no
     problem, we'll just create (and add to the hash) one. */
  if (array == NULL)
    {
      array = apr_array_make(result_pool, 1, sizeof(new_item));
      svn_hash_sets(committables->by_repository,
                    apr_pstrdup(result_pool, repos_root_url), array);
    }

  /* Now update pointer values, ensuring that their allocations live
     in POOL. */
  new_item = svn_client_commit_item3_create(result_pool);
  new_item->path           = apr_pstrdup(result_pool, local_abspath);
  new_item->kind           = kind;
  new_item->url            = svn_path_url_add_component2(repos_root_url,
                                                         repos_relpath,
                                                         result_pool);
  new_item->revision       = revision;
  new_item->copyfrom_url   = copyfrom_relpath
                                ? svn_path_url_add_component2(repos_root_url,
                                                              copyfrom_relpath,
                                                              result_pool)
                                : NULL;
  new_item->copyfrom_rev   = copyfrom_rev;
  new_item->state_flags    = state_flags;
  new_item->incoming_prop_changes = apr_array_make(result_pool, 1,
                                                   sizeof(svn_prop_t *));

  if (moved_from_abspath)
    new_item->moved_from_abspath = apr_pstrdup(result_pool,
                                               moved_from_abspath);

  /* Now, add the commit item to the array. */
  APR_ARRAY_PUSH(array, svn_client_commit_item3_t *) = new_item;

  /* ... and to the hash. */
  svn_hash_sets(committables->by_path, new_item->path, new_item);

  if (lock
      && lock_tokens
      && (state_flags & SVN_CLIENT_COMMIT_ITEM_LOCK_TOKEN))
    {
      svn_hash_sets(lock_tokens, new_item->url,
                    apr_pstrdup(result_pool, lock->token));
    }

  return SVN_NO_ERROR;
}

/* If there is a commit item for PATH in COMMITTABLES, return it, else
   return NULL.  Use POOL for temporary allocation only. */
static svn_client_commit_item3_t *
look_up_committable(svn_client__committables_t *committables,
                    const char *path,
                    apr_pool_t *pool)
{
  return (svn_client_commit_item3_t *)
      svn_hash_gets(committables->by_path, path);
}

/* Helper function for svn_client__harvest_committables().
 * Determine whether we are within a tree-conflicted subtree of the
 * working copy and return an SVN_ERR_WC_FOUND_CONFLICT error if so. */
static svn_error_t *
bail_on_tree_conflicted_ancestor(svn_wc_context_t *wc_ctx,
                                 const char *local_abspath,
                                 svn_wc_notify_func2_t notify_func,
                                 void *notify_baton,
                                 apr_pool_t *scratch_pool)
{
  const char *wcroot_abspath;

  SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath, wc_ctx, local_abspath,
                             scratch_pool, scratch_pool));

  local_abspath = svn_dirent_dirname(local_abspath, scratch_pool);

  while(svn_dirent_is_ancestor(wcroot_abspath, local_abspath))
    {
      svn_boolean_t tree_conflicted;

      /* Check if the parent has tree conflicts */
      SVN_ERR(svn_wc_conflicted_p3(NULL, NULL, &tree_conflicted,
                                   wc_ctx, local_abspath, scratch_pool));
      if (tree_conflicted)
        {
          if (notify_func != NULL)
            {
              notify_func(notify_baton,
                          svn_wc_create_notify(local_abspath,
                                               svn_wc_notify_failed_conflict,
                                               scratch_pool),
                          scratch_pool);
            }

          return svn_error_createf(
                   SVN_ERR_WC_FOUND_CONFLICT, NULL,
                   _("Aborting commit: '%s' remains in tree-conflict"),
                   svn_dirent_local_style(local_abspath, scratch_pool));
        }

      /* Step outwards */
      if (svn_dirent_is_root(local_abspath, strlen(local_abspath)))
        break;
      else
        local_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
    }

  return SVN_NO_ERROR;
}


/* Recursively search for commit candidates in (and under) LOCAL_ABSPATH using
   WC_CTX 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
   svn_client__harvest_committables() for its behavior.

   Lock tokens of candidates will be added to LOCK_TOKENS, if
   non-NULL.  JUST_LOCKED indicates whether to treat non-modified items with
   lock tokens as commit candidates.

   If COMMIT_RELPATH is not NULL, treat not-added nodes as if it is destined to
   be added as COMMIT_RELPATH, and add 'deleted' entries to COMMITTABLES as
   items to delete in the copy destination.  COPY_MODE_ROOT should be set TRUE
   for the first call for which COPY_MODE is TRUE, i.e. not 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
   when harvesting committables; that is, don't add a path to
   COMMITTABLES unless it's a member of one of those changelists.

   IS_EXPLICIT_TARGET should always be passed as TRUE, except when
   harvest_committables() calls itself in recursion. This provides a way to
   tell whether LOCAL_ABSPATH was an original target or whether it was reached
   by recursing deeper into a dir target. (This is used to skip all file
   externals that aren't explicit commit targets.)

   DANGLERS is a hash table mapping const char* absolute paths of a parent
   to a const char * absolute path of a child. See the comment about
   danglers at the top of svn_client__harvest_committables().

   If CANCEL_FUNC is non-null, call it with CANCEL_BATON to see
   if the user has cancelled the operation.

   Any items added to COMMITTABLES are allocated from the COMITTABLES
   hash pool, not POOL.  SCRATCH_POOL is used for temporary allocations. */

struct harvest_baton
{
  /* Static data */
  const char *root_abspath;
  svn_client__committables_t *committables;
  apr_hash_t *lock_tokens;
  const char *commit_relpath; /* Valid for the harvest root */
  svn_depth_t depth;
  svn_boolean_t just_locked;
  apr_hash_t *changelists;
  apr_hash_t *danglers;
  svn_client__check_url_kind_t check_url_func;
  void *check_url_baton;
  svn_wc_notify_func2_t notify_func;
  void *notify_baton;
  svn_wc_context_t *wc_ctx;
  apr_pool_t *result_pool;

  /* Harvester state */
  const char *skip_below_abspath; /* If non-NULL, skip everything below */
};

static svn_error_t *
harvest_status_callback(void *status_baton,
                        const char *local_abspath,
                        const svn_wc_status3_t *status,
                        apr_pool_t *scratch_pool);

static svn_error_t *
harvest_committables(const char *local_abspath,
                     svn_client__committables_t *committables,
                     apr_hash_t *lock_tokens,
                     const char *copy_mode_relpath,
                     svn_depth_t depth,
                     svn_boolean_t just_locked,
                     apr_hash_t *changelists,
                     apr_hash_t *danglers,
                     svn_client__check_url_kind_t check_url_func,
                     void *check_url_baton,
                     svn_cancel_func_t cancel_func,
                     void *cancel_baton,
                     svn_wc_notify_func2_t notify_func,
                     void *notify_baton,
                     svn_wc_context_t *wc_ctx,
                     apr_pool_t *result_pool,
                     apr_pool_t *scratch_pool)
{
  struct harvest_baton baton;

  SVN_ERR_ASSERT((just_locked && lock_tokens) || !just_locked);

  baton.root_abspath = local_abspath;
  baton.committables = committables;
  baton.lock_tokens = lock_tokens;
  baton.commit_relpath = copy_mode_relpath;
  baton.depth = depth;
  baton.just_locked = just_locked;
  baton.changelists = changelists;
  baton.danglers = danglers;
  baton.check_url_func = check_url_func;
  baton.check_url_baton = check_url_baton;
  baton.notify_func = notify_func;
  baton.notify_baton = notify_baton;
  baton.wc_ctx = wc_ctx;
  baton.result_pool = result_pool;

  baton.skip_below_abspath = NULL;

  SVN_ERR(svn_wc_walk_status(wc_ctx,
                             local_abspath,
                             depth,
                             (copy_mode_relpath != NULL) /* get_all */,
                             FALSE /* no_ignore */,
                             FALSE /* ignore_text_mods */,
                             NULL /* ignore_patterns */,
                             harvest_status_callback,
                             &baton,
                             cancel_func, cancel_baton,
                             scratch_pool));

  return SVN_NO_ERROR;
}

static svn_error_t *
harvest_not_present_for_copy(svn_wc_context_t *wc_ctx,
                             const char *local_abspath,
                             svn_client__committables_t *committables,
                             const char *repos_root_url,
                             const char *commit_relpath,
                             svn_client__check_url_kind_t check_url_func,
                             void *check_url_baton,
                             apr_pool_t *result_pool,
                             apr_pool_t *scratch_pool)
{
  const apr_array_header_t *children;
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
  int i;

  SVN_ERR_ASSERT(commit_relpath != NULL);

  /* A function to retrieve not present children would be nice to have */
  SVN_ERR(svn_wc__node_get_not_present_children(&children, wc_ctx,
                                                local_abspath,
                                                scratch_pool, iterpool));

  for (i = 0; i < children->nelts; i++)
    {
      const char *this_abspath = APR_ARRAY_IDX(children, i, const char *);
      const char *name = svn_dirent_basename(this_abspath, NULL);
      const char *this_commit_relpath;
      svn_boolean_t not_present;
      svn_node_kind_t kind;

      svn_pool_clear(iterpool);

      SVN_ERR(svn_wc__node_is_not_present(&not_present, NULL, NULL, wc_ctx,
                                          this_abspath, FALSE, scratch_pool));

      if (!not_present)
        continue; /* Node is replaced */

      this_commit_relpath = svn_relpath_join(commit_relpath, name,
                                             iterpool);

      /* We should check if we should really add a delete operation */
      if (check_url_func)
        {
          svn_revnum_t parent_rev;
          const char *parent_repos_relpath;
          const char *parent_repos_root_url;
          const char *node_url;

          /* Determine from what parent we would be the deleted child */
          SVN_ERR(svn_wc__node_get_origin(
                              NULL, &parent_rev, &parent_repos_relpath,
                              &parent_repos_root_url, NULL, NULL, NULL,
                              wc_ctx,
                              svn_dirent_dirname(this_abspath,
                                                  scratch_pool),
                              FALSE, scratch_pool, scratch_pool));

          node_url = svn_path_url_add_component2(
                        svn_path_url_add_component2(parent_repos_root_url,
                                                    parent_repos_relpath,
                                                    scratch_pool),
                        svn_dirent_basename(this_abspath, NULL),
                        iterpool);

          SVN_ERR(check_url_func(check_url_baton, &kind,
                                 node_url, parent_rev, iterpool));

          if (kind == svn_node_none)
            continue; /* This node can't be deleted */
        }
      else
        SVN_ERR(svn_wc_read_kind2(&kind, wc_ctx, this_abspath,
                                  TRUE, TRUE, scratch_pool));

      SVN_ERR(add_committable(committables, this_abspath, kind,
                              repos_root_url,
                              this_commit_relpath,
                              SVN_INVALID_REVNUM,
                              NULL /* copyfrom_relpath */,
                              SVN_INVALID_REVNUM /* copyfrom_rev */,
                              NULL /* moved_from_abspath */,
                              SVN_CLIENT_COMMIT_ITEM_DELETE,
                              NULL, NULL,
                              result_pool, scratch_pool));
    }

  svn_pool_destroy(iterpool);
  return SVN_NO_ERROR;
}

/* Implements svn_wc_status_func4_t */
static svn_error_t *
harvest_status_callback(void *status_baton,
                        const char *local_abspath,
                        const svn_wc_status3_t *status,
                        apr_pool_t *scratch_pool)
{
  apr_byte_t state_flags = 0;
  svn_revnum_t node_rev;
  const char *cf_relpath = NULL;
  svn_revnum_t cf_rev = SVN_INVALID_REVNUM;
  svn_boolean_t matches_changelists;
  svn_boolean_t is_added;
  svn_boolean_t is_deleted;
  svn_boolean_t is_replaced;
  svn_boolean_t is_op_root;
  svn_revnum_t original_rev;
  const char *original_relpath;
  svn_boolean_t copy_mode;

  struct harvest_baton *baton = status_baton;
  svn_boolean_t is_harvest_root =
                (strcmp(baton->root_abspath, local_abspath) == 0);
  svn_client__committables_t *committables = baton->committables;
  const char *repos_root_url = status->repos_root_url;
  const char *commit_relpath = NULL;
  svn_boolean_t copy_mode_root = (baton->commit_relpath && is_harvest_root);
  svn_boolean_t just_locked = baton->just_locked;
  apr_hash_t *changelists = baton->changelists;
  svn_wc_notify_func2_t notify_func = baton->notify_func;
  void *notify_baton = baton->notify_baton;
  svn_wc_context_t *wc_ctx = baton->wc_ctx;
  apr_pool_t *result_pool = baton->result_pool;
  const char *moved_from_abspath = NULL;

  if (baton->commit_relpath)
    commit_relpath = svn_relpath_join(
                        baton->commit_relpath,
                        svn_dirent_skip_ancestor(baton->root_abspath,
                                                 local_abspath),
                        scratch_pool);

  copy_mode = (commit_relpath != NULL);

  if (baton->skip_below_abspath
      && svn_dirent_is_ancestor(baton->skip_below_abspath, local_abspath))
    {
      return SVN_NO_ERROR;
    }
  else
    baton->skip_below_abspath = NULL; /* We have left the skip tree */

  /* Return early for nodes that don't have a committable status */
  switch (status->node_status)
    {
      case svn_wc_status_unversioned:
      case svn_wc_status_ignored:
      case svn_wc_status_external:
      case svn_wc_status_none:
        /* Unversioned nodes aren't committable, but are reported by the status
           walker.
           But if the unversioned node is the root of the walk, we have a user
           error */
        if (is_harvest_root)
          return svn_error_createf(
                       SVN_ERR_ILLEGAL_TARGET, NULL,
                       _("'%s' is not under version control"),
                       svn_dirent_local_style(local_abspath, scratch_pool));
        return SVN_NO_ERROR;
      case svn_wc_status_normal:
        /* Status normal nodes aren't modified, so we don't have to commit them
           when we perform a normal commit. But if a node is conflicted we want
           to stop the commit and if we are collecting lock tokens we want to
           look further anyway.

           When in copy mode we need to compare the revision of the node against
           the parent node to copy mixed-revision base nodes properly */
        if (!copy_mode && !status->conflicted
            && !(just_locked && status->lock))
          return SVN_NO_ERROR;
        break;
      default:
        /* Fall through */
        break;
    }

  /* Early out if the item is already marked as committable. */
  if (look_up_committable(committables, local_abspath, scratch_pool))
    return SVN_NO_ERROR;

  SVN_ERR_ASSERT((copy_mode && commit_relpath)
                 || (! copy_mode && ! commit_relpath));
  SVN_ERR_ASSERT((copy_mode_root && copy_mode) || ! copy_mode_root);

  /* Save the result for reuse. */
  matches_changelists = ((changelists == NULL)
                         || (status->changelist != NULL
                             && svn_hash_gets(changelists, status->changelist)
                                != NULL));

  /* Early exit. */
  if (status->kind != svn_node_dir && ! matches_changelists)
    {
      return SVN_NO_ERROR;
    }

  /* If NODE is in our changelist, then examine it for conflicts. We
     need to bail out if any conflicts exist.
     The status walker checked for conflict marker removal. */
  if (status->conflicted && matches_changelists)
    {
      if (notify_func != NULL)
        {
          notify_func(notify_baton,
                      svn_wc_create_notify(local_abspath,
                                           svn_wc_notify_failed_conflict,
                                           scratch_pool),
                      scratch_pool);
        }

      return svn_error_createf(
            SVN_ERR_WC_FOUND_CONFLICT, NULL,
            _("Aborting commit: '%s' remains in conflict"),
            svn_dirent_local_style(local_abspath, scratch_pool));
    }
  else if (status->node_status == svn_wc_status_obstructed)
    {
      /* A node's type has changed before attempting to commit.
         This also catches symlink vs non symlink changes */

      if (notify_func != NULL)
        {
          notify_func(notify_baton,
                      svn_wc_create_notify(local_abspath,
                                           svn_wc_notify_failed_obstruction,
                                           scratch_pool),
                      scratch_pool);
        }

      return svn_error_createf(
                    SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
                    _("Node '%s' has unexpectedly changed kind"),
                    svn_dirent_local_style(local_abspath, scratch_pool));
    }

  if (status->conflicted && status->kind == svn_node_unknown)
    return SVN_NO_ERROR; /* Ignore delete-delete conflict */

  /* 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. */
  SVN_ERR(svn_wc__node_get_commit_status(&is_added, &is_deleted,
                                         &is_replaced,
                                         &is_op_root,
                                         &node_rev,
                                         &original_rev, &original_relpath,
                                         wc_ctx, local_abspath,
                                         scratch_pool, scratch_pool));

  /* Hande file externals only when passed as explicit target. Note that
   * svn_client_commit6() passes all committable externals in as explicit
   * targets iff they count. */
  if (status->file_external && !is_harvest_root)
    {
      return SVN_NO_ERROR;
    }

  if (status->node_status == svn_wc_status_missing && matches_changelists)
    {
      /* Added files and directories must exist. See issue #3198. */
      if (is_added && is_op_root)
        {
          if (notify_func != NULL)
            {
              notify_func(notify_baton,
                          svn_wc_create_notify(local_abspath,
                                               svn_wc_notify_failed_missing,
                                               scratch_pool),
                          scratch_pool);
            }
          return svn_error_createf(
             SVN_ERR_WC_PATH_NOT_FOUND, NULL,
             _("'%s' is scheduled for addition, but is missing"),
             svn_dirent_local_style(local_abspath, scratch_pool));
        }

      return SVN_NO_ERROR;
    }

  if (is_deleted && !is_op_root /* && !is_added */)
    return SVN_NO_ERROR; /* Not an operational delete and not an add. */

  /* Check for the deletion case.
     * We delete explicitly deleted nodes (duh!)
     * We delete not-present children of copies
     * We delete nodes that directly replace a node in its ancestor
   */

  if (is_deleted || is_replaced)
    state_flags |= SVN_CLIENT_COMMIT_ITEM_DELETE;

  /* Check for adds and copies */
  if (is_added && is_op_root)
    {
      /* Root of local add or copy */
      state_flags |= SVN_CLIENT_COMMIT_ITEM_ADD;

      if (original_relpath)
        {
          /* Root of copy */
          state_flags |= SVN_CLIENT_COMMIT_ITEM_IS_COPY;
          cf_relpath = original_relpath;
          cf_rev = original_rev;

          if (status->moved_from_abspath && !copy_mode)
            {
              state_flags |= SVN_CLIENT_COMMIT_ITEM_MOVED_HERE;
              moved_from_abspath = status->moved_from_abspath;
            }
        }
    }

  /* Further copies may occur in copy mode. */
  else if (copy_mode
           && !(state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE))
    {
      svn_revnum_t dir_rev = SVN_INVALID_REVNUM;
      const char *dir_repos_relpath = NULL;

      if (!copy_mode_root && !is_added)
        SVN_ERR(svn_wc__node_get_base(NULL, &dir_rev, &dir_repos_relpath, NULL,
                                      NULL, NULL,
                                      wc_ctx, svn_dirent_dirname(local_abspath,
                                                                 scratch_pool),
                                      FALSE /* ignore_enoent */,
                                      scratch_pool, scratch_pool));

      if (copy_mode_root || status->switched || node_rev != dir_rev)
        {
          state_flags |= (SVN_CLIENT_COMMIT_ITEM_ADD
                          | SVN_CLIENT_COMMIT_ITEM_IS_COPY);

          if (status->copied)
            {
              /* Copy from original location */
              cf_rev = original_rev;
              cf_relpath = original_relpath;
            }
          else
            {
              /* Copy BASE location, to represent a mixed-rev or switch copy */
              cf_rev = status->revision;
              cf_relpath = status->repos_relpath;
            }

          if (!copy_mode_root && !is_added && baton->check_url_func
              && dir_repos_relpath)
            {
              svn_node_kind_t me_kind;
              /* Maybe we need to issue an delete (mixed rev/switched) */

              SVN_ERR(baton->check_url_func(
                            baton->check_url_baton, &me_kind,
                            svn_path_url_add_component2(repos_root_url,
                                        svn_relpath_join(dir_repos_relpath,
                                            svn_dirent_basename(local_abspath,
                                                                NULL),
                                            scratch_pool),
                                        scratch_pool),
                                        dir_rev, scratch_pool));
              if (me_kind != svn_node_none)
                state_flags |= SVN_CLIENT_COMMIT_ITEM_DELETE;
            }
        }
    }

  if (!(state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)
      || (state_flags & SVN_CLIENT_COMMIT_ITEM_ADD))
    {
      svn_boolean_t text_mod = FALSE;
      svn_boolean_t prop_mod = FALSE;

      if (status->kind == svn_node_file)
        {
          /* Check for text modifications on files */
          if ((state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)
              && ! (state_flags & SVN_CLIENT_COMMIT_ITEM_IS_COPY))
            {
              text_mod = TRUE; /* Local added files are always modified */
            }
          else
            text_mod = (status->text_status != svn_wc_status_normal);
        }

      prop_mod = (status->prop_status != svn_wc_status_normal
                  && status->prop_status != svn_wc_status_none);

      /* Set text/prop modification flags accordingly. */
      if (text_mod)
        state_flags |= SVN_CLIENT_COMMIT_ITEM_TEXT_MODS;
      if (prop_mod)
        state_flags |= SVN_CLIENT_COMMIT_ITEM_PROP_MODS;
    }

  /* 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 (status->lock && baton->lock_tokens && (state_flags || just_locked))
    {
      state_flags |= SVN_CLIENT_COMMIT_ITEM_LOCK_TOKEN;
    }

  /* Now, if this is something to commit, add it to our list. */
  if (matches_changelists
      && state_flags)
    {
      /* Finally, add the committable item. */
      SVN_ERR(add_committable(committables, local_abspath,
                              status->kind,
                              repos_root_url,
                              copy_mode
                                      ? commit_relpath
                                      : status->repos_relpath,
                              copy_mode
                                      ? SVN_INVALID_REVNUM
                                      : node_rev,
                              cf_relpath,
                              cf_rev,
                              moved_from_abspath,
                              state_flags,
                              baton->lock_tokens, status->lock,
                              result_pool, scratch_pool));
    }

    /* Fetch lock tokens for descendants of deleted BASE nodes. */
  if (matches_changelists
      && (state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)
      && !copy_mode
      && SVN_IS_VALID_REVNUM(node_rev) /* && BASE-kind = dir */
      && baton->lock_tokens)
    {
      apr_hash_t *local_relpath_tokens;
      apr_hash_index_t *hi;

      SVN_ERR(svn_wc__node_get_lock_tokens_recursive(
                  &local_relpath_tokens, wc_ctx, local_abspath,
                  result_pool, scratch_pool));

      /* Add tokens to existing hash. */
      for (hi = apr_hash_first(scratch_pool, local_relpath_tokens);
           hi;
           hi = apr_hash_next(hi))
        {
          const void *key;
          apr_ssize_t klen;
          void * val;

          apr_hash_this(hi, &key, &klen, &val);

          apr_hash_set(baton->lock_tokens, key, klen, val);
        }
    }

  /* Make sure we check for dangling children on additions

     We perform this operation on the harvest root, and on roots caused by
     changelist filtering.
  */
  if (matches_changelists
      && (is_harvest_root || baton->changelists)
      && state_flags
      && (is_added || (is_deleted && is_op_root && status->copied))
      && baton->danglers)
    {
      /* If a node is added, its parent must exist in the repository at the
         time of committing */
      apr_hash_t *danglers = baton->danglers;
      svn_boolean_t parent_added;
      const char *parent_abspath = svn_dirent_dirname(local_abspath,
                                                      scratch_pool);

      /* First check if parent is already in the list of commits
         (Common case for GUI clients that provide a list of commit targets) */
      if (look_up_committable(committables, parent_abspath, scratch_pool))
        parent_added = FALSE; /* Skip all expensive checks */
      else
        SVN_ERR(svn_wc__node_is_added(&parent_added, wc_ctx, parent_abspath,
                                      scratch_pool));

      if (parent_added)
        {
          const char *copy_root_abspath;
          svn_boolean_t parent_is_copy;

          /* The parent is added, so either it is a copy, or a locally added
           * directory. In either case, we require the op-root of the parent
           * to be part of the commit. See issue #4059. */
          SVN_ERR(svn_wc__node_get_origin(&parent_is_copy, NULL, NULL, NULL,
                                          NULL, NULL, &copy_root_abspath,
                                          wc_ctx, parent_abspath,
                                          FALSE, scratch_pool, scratch_pool));

          if (parent_is_copy)
            parent_abspath = copy_root_abspath;

          if (!svn_hash_gets(danglers, parent_abspath))
            {
              svn_hash_sets(danglers, apr_pstrdup(result_pool, parent_abspath),
                            apr_pstrdup(result_pool, local_abspath));
            }
        }
    }

  if (is_deleted && !is_added)
    {
      /* Skip all descendants */
      if (status->kind == svn_node_dir)
        baton->skip_below_abspath = apr_pstrdup(baton->result_pool,
                                                local_abspath);
      return SVN_NO_ERROR;
    }

  /* Recursively handle each node according to depth, except when the
     node is only being deleted, or is in an added tree (as added trees
     use the normal commit handling). */
  if (copy_mode && !is_added && !is_deleted && status->kind == svn_node_dir)
    {
      SVN_ERR(harvest_not_present_for_copy(wc_ctx, local_abspath, committables,
                                           repos_root_url, commit_relpath,
                                           baton->check_url_func,
                                           baton->check_url_baton,
                                           result_pool, scratch_pool));
    }

  return SVN_NO_ERROR;
}

/* Baton for handle_descendants */
struct handle_descendants_baton
{
  svn_wc_context_t *wc_ctx;
  svn_cancel_func_t cancel_func;
  void *cancel_baton;
  svn_client__check_url_kind_t check_url_func;
  void *check_url_baton;
  svn_client__committables_t *committables;
};

/* Helper for the commit harvesters */
static svn_error_t *
handle_descendants(void *baton,
                   const void *key, apr_ssize_t klen, void *val,
                   apr_pool_t *pool)
{
  struct handle_descendants_baton *hdb = baton;
  apr_array_header_t *commit_items = val;
  apr_pool_t *iterpool = svn_pool_create(pool);
  const char *repos_root_url = key;
  int i;

  for (i = 0; i < commit_items->nelts; i++)
    {
      svn_client_commit_item3_t *item =
        APR_ARRAY_IDX(commit_items, i, svn_client_commit_item3_t *);
      const apr_array_header_t *absent_descendants;
      int j;

      /* Is this a copy operation? */
      if (!(item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)
          || ! item->copyfrom_url)
        continue;

      if (hdb->cancel_func)
        SVN_ERR(hdb->cancel_func(hdb->cancel_baton));

      svn_pool_clear(iterpool);

      SVN_ERR(svn_wc__get_not_present_descendants(&absent_descendants,
                                                  hdb->wc_ctx, item->path,
                                                  iterpool, iterpool));

      for (j = 0; j < absent_descendants->nelts; j++)
        {
          svn_node_kind_t kind;
          svn_client_commit_item3_t *desc_item;
          const char *relpath = APR_ARRAY_IDX(absent_descendants, j,
                                              const char *);
          const char *local_abspath = svn_dirent_join(item->path, relpath,
                                                      iterpool);

          /* ### Need a sub-iterpool? */


          /* We found a 'not present' descendant during a copy (at op_depth>0),
             this is most commonly caused by copying some mixed revision tree.

             In this case not present can imply that the node does not exist
             in the parent revision, or that the node does. But we want to copy
             the working copy state in which it does not exist, but might be
             replaced. */

          desc_item = svn_hash_gets(hdb->committables->by_path, local_abspath);

          /* If the path has a commit operation (possibly at an higher
             op_depth, we might want to turn an add in a replace. */
          if (desc_item)
            {
              const char *dir;
              svn_boolean_t found_intermediate = FALSE;

              if (desc_item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)
                continue; /* We already have a delete or replace */
              else if (!(desc_item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD))
                continue; /* Not a copy/add, just a modification */

              dir = svn_dirent_dirname(local_abspath, iterpool);

              while (strcmp(dir, item->path))
                {
                  svn_client_commit_item3_t *i_item;

                  i_item = svn_hash_gets(hdb->committables->by_path, dir);

                  if (i_item)
                    {
                      if ((i_item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)
                          || (i_item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD))
                        {
                          found_intermediate = TRUE;
                          break;
                        }
                    }
                  dir = svn_dirent_dirname(dir, iterpool);
                }

              if (found_intermediate)
                continue; /* Some intermediate ancestor is an add or delete */

              /* Fall through to detect if we need to turn the add in a
                 replace. */
            }

          if (hdb->check_url_func)
            {
              const char *from_url = svn_path_url_add_component2(
                                                item->copyfrom_url, relpath,
                                                iterpool);

              SVN_ERR(hdb->check_url_func(hdb->check_url_baton,
                                          &kind, from_url, item->copyfrom_rev,
                                          iterpool));

              if (kind == svn_node_none)
                continue; /* This node is already deleted */
            }
          else
            kind = svn_node_unknown; /* 'Ok' for a delete of something */

          if (desc_item)
            {
              /* Extend the existing add/copy item to create a replace */
              desc_item->state_flags |= SVN_CLIENT_COMMIT_ITEM_DELETE;
              continue;
            }

          /* Add a new commit item that describes the delete */

          SVN_ERR(add_committable(hdb->committables,
                                  svn_dirent_join(item->path, relpath,
                                                  iterpool),
                                  kind,
                                  repos_root_url,
                                  svn_uri_skip_ancestor(
                                        repos_root_url,
                                        svn_path_url_add_component2(item->url,
                                                                    relpath,
                                                                    iterpool),
                                        iterpool),
                                  SVN_INVALID_REVNUM,
                                  NULL /* copyfrom_relpath */,
                                  SVN_INVALID_REVNUM,
                                  NULL /* moved_from_abspath */,
                                  SVN_CLIENT_COMMIT_ITEM_DELETE,
                                  NULL /* lock tokens */,
                                  NULL /* lock */,
                                  commit_items->pool,
                                  iterpool));
        }
      }

  svn_pool_destroy(iterpool);
  return SVN_NO_ERROR;
}

/* Allocate and initialize the COMMITTABLES structure from POOL.
 */
static void
create_committables(svn_client__committables_t **committables,
                    apr_pool_t *pool)
{
  *committables = apr_palloc(pool, sizeof(**committables));

  (*committables)->by_repository = apr_hash_make(pool);
  (*committables)->by_path = apr_hash_make(pool);
}

svn_error_t *
svn_client__harvest_committables(svn_client__committables_t **committables,
                                 apr_hash_t **lock_tokens,
                                 const char *base_dir_abspath,
                                 const apr_array_header_t *targets,
                                 int depth_empty_start,
                                 svn_depth_t depth,
                                 svn_boolean_t just_locked,
                                 const apr_array_header_t *changelists,
                                 svn_client__check_url_kind_t check_url_func,
                                 void *check_url_baton,
                                 svn_client_ctx_t *ctx,
                                 apr_pool_t *result_pool,
                                 apr_pool_t *scratch_pool)
{
  int i;
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
  apr_hash_t *changelist_hash = NULL;
  struct handle_descendants_baton hdb;
  apr_hash_index_t *hi;

  /* It's possible that one of the named targets has a parent that is
   * itself scheduled for addition or replacement -- that is, the
   * parent is not yet versioned in the repository.  This is okay, as
   * long as the parent itself is part of this same commit, either
   * directly, or by virtue of a grandparent, great-grandparent, etc,
   * being part of the commit.
   *
   * Since we don't know what's included in the commit until we've
   * harvested all the targets, we can't reliably check this as we
   * go.  So in `danglers', we record named targets whose parents
   * do not yet exist in the repository. Then after harvesting the total
   * commit group, we check to make sure those parents are included.
   *
   * Each key of danglers is a parent which does not exist in the
   * repository.  The (const char *) value is one of that parent's
   * children which is named as part of the commit; the child is
   * included only to make a better error message.
   *
   * (The reason we don't bother to check unnamed -- i.e, implicit --
   * targets is that they can only join the commit if their parents
   * did too, so this situation can't arise for them.)
   */
  apr_hash_t *danglers = apr_hash_make(scratch_pool);

  SVN_ERR_ASSERT(svn_dirent_is_absolute(base_dir_abspath));

  /* Create the COMMITTABLES structure. */
  create_committables(committables, result_pool);

  /* And the LOCK_TOKENS dito. */
  *lock_tokens = apr_hash_make(result_pool);

  /* If we have a list of changelists, convert that into a hash with
     changelist keys. */
  if (changelists && changelists->nelts)
    SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash, changelists,
                                       scratch_pool));

  for (i = 0; i < targets->nelts; ++i)
    {
      const char *target_abspath;

      svn_pool_clear(iterpool);

      /* Add the relative portion to the base abspath.  */
      target_abspath = svn_dirent_join(base_dir_abspath,
                                       APR_ARRAY_IDX(targets, i, const char *),
                                       iterpool);

      /* 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, target_abspath,
                                               ctx->notify_func2,
                                               ctx->notify_baton2,
                                               iterpool));

      /* Are the remaining items externals with depth empty? */
      if (i == depth_empty_start)
        depth = svn_depth_empty;

      SVN_ERR(harvest_committables(target_abspath,
                                   *committables, *lock_tokens,
                                   NULL /* COPY_MODE_RELPATH */,
                                   depth, just_locked, changelist_hash,
                                   danglers,
                                   check_url_func, check_url_baton,
                                   ctx->cancel_func, ctx->cancel_baton,
                                   ctx->notify_func2, ctx->notify_baton2,
                                   ctx->wc_ctx, result_pool, iterpool));
    }

  hdb.wc_ctx = ctx->wc_ctx;
  hdb.cancel_func = ctx->cancel_func;
  hdb.cancel_baton = ctx->cancel_baton;
  hdb.check_url_func = check_url_func;
  hdb.check_url_baton = check_url_baton;
  hdb.committables = *committables;

  SVN_ERR(svn_iter_apr_hash(NULL, (*committables)->by_repository,
                            handle_descendants, &hdb, iterpool));

  /* Make sure that every path in danglers is part of the commit. */
  for (hi = apr_hash_first(scratch_pool, danglers); hi; hi = apr_hash_next(hi))
    {
      const char *dangling_parent = apr_hash_this_key(hi);

      svn_pool_clear(iterpool);

      if (! look_up_committable(*committables, dangling_parent, iterpool))
        {
          const char *dangling_child = apr_hash_this_val(hi);

          if (ctx->notify_func2 != NULL)
            {
              svn_wc_notify_t *notify;

              notify = svn_wc_create_notify(dangling_child,
                                            svn_wc_notify_failed_no_parent,
                                            scratch_pool);

              ctx->notify_func2(ctx->notify_baton2, notify, iterpool);
            }

          return svn_error_createf(
                           SVN_ERR_ILLEGAL_TARGET, NULL,
                           _("'%s' is not known to exist in the repository "
                             "and is not part of the commit, "
                             "yet its child '%s' is part of the commit"),
                           /* Probably one or both of these is an entry, but
                              safest to local_stylize just in case. */
                           svn_dirent_local_style(dangling_parent, iterpool),
                           svn_dirent_local_style(dangling_child, iterpool));
        }
    }

  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}

struct copy_committables_baton
{
  svn_client_ctx_t *ctx;
  svn_client__committables_t *committables;
  apr_pool_t *result_pool;
  svn_client__check_url_kind_t check_url_func;
  void *check_url_baton;
};

static svn_error_t *
harvest_copy_committables(void *baton, void *item, apr_pool_t *pool)
{
  struct copy_committables_baton *btn = baton;
  svn_client__copy_pair_t *pair = *(svn_client__copy_pair_t **)item;
  const char *repos_root_url;
  const char *commit_relpath;
  struct handle_descendants_baton hdb;

  /* Read the entry for this SRC. */
  SVN_ERR_ASSERT(svn_dirent_is_absolute(pair->src_abspath_or_url));

  SVN_ERR(svn_wc__node_get_repos_info(NULL, NULL, &repos_root_url, NULL,
                                      btn->ctx->wc_ctx,
                                      pair->src_abspath_or_url,
                                      pool, pool));

  commit_relpath = svn_uri_skip_ancestor(repos_root_url,
                                         pair->dst_abspath_or_url, pool);

  /* Handle this SRC. */
  SVN_ERR(harvest_committables(pair->src_abspath_or_url,
                               btn->committables, NULL,
                               commit_relpath,
                               svn_depth_infinity,
                               FALSE,  /* JUST_LOCKED */
                               NULL /* changelists */,
                               NULL,
                               btn->check_url_func,
                               btn->check_url_baton,
                               btn->ctx->cancel_func,
                               btn->ctx->cancel_baton,
                               btn->ctx->notify_func2,
                               btn->ctx->notify_baton2,
                               btn->ctx->wc_ctx, btn->result_pool, pool));

  hdb.wc_ctx = btn->ctx->wc_ctx;
  hdb.cancel_func = btn->ctx->cancel_func;
  hdb.cancel_baton = btn->ctx->cancel_baton;
  hdb.check_url_func = btn->check_url_func;
  hdb.check_url_baton = btn->check_url_baton;
  hdb.committables = btn->committables;

  SVN_ERR(svn_iter_apr_hash(NULL, btn->committables->by_repository,
                            handle_descendants, &hdb, pool));

  return SVN_NO_ERROR;
}



svn_error_t *
svn_client__get_copy_committables(svn_client__committables_t **committables,
                                  const apr_array_header_t *copy_pairs,
                                  svn_client__check_url_kind_t check_url_func,
                                  void *check_url_baton,
                                  svn_client_ctx_t *ctx,
                                  apr_pool_t *result_pool,
                                  apr_pool_t *scratch_pool)
{
  struct copy_committables_baton btn;

  /* Create the COMMITTABLES structure. */
  create_committables(committables, result_pool);

  btn.ctx = ctx;
  btn.committables = *committables;
  btn.result_pool = result_pool;

  btn.check_url_func = check_url_func;
  btn.check_url_baton = check_url_baton;

  /* For each copy pair, harvest the committables for that pair into the
     committables hash. */
  return svn_iter_apr_array(NULL, copy_pairs,
                            harvest_copy_committables, &btn, scratch_pool);
}


/* A svn_sort__array()/qsort()-compatible sort routine for sorting
   an array of svn_client_commit_item_t *'s by their URL member. */
static int
sort_commit_item_urls(const void *a, const void *b)
{
  const svn_client_commit_item3_t *item1
    = *((const svn_client_commit_item3_t * const *) a);
  const svn_client_commit_item3_t *item2
    = *((const svn_client_commit_item3_t * const *) b);
  return svn_path_compare_paths(item1->url, item2->url);
}


svn_error_t *
svn_client__condense_commit_items2(const char *base_url,
                                   apr_array_header_t *commit_items,
                                   apr_pool_t *pool)
{
  apr_array_header_t *ci = commit_items; /* convenience */
  int i;

  /* Sort our commit items by their URLs. */
  svn_sort__array(ci, sort_commit_item_urls);

  /* Hack BASE_URL off each URL; store the result as session_relpath. */
  for (i = 0; i < ci->nelts; i++)
    {
      svn_client_commit_item3_t *this_item
        = APR_ARRAY_IDX(ci, i, svn_client_commit_item3_t *);

      this_item->session_relpath = svn_uri_skip_ancestor(base_url,
                                                         this_item->url, pool);
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client__condense_commit_items(const char **base_url,
                                  apr_array_header_t *commit_items,
                                  apr_pool_t *pool)
{
  apr_array_header_t *ci = commit_items; /* convenience */
  const char *url;
  svn_client_commit_item3_t *item, *last_item = NULL;
  int i;

  SVN_ERR_ASSERT(ci && ci->nelts);

  /* Sort our commit items by their URLs. */
  svn_sort__array(ci, sort_commit_item_urls);

  /* Loop through the URLs, finding the longest usable ancestor common
     to all of them, and making sure there are no duplicate URLs.  */
  for (i = 0; i < ci->nelts; i++)
    {
      item = APR_ARRAY_IDX(ci, i, svn_client_commit_item3_t *);
      url = item->url;

      if ((last_item) && (strcmp(last_item->url, url) == 0))
        return svn_error_createf
          (SVN_ERR_CLIENT_DUPLICATE_COMMIT_URL, NULL,
           _("Cannot commit both '%s' and '%s' as they refer to the same URL"),
           svn_dirent_local_style(item->path, pool),
           svn_dirent_local_style(last_item->path, pool));

      /* In the first iteration, our BASE_URL is just our only
         encountered commit URL to date.  After that, we find the
         longest ancestor between the current BASE_URL and the current
         commit URL.  */
      if (i == 0)
        *base_url = apr_pstrdup(pool, url);
      else
        *base_url = svn_uri_get_longest_ancestor(*base_url, url, pool);

      /* If our BASE_URL is itself a to-be-committed item, and it is
         anything other than an already-versioned directory with
         property mods, we'll call its parent directory URL the
         BASE_URL.  Why?  Because we can't have a file URL as our base
         -- period -- and all other directory operations (removal,
         addition, etc.) require that we open that directory's parent
         dir first.  */
      /* ### I don't understand the strlen()s here, hmmm.  -kff */
      if ((strlen(*base_url) == strlen(url))
          && (! ((item->kind == svn_node_dir)
                 && item->state_flags == SVN_CLIENT_COMMIT_ITEM_PROP_MODS)))
        *base_url = svn_uri_dirname(*base_url, pool);

      /* Stash our item here for the next iteration. */
      last_item = item;
    }

  /* Now that we've settled on a *BASE_URL, go hack that base off
     of all of our URLs and store it as session_relpath. */
  for (i = 0; i < ci->nelts; i++)
    {
      svn_client_commit_item3_t *this_item
        = APR_ARRAY_IDX(ci, i, svn_client_commit_item3_t *);

      this_item->session_relpath = svn_uri_skip_ancestor(*base_url,
                                                         this_item->url, pool);
    }
#ifdef SVN_CLIENT_COMMIT_DEBUG
  /* ### TEMPORARY CODE ### */
  SVN_DBG(("COMMITTABLES: (base URL=%s)\n", *base_url));
  SVN_DBG(("   FLAGS     REV  REL-URL (COPY-URL)\n"));
  for (i = 0; i < ci->nelts; i++)
    {
      svn_client_commit_item3_t *this_item
        = APR_ARRAY_IDX(ci, i, svn_client_commit_item3_t *);
      char flags[6];
      flags[0] = (this_item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)
                   ? 'a' : '-';
      flags[1] = (this_item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)
                   ? 'd' : '-';
      flags[2] = (this_item->state_flags & SVN_CLIENT_COMMIT_ITEM_TEXT_MODS)
                   ? 't' : '-';
      flags[3] = (this_item->state_flags & SVN_CLIENT_COMMIT_ITEM_PROP_MODS)
                   ? 'p' : '-';
      flags[4] = (this_item->state_flags & SVN_CLIENT_COMMIT_ITEM_IS_COPY)
                   ? 'c' : '-';
      flags[5] = '\0';
      SVN_DBG(("   %s  %6ld  '%s' (%s)\n",
               flags,
               this_item->revision,
               this_item->url ? this_item->url : "",
               this_item->copyfrom_url ? this_item->copyfrom_url : "none"));
    }
#endif /* SVN_CLIENT_COMMIT_DEBUG */

  return SVN_NO_ERROR;
}


struct file_mod_t
{
  const svn_client_commit_item3_t *item;
  void *file_baton;
  apr_pool_t *file_pool;
};


/* A baton for use while driving a path-based editor driver for commit */
struct item_commit_baton
{
  apr_hash_t *file_mods;               /* hash: path->file_mod_t */
  const char *notify_path_prefix;      /* notification path prefix
                                          (NULL is okay, else abs path) */
  svn_client_ctx_t *ctx;               /* client context baton */
  apr_hash_t *commit_items;            /* the committables */
  const char *base_url;                /* The session url for the commit */
};


/* 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,
               const svn_delta_editor_t *editor,
               void *edit_baton,
               void *parent_baton,
               void *callback_baton,
               const char *path,
               apr_pool_t *pool)
{
  struct item_commit_baton *icb = callback_baton;
  const svn_client_commit_item3_t *item = svn_hash_gets(icb->commit_items,
                                                        path);
  svn_node_kind_t kind = item->kind;
  void *file_baton = NULL;
  apr_pool_t *file_pool = NULL;
  apr_hash_t *file_mods = icb->file_mods;
  svn_client_ctx_t *ctx = icb->ctx;
  svn_error_t *err;
  const char *local_abspath = NULL;

  /* Do some initializations. */
  *dir_baton = NULL;
  if (item->kind != svn_node_none && item->path)
    {
      /* We always get an absolute path, see svn_client_commit_item3_t. */
      SVN_ERR_ASSERT(svn_dirent_is_absolute(item->path));
      local_abspath = item->path;
    }

  /* If this is a file with textual mods, we'll be keeping its baton
     around until the end of the commit.  So just lump its memory into
     a single, big, all-the-file-batons-in-here pool.  Otherwise, we
     can just use POOL, and trust our caller to clean that mess up. */
  if ((kind == svn_node_file)
      && (item->state_flags & SVN_CLIENT_COMMIT_ITEM_TEXT_MODS))
    file_pool = apr_hash_pool_get(file_mods);
  else
    file_pool = pool;

  /* Subpools are cheap, but memory isn't */
  file_pool = svn_pool_create(file_pool);

  /* Call the cancellation function. */
  if (ctx->cancel_func)
    SVN_ERR(ctx->cancel_func(ctx->cancel_baton));

  /* Validation. */
  if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_IS_COPY)
    {
      if (! item->copyfrom_url)
        return svn_error_createf
          (SVN_ERR_BAD_URL, NULL,
           _("Commit item '%s' has copy flag but no copyfrom URL"),
           svn_dirent_local_style(path, pool));
      if (! SVN_IS_VALID_REVNUM(item->copyfrom_rev))
        return svn_error_createf
          (SVN_ERR_CLIENT_BAD_REVISION, NULL,
           _("Commit item '%s' has copy flag but an invalid revision"),
           svn_dirent_local_style(path, pool));
    }

  /* If a feedback table was supplied by the application layer,
     describe what we're about to do to this item. */
  if (ctx->notify_func2 && item->path)
    {
      const char *npath = item->path;
      svn_wc_notify_t *notify;

      if ((item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)
          && (item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD))
        {
          /* We don't print the "(bin)" notice for binary files when
             replacing, only when adding.  So we don't bother to get
             the mime-type here. */
          if (item->copyfrom_url)
            notify = svn_wc_create_notify(npath,
                                          svn_wc_notify_commit_copied_replaced,
                                          pool);
          else
            notify = svn_wc_create_notify(npath, svn_wc_notify_commit_replaced,
                                          pool);

        }
      else if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)
        {
          notify = svn_wc_create_notify(npath, svn_wc_notify_commit_deleted,
                                        pool);
        }
      else if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)
        {
          if (item->copyfrom_url)
            notify = svn_wc_create_notify(npath, svn_wc_notify_commit_copied,
                                          pool);
          else
            notify = svn_wc_create_notify(npath, svn_wc_notify_commit_added,
                                          pool);

          if (item->kind == svn_node_file)
            {
              const svn_string_t *propval;

              SVN_ERR(svn_wc_prop_get2(&propval, ctx->wc_ctx, local_abspath,
                                       SVN_PROP_MIME_TYPE, pool, pool));

              if (propval)
                notify->mime_type = propval->data;
            }
        }
      else if ((item->state_flags & SVN_CLIENT_COMMIT_ITEM_TEXT_MODS)
               || (item->state_flags & SVN_CLIENT_COMMIT_ITEM_PROP_MODS))
        {
          notify = svn_wc_create_notify(npath, svn_wc_notify_commit_modified,
                                        pool);
          if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_TEXT_MODS)
            notify->content_state = svn_wc_notify_state_changed;
          else
            notify->content_state = svn_wc_notify_state_unchanged;
          if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_PROP_MODS)
            notify->prop_state = svn_wc_notify_state_changed;
          else
            notify->prop_state = svn_wc_notify_state_unchanged;
        }
      else
        notify = NULL;


      if (notify)
        {
          notify->kind = item->kind;
          notify->path_prefix = icb->notify_path_prefix;
          ctx->notify_func2(ctx->notify_baton2, notify, pool);
        }
    }

  /* If this item is supposed to be deleted, do so. */
  if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)
    {
      SVN_ERR_ASSERT(parent_baton);
      err = editor->delete_entry(path, item->revision,
                                 parent_baton, pool);

      if (err)
        goto fixup_error;
    }

  /* If this item is supposed to be added, do so. */
  if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)
    {
      if (kind == svn_node_file)
        {
          SVN_ERR_ASSERT(parent_baton);
          err = editor->add_file(
                   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);
          err = editor->add_directory(
                   path, parent_baton, item->copyfrom_url,
                   item->copyfrom_url ? item->copyfrom_rev : SVN_INVALID_REVNUM,
                   pool, dir_baton);
        }

      if (err)
        goto fixup_error;

      /* Set other prop-changes, if available in the baton */
      if (item->outgoing_prop_changes)
        {
          svn_prop_t *prop;
          apr_array_header_t *prop_changes = item->outgoing_prop_changes;
          int ctr;
          for (ctr = 0; ctr < prop_changes->nelts; ctr++)
            {
              prop = APR_ARRAY_IDX(prop_changes, ctr, svn_prop_t *);
              if (kind == svn_node_file)
                {
                  err = editor->change_file_prop(file_baton, prop->name,
                                                 prop->value, pool);
                }
              else
                {
                  err = editor->change_dir_prop(*dir_baton, prop->name,
                                                prop->value, pool);
                }

              if (err)
                goto fixup_error;
            }
        }
    }

  /* Now handle property mods. */
  if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_PROP_MODS)
    {
      if (kind == svn_node_file)
        {
          if (! file_baton)
            {
              SVN_ERR_ASSERT(parent_baton);
              err = editor->open_file(path, parent_baton,
                                      item->revision,
                                      file_pool, &file_baton);

              if (err)
                goto fixup_error;
            }
        }
      else
        {
          if (! *dir_baton)
            {
              if (! parent_baton)
                {
                  err = editor->open_root(edit_baton, item->revision,
                                          pool, dir_baton);
                }
              else
                {
                  err = editor->open_directory(path, parent_baton,
                                               item->revision,
                                               pool, dir_baton);
                }

              if (err)
                goto fixup_error;
            }
        }

      /* When committing a directory that no longer exists in the
         repository, a "not found" error does not occur immediately
         upon opening the directory.  It appears here during the delta
         transmisssion. */
      err = svn_wc_transmit_prop_deltas2(
              ctx->wc_ctx, local_abspath, editor,
              (kind == svn_node_dir) ? *dir_baton : file_baton, pool);

      if (err)
        goto fixup_error;

      /* Make any additional client -> repository prop changes. */
      if (item->outgoing_prop_changes)
        {
          svn_prop_t *prop;
          int i;

          for (i = 0; i < item->outgoing_prop_changes->nelts; i++)
            {
              prop = APR_ARRAY_IDX(item->outgoing_prop_changes, i,
                                   svn_prop_t *);
              if (kind == svn_node_file)
                {
                  err = editor->change_file_prop(file_baton, prop->name,
                                           prop->value, pool);
                }
              else
                {
                  err = editor->change_dir_prop(*dir_baton, prop->name,
                                          prop->value, pool);
                }

              if (err)
                goto fixup_error;
            }
        }
    }

  /* Finally, handle text mods (in that we need to open a file if it
     hasn't already been opened, and we need to put the file baton in
     our FILES hash). */
  if ((kind == svn_node_file)
      && (item->state_flags & SVN_CLIENT_COMMIT_ITEM_TEXT_MODS))
    {
      struct file_mod_t *mod = apr_palloc(file_pool, sizeof(*mod));

      if (! file_baton)
        {
          SVN_ERR_ASSERT(parent_baton);
          err = editor->open_file(path, parent_baton,
                                    item->revision,
                                    file_pool, &file_baton);

          if (err)
            goto fixup_error;
        }

      /* Add this file mod to the FILE_MODS hash. */
      mod->item = item;
      mod->file_baton = file_baton;
      mod->file_pool = file_pool;
      svn_hash_sets(file_mods, item->session_relpath, mod);
    }
  else if (file_baton)
    {
      /* Close any outstanding file batons that didn't get caught by
         the "has local mods" conditional above. */
      err = editor->close_file(file_baton, NULL, file_pool);
      svn_pool_destroy(file_pool);
      if (err)
        goto fixup_error;
    }

  return SVN_NO_ERROR;

fixup_error:
  return svn_error_trace(fixup_commit_error(local_abspath,
                                            icb->base_url,
                                            path, kind,
                                            err, ctx, pool));
}

svn_error_t *
svn_client__do_commit(const char *base_url,
                      const apr_array_header_t *commit_items,
                      const svn_delta_editor_t *editor,
                      void *edit_baton,
                      const char *notify_path_prefix,
                      apr_hash_t **sha1_checksums,
                      svn_client_ctx_t *ctx,
                      apr_pool_t *result_pool,
                      apr_pool_t *scratch_pool)
{
  apr_hash_t *file_mods = apr_hash_make(scratch_pool);
  apr_hash_t *items_hash = apr_hash_make(scratch_pool);
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
  apr_hash_index_t *hi;
  int i;
  struct item_commit_baton cb_baton;
  apr_array_header_t *paths =
    apr_array_make(scratch_pool, commit_items->nelts, sizeof(const char *));

  /* Ditto for the checksums. */
  if (sha1_checksums)
    *sha1_checksums = apr_hash_make(result_pool);

  /* Build a hash from our COMMIT_ITEMS array, keyed on the
     relative paths (which come from the item URLs).  And
     keep an array of those decoded paths, too.  */
  for (i = 0; i < commit_items->nelts; i++)
    {
      svn_client_commit_item3_t *item =
        APR_ARRAY_IDX(commit_items, i, svn_client_commit_item3_t *);
      const char *path = item->session_relpath;
      svn_hash_sets(items_hash, path, item);
      APR_ARRAY_PUSH(paths, const char *) = path;
    }

  /* Setup the callback baton. */
  cb_baton.file_mods = file_mods;
  cb_baton.notify_path_prefix = notify_path_prefix;
  cb_baton.ctx = ctx;
  cb_baton.commit_items = items_hash;
  cb_baton.base_url = base_url;

  /* Drive the commit editor! */
  SVN_ERR(svn_delta_path_driver3(editor, edit_baton, paths, TRUE,
                                 do_item_commit, &cb_baton, scratch_pool));

  /* Transmit outstanding text deltas. */
  for (hi = apr_hash_first(scratch_pool, file_mods);
       hi;
       hi = apr_hash_next(hi))
    {
      struct file_mod_t *mod = apr_hash_this_val(hi);
      const svn_client_commit_item3_t *item = mod->item;
      const svn_checksum_t *new_text_base_md5_checksum;
      const svn_checksum_t *new_text_base_sha1_checksum;
      svn_boolean_t fulltext = FALSE;
      svn_error_t *err;

      svn_pool_clear(iterpool);

      /* Transmit the entry. */
      if (ctx->cancel_func)
        SVN_ERR(ctx->cancel_func(ctx->cancel_baton));

      if (ctx->notify_func2)
        {
          svn_wc_notify_t *notify;
          notify = svn_wc_create_notify(item->path,
                                        svn_wc_notify_commit_postfix_txdelta,
                                        iterpool);
          notify->kind = svn_node_file;
          notify->path_prefix = notify_path_prefix;
          ctx->notify_func2(ctx->notify_baton2, notify, iterpool);
        }

      /* If the node has no history, transmit full text */
      if ((item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)
          && ! (item->state_flags & SVN_CLIENT_COMMIT_ITEM_IS_COPY))
        fulltext = TRUE;

      err = svn_wc_transmit_text_deltas3(&new_text_base_md5_checksum,
                                         &new_text_base_sha1_checksum,
                                         ctx->wc_ctx, item->path,
                                         fulltext, editor, mod->file_baton,
                                         result_pool, iterpool);

      if (err)
        {
          svn_pool_destroy(iterpool); /* Close tempfiles */
          return svn_error_trace(fixup_commit_error(item->path,
                                                    base_url,
                                                    item->session_relpath,
                                                    svn_node_file,
                                                    err, ctx, scratch_pool));
        }

      if (sha1_checksums)
        svn_hash_sets(*sha1_checksums, item->path, new_text_base_sha1_checksum);

      svn_pool_destroy(mod->file_pool);
    }

  if (ctx->notify_func2)
    {
      svn_wc_notify_t *notify;
      notify = svn_wc_create_notify_url(base_url,
                                        svn_wc_notify_commit_finalizing,
                                        iterpool);
      ctx->notify_func2(ctx->notify_baton2, notify, iterpool);
    }

  svn_pool_destroy(iterpool);

  /* Close the edit. */
  return svn_error_trace(editor->close_edit(edit_baton, scratch_pool));
}


svn_error_t *
svn_client__get_log_msg(const char **log_msg,
                        const char **tmp_file,
                        const apr_array_header_t *commit_items,
                        svn_client_ctx_t *ctx,
                        apr_pool_t *pool)
{
  if (ctx->log_msg_func3)
    {
      /* The client provided a callback function for the current API.
         Forward the call to it directly. */
      return (*ctx->log_msg_func3)(log_msg, tmp_file, commit_items,
                                   ctx->log_msg_baton3, pool);
    }
  else if (ctx->log_msg_func2 || ctx->log_msg_func)
    {
      /* The client provided a pre-1.5 (or pre-1.3) API callback
         function.  Convert the commit_items list to the appropriate
         type, and forward call to it. */
      svn_error_t *err;
      apr_pool_t *scratch_pool = svn_pool_create(pool);
      apr_array_header_t *old_commit_items =
        apr_array_make(scratch_pool, commit_items->nelts, sizeof(void*));

      int i;
      for (i = 0; i < commit_items->nelts; i++)
        {
          svn_client_commit_item3_t *item =
            APR_ARRAY_IDX(commit_items, i, svn_client_commit_item3_t *);

          if (ctx->log_msg_func2)
            {
              svn_client_commit_item2_t *old_item =
                apr_pcalloc(scratch_pool, sizeof(*old_item));

              old_item->path = item->path;
              old_item->kind = item->kind;
              old_item->url = item->url;
              old_item->revision = item->revision;
              old_item->copyfrom_url = item->copyfrom_url;
              old_item->copyfrom_rev = item->copyfrom_rev;
              old_item->state_flags = item->state_flags;
              old_item->wcprop_changes = item->incoming_prop_changes;

              APR_ARRAY_PUSH(old_commit_items, svn_client_commit_item2_t *) =
                old_item;
            }
          else /* ctx->log_msg_func */
            {
              svn_client_commit_item_t *old_item =
                apr_pcalloc(scratch_pool, sizeof(*old_item));

              old_item->path = item->path;
              old_item->kind = item->kind;
              old_item->url = item->url;
              /* The pre-1.3 API used the revision field for copyfrom_rev
                 and revision depending of copyfrom_url. */
              old_item->revision = item->copyfrom_url ?
                item->copyfrom_rev : item->revision;
              old_item->copyfrom_url = item->copyfrom_url;
              old_item->state_flags = item->state_flags;
              old_item->wcprop_changes = item->incoming_prop_changes;

              APR_ARRAY_PUSH(old_commit_items, svn_client_commit_item_t *) =
                old_item;
            }
        }

      if (ctx->log_msg_func2)
        err = (*ctx->log_msg_func2)(log_msg, tmp_file, old_commit_items,
                                    ctx->log_msg_baton2, pool);
      else
        err = (*ctx->log_msg_func)(log_msg, tmp_file, old_commit_items,
                                   ctx->log_msg_baton, pool);
      svn_pool_destroy(scratch_pool);
      return err;
    }
  else
    {
      /* No log message callback was provided by the client. */
      *log_msg = "";
      *tmp_file = NULL;
      return SVN_NO_ERROR;
    }
}

svn_error_t *
svn_client__ensure_revprop_table(apr_hash_t **revprop_table_out,
                                 const apr_hash_t *revprop_table_in,
                                 const char *log_msg,
                                 svn_client_ctx_t *ctx,
                                 apr_pool_t *pool)
{
  apr_hash_t *new_revprop_table;
  if (revprop_table_in)
    {
      if (svn_prop_has_svn_prop(revprop_table_in, pool))
        return svn_error_create(SVN_ERR_CLIENT_PROPERTY_NAME, NULL,
                                _("Standard properties can't be set "
                                  "explicitly as revision properties"));
      new_revprop_table = apr_hash_copy(pool, revprop_table_in);
    }
  else
    {
      new_revprop_table = apr_hash_make(pool);
    }
  svn_hash_sets(new_revprop_table, SVN_PROP_REVISION_LOG,
                svn_string_create(log_msg, pool));
  *revprop_table_out = new_revprop_table;
  return SVN_NO_ERROR;
}
