/*
 * commit.c:  wrappers around wc commit functionality.
 *
 * ====================================================================
 * Copyright (c) 2000-2002 CollabNet.  All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at http://subversion.tigris.org/license-1.html.
 * If newer versions of this license are posted there, you may use a
 * newer version instead, at your option.
 *
 * This software consists of voluntary contributions made by many
 * individuals.  For exact contribution history, see the revision
 * history and logs, available at http://subversion.tigris.org/.
 * ====================================================================
 */

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



/*** Includes. ***/

#include <string.h>
#include <assert.h>
#include <apr_strings.h>
#include "svn_wc.h"
#include "svn_ra.h"
#include "svn_delta.h"
#include "svn_client.h"
#include "svn_string.h"
#include "svn_pools.h"
#include "svn_error.h"
#include "svn_path.h"
#include "svn_test.h"
#include "svn_io.h"

#include "client.h"


/* Shared internals of import and commit. */

/* Apply PATH's contents (as a delta against the empty string) to
   FILE_BATON in EDITOR.  Use POOL for any temporary allocation.  */
static svn_error_t *
send_file_contents (svn_stringbuf_t *path,
                    void *file_baton,
                    const svn_delta_editor_t *editor,
                    apr_pool_t *pool)
{
  svn_stream_t *contents;
  svn_txdelta_window_handler_t handler;
  void *handler_baton;
  apr_file_t *f = NULL;
  apr_status_t apr_err;

  /* Get an apr file for PATH. */
  apr_err = apr_file_open (&f, path->data, APR_READ, APR_OS_DEFAULT, pool);
  if (! APR_STATUS_IS_SUCCESS (apr_err))
    return svn_error_createf (apr_err, 0, NULL, pool, 
                              "error opening `%s' for reading", path->data);
  
  /* Get a readable stream of the file's contents. */
  contents = svn_stream_from_aprfile (f, pool);

  /* Get an editor func that wants to consume the delta stream. */
  SVN_ERR (editor->apply_textdelta (file_baton, &handler, &handler_baton));

  /* Send the file's contents to the delta-window handler. */
  SVN_ERR (svn_txdelta_send_stream (contents, handler, handler_baton, pool));

  /* Close the file. */
  apr_err = apr_file_close (f);
  if (! APR_STATUS_IS_SUCCESS (apr_err))
    return svn_error_createf
      (apr_err, 0, NULL, pool, "error closing `%s'", path->data);

  return SVN_NO_ERROR;
}


/* Import file PATH as EDIT_PATH in the repository directory indicated
 * by DIR_BATON in EDITOR.  
 *
 * Use POOL for any temporary allocation.  */
static svn_error_t *
import_file (apr_hash_t *files,
             const svn_delta_editor_t *editor,
             void *dir_baton,
             const svn_stringbuf_t *path,
             const char *edit_path,
             apr_pool_t *pool)
{
  void *file_baton;
  const char *mimetype;
  apr_pool_t *hash_pool = apr_hash_pool_get (files);
  svn_stringbuf_t *filepath = svn_stringbuf_dup (path, hash_pool);

  /* Add the file, using the pool from the FILES hash. */
  SVN_ERR (editor->add_file (edit_path, dir_baton, NULL, SVN_INVALID_REVNUM, 
                             hash_pool, &file_baton));          

  /* If the file has a discernable mimetype, add that as a property to
     the file. */
  SVN_ERR (svn_io_detect_mimetype (&mimetype, path->data, pool));
  if (mimetype)
    SVN_ERR (editor->change_file_prop (file_baton, SVN_PROP_MIME_TYPE,
                                       svn_string_create (mimetype, pool), 
                                       pool));
  
  /* Finally, add the file's path and baton to the FILES hash. */
  apr_hash_set (files, filepath->data, filepath->len, (void *)file_baton);

  return SVN_NO_ERROR;
}
             

/* Import directory PATH into the repository directory indicated by
 * DIR_BATON in EDITOR.  ROOT_PATH is the path imported as the root
 * directory, so all edits are relative to that.
 *
 * Use POOL for any temporary allocation.  */
static svn_error_t *
import_dir (apr_hash_t *files,
            const svn_delta_editor_t *editor, 
            void *dir_baton,
            const svn_stringbuf_t *path,
            const svn_stringbuf_t *edit_path,
            apr_pool_t *pool)
{
  apr_pool_t *subpool = svn_pool_create (pool);  /* iteration pool */
  apr_dir_t *dir;
  apr_finfo_t finfo;
  apr_status_t apr_err;
  apr_int32_t flags = APR_FINFO_TYPE | APR_FINFO_NAME;
  svn_stringbuf_t *this_path, *this_edit_path;

  if ((apr_err = apr_dir_open (&dir, path->data, pool)))
    return svn_error_createf (apr_err, 0, NULL, pool, 
                              "unable to open directory %s", path->data);

  this_path = svn_stringbuf_dup (path, pool);
  this_edit_path = svn_stringbuf_dup (edit_path, pool);

  for (apr_err = apr_dir_read (&finfo, flags, dir);
       APR_STATUS_IS_SUCCESS (apr_err);
       svn_pool_clear (subpool), apr_err = apr_dir_read (&finfo, flags, dir))
    {
      svn_stringbuf_t *name;

      if (finfo.filetype == APR_DIR)
        {
          /* Skip entries for this dir and its parent.  
             ### kff todo: APR actually promises that they'll come first,
             so this guard could be moved outside the loop. */
          if (! (strcmp (finfo.name, ".") && strcmp (finfo.name, "..")))
            continue;

          /* If someone's trying to import a directory named the same
             as our administrative directories, that's probably not
             what they wanted to do.  Someday we can take an option to
             make these subdirs be silently ignored, but for now,
             seems safest to error. */
          if (strcmp (finfo.name, SVN_WC_ADM_DIR_NAME) == 0)
            return svn_error_createf
              (SVN_ERR_CL_ADM_DIR_RESERVED, 0, NULL, subpool,
               "cannot import directory named \"%s\" (in `%s')",
               finfo.name, path->data);
        }

      /* Make a stringbuf version of the entry name, and append it as
         a path component to THIS_PATH and THIS_EDIT_PATH. */
      name = svn_stringbuf_create (finfo.name, subpool);
      svn_path_add_component (this_path, name);
      svn_path_add_component (this_edit_path, name);

      if (finfo.filetype == APR_DIR)
        {
          void *this_dir_baton;

          /* Add the new subdirectory, getting a descent baton from
             the editor. */
          SVN_ERR (editor->add_directory (this_edit_path->data, dir_baton, 
                                          NULL, SVN_INVALID_REVNUM, subpool,
                                          &this_dir_baton));

          /* Recurse. */
          SVN_ERR (import_dir (files, editor, this_dir_baton, 
                               this_path, this_edit_path, subpool));

          /* Finally, close the sub-directory. */
          SVN_ERR (editor->close_directory (this_dir_baton));
        }
      else if (finfo.filetype == APR_REG)
        {
          /* Import a file. */
          SVN_ERR (import_file (files, editor, dir_baton, 
                                this_path, this_edit_path->data, subpool));
        }
      else
        {
          /* It's not a file or dir, so we can't import it (yet).
             No need to error, just ignore the thing. */
        }
      
      /* Hack THIS_PATH and THIS_EDIT_PATH back to their original sizes. */
      svn_stringbuf_chop (this_path, 
                          (path->len ? name->len + 1 : name->len));
      svn_stringbuf_chop (this_edit_path, 
                          (edit_path->len ? name->len + 1 : name->len));
    }

  /* Check that the loop exited cleanly. */
  if (! (APR_STATUS_IS_ENOENT (apr_err)))
    return svn_error_createf
      (apr_err, 0, NULL, subpool, "error during import of `%s'", path->data);

  /* Yes, it exited cleanly, so close the dir. */
  else if ((apr_err = apr_dir_close (dir)))
    return svn_error_createf
      (apr_err, 0, NULL, subpool, "error closing dir `%s'", path->data);
      
  svn_pool_destroy (subpool);
  return SVN_NO_ERROR;
}



/*** Public interfaces. ***/

/* Recursively import PATH to a repository using EDITOR and
 * EDIT_BATON.  PATH can be a file or directory.
 * 
 * NEW_ENTRY is the name to use in the repository.  If PATH is a
 * directory, NEW_ENTRY may be null, which creates as many new entries
 * in the top repository target directory as there are entries in the
 * top of PATH; but if NEW_ENTRY is non-null, it is the name of a new
 * subdirectory in the repository to hold the import.  If PATH is a
 * file, NEW_ENTRY may not be null.
 * 
 * NEW_ENTRY can never be the empty string.
 * 
 * Use POOL for any temporary allocation.
 *
 * Note: the repository directory receiving the import was specified
 * when the editor was fetched.  (I.e, when EDITOR->open_root() is
 * called, it returns a directory baton for that directory, which is
 * not necessarily the root.)
 */
static svn_error_t *
import (const svn_stringbuf_t *path,
        const svn_stringbuf_t *new_entry,
        const svn_delta_editor_t *editor,
        void *edit_baton,
        apr_pool_t *pool)
{
  void *root_baton;
  enum svn_node_kind kind;
  apr_hash_t *files = apr_hash_make (pool);
  apr_pool_t *subpool = svn_pool_create (pool); /* for post-fix textdeltas */
  apr_hash_index_t *hi;

  /* Get a root dir baton.  We pass an invalid revnum to open_root
     to mean "base this on the youngest revision".  Should we have an
     SVN_YOUNGEST_REVNUM defined for these purposes? */
  SVN_ERR (editor->open_root (edit_baton, SVN_INVALID_REVNUM, 
                              pool, &root_baton));

  /* Import a file or a directory tree. */
  SVN_ERR (svn_io_check_path (path->data, &kind, pool));

  /* Note that there is no need to check whether PATH's basename is
     the same name that we reserve for our admistritave
     subdirectories.  It would be strange, but not illegal to import
     the contents of a directory of that name, because the directory's
     own name is not part of those contents.  Of course, if something
     underneath it also has our reserved name, then we'll error. */

  if (kind == svn_node_file)
    {
      if (! new_entry)
        return svn_error_create
          (SVN_ERR_UNKNOWN_NODE_KIND, 0, NULL, pool,
           "new entry name required when importing a file");

      SVN_ERR (import_file (files, editor, root_baton, 
                            path, new_entry->data, pool));
    }
  else if (kind == svn_node_dir)
    {
      void *new_dir_baton = NULL;

      /* Grab a new baton, making two we'll have to close. */
      if (new_entry)
        SVN_ERR (editor->add_directory (new_entry->data, root_baton,
                                        NULL, SVN_INVALID_REVNUM,
                                        pool, &new_dir_baton));
      
      SVN_ERR (import_dir 
               (files, editor, new_dir_baton ? new_dir_baton : root_baton, 
                path, new_entry ? new_entry : svn_stringbuf_create ("", pool), 
                pool));

      /* Close one baton or two. */
      if (new_dir_baton)
        SVN_ERR (editor->close_directory (new_dir_baton));
    }
  else if (kind == svn_node_none)
    {
      return svn_error_createf
        (SVN_ERR_UNKNOWN_NODE_KIND, 0, NULL, pool,
         "'%s' does not exist.", path->data);  
    }

  SVN_ERR (editor->close_directory (root_baton));

  /* Do post-fix textdeltas here! */
  for (hi = apr_hash_first (pool, files); hi; hi = apr_hash_next (hi))
    {
      const void *key;
      apr_ssize_t keylen;
      void *file_baton;
      svn_stringbuf_t *full_path;

      apr_hash_this (hi, &key, &keylen, &file_baton);
      full_path = svn_stringbuf_create ((char *) key, subpool);
      SVN_ERR (send_file_contents (full_path, file_baton, editor, subpool));
      SVN_ERR (editor->close_file (file_baton));

      /* Clear our per-iteration subpool. */
      svn_pool_clear (subpool);
    }
  
  /* Destroy the per-iteration subpool. */
  svn_pool_destroy (subpool);

  SVN_ERR (editor->close_edit (edit_baton));

  return SVN_NO_ERROR;
}


static svn_error_t *
get_xml_editor (apr_file_t **xml_hnd,
                const svn_delta_editor_t **editor,
                void **edit_baton,
                const char *xml_file,
                apr_pool_t *pool)
{
  apr_status_t apr_err;

  /* Open the xml file for writing. */
  if ((apr_err = apr_file_open (xml_hnd, xml_file, (APR_WRITE | APR_CREATE),
                                APR_OS_DEFAULT, pool)))
    return svn_error_createf (apr_err, 0, NULL, pool, 
                              "error opening %s", xml_file);
  
  /* ... we need an XML commit editor. */
  return svn_delta_get_xml_editor (svn_stream_from_aprfile (*xml_hnd, pool), 
                                   editor, edit_baton, pool);
}


static svn_error_t *
get_ra_editor (void **ra_baton, 
               void **session,
               svn_ra_plugin_t **ra_lib,
               const svn_delta_editor_t **editor,
               void **edit_baton,
               svn_client_auth_baton_t *auth_baton,
               svn_stringbuf_t *base_url,
               svn_stringbuf_t *base_dir,
               svn_stringbuf_t *log_msg,
               apr_array_header_t *commit_items,
               svn_revnum_t *committed_rev,
               const char **committed_date,
               const char **committed_author,
               svn_boolean_t is_commit,
               apr_pool_t *pool)
{
  /* Get the RA vtable that matches URL. */
  SVN_ERR (svn_ra_init_ra_libs (ra_baton, pool));
  SVN_ERR (svn_ra_get_ra_library (ra_lib, *ra_baton, 
                                  base_url->data, pool));
  
  /* Open an RA session to URL. */
  SVN_ERR (svn_client__open_ra_session (session, *ra_lib,
                                        base_url, base_dir,
                                        commit_items, is_commit,
                                        is_commit, !is_commit,
                                        auth_baton, pool));
  
  /* Fetch RA commit editor, giving it svn_wc_process_committed(). */
  return (*ra_lib)->get_commit_editor (*session, editor, edit_baton, 
                                       committed_rev, committed_date, 
                                       committed_author, log_msg);
}


/*** Public Interfaces. ***/

svn_error_t *
svn_client_import (svn_client_commit_info_t **commit_info,
                   const svn_delta_editor_t *before_editor,
                   void *before_edit_baton,
                   const svn_delta_editor_t *after_editor,
                   void *after_edit_baton,
                   svn_client_auth_baton_t *auth_baton,
                   svn_stringbuf_t *path,
                   svn_stringbuf_t *url,
                   svn_stringbuf_t *new_entry,
                   svn_client_get_commit_log_t log_msg_func,
                   void *log_msg_baton,
                   svn_stringbuf_t *xml_dst,
                   svn_revnum_t revision,
                   apr_pool_t *pool)
{
  apr_status_t apr_err;
  svn_error_t *err;
  svn_stringbuf_t *log_msg;
  const svn_delta_editor_t *editor;
  void *edit_baton;
  void *ra_baton, *session;
  svn_ra_plugin_t *ra_lib;
  svn_revnum_t committed_rev = SVN_INVALID_REVNUM;
  const char *committed_date = NULL;
  const char *committed_author = NULL;
  apr_file_t *xml_hnd;
  svn_boolean_t use_xml = (xml_dst && xml_dst->data) ? TRUE : FALSE;

  /* Sanity check: NEW_ENTRY can be null or non-empty, but it can't be
     empty. */
  if (new_entry && (strcmp (new_entry->data, "") == 0))
    return svn_error_create (SVN_ERR_FS_PATH_SYNTAX, 0, NULL, pool,
                             "empty string is an invalid entry name");

  /* The repository doesn't know about the reserved. */
  if (new_entry && strcmp (new_entry->data, SVN_WC_ADM_DIR_NAME) == 0)
    return svn_error_createf
      (SVN_ERR_CL_ADM_DIR_RESERVED, 0, NULL, pool,
       "the name \"%s\" is reserved and cannot be imported",
       SVN_WC_ADM_DIR_NAME);

  /* Create a new commit item and add it to the array. */
  if (log_msg_func)
    {
      svn_client_commit_item_t *item;
      apr_array_header_t *commit_items 
        = apr_array_make (pool, 1, sizeof (item));
      
      item = apr_pcalloc (pool, sizeof (*item));
      item->path = svn_stringbuf_dup (path, pool);
      item->state_flags = SVN_CLIENT_COMMIT_ITEM_ADD;
      (*((svn_client_commit_item_t **) apr_array_push (commit_items))) 
        = item;
      
      SVN_ERR ((*log_msg_func) (&log_msg, commit_items, log_msg_baton, pool));
      if (! log_msg)
        return SVN_NO_ERROR;
    }
  else
    log_msg = svn_stringbuf_create ("", pool);

  /* If we're importing to XML ... */
  if (use_xml)
    SVN_ERR (get_xml_editor (&xml_hnd, &editor, &edit_baton, 
                             xml_dst->data, pool));

  /* Else we're importing to an RA layer. */
  else  
    SVN_ERR (get_ra_editor (&ra_baton, &session, &ra_lib, 
                            &editor, &edit_baton, auth_baton, url, path,
                            log_msg, NULL, &committed_rev, &committed_date,
                            &committed_author, FALSE, pool));

  /* Wrap the resulting editor with BEFORE and AFTER editors. */
  svn_delta_wrap_editor (&editor, &edit_baton,
                         before_editor, before_edit_baton,
                         editor, edit_baton, 
                         after_editor, after_edit_baton, pool);

  /* If an error occured during the commit, abort the edit and return
     the error.  We don't even care if the abort itself fails.  */
  if ((err = import (path, new_entry, editor, edit_baton, pool)))
    {
      editor->abort_edit (edit_baton);
      return err;
    }

  /* Finish the import. */
  if (use_xml)
    {
      /* If we were committing into XML, close the xml file. */      
      if ((apr_err = apr_file_close (xml_hnd)))
        return svn_error_createf (apr_err, 0, NULL, pool,
                                  "error closing %s", xml_dst->data);
      
      /* Use REVISION for COMMITTED_REV. */
      committed_rev = revision;
    }
  else  
    {
      /* We were committing to RA, so close the session. */
      SVN_ERR (ra_lib->close (session));
    }

  /* Finally, fill in the commit_info structure. */
  *commit_info = svn_client__make_commit_info (committed_rev,
                                               committed_author,
                                               committed_date,
                                               pool);
  return SVN_NO_ERROR;
}


static svn_error_t *
unlock_dirs (apr_hash_t *locked_dirs,
             apr_pool_t *pool)
{
  apr_hash_index_t *hi;

  /* Split if there's nothing to be done. */
  if (! locked_dirs)
    return SVN_NO_ERROR;

  /* Clean up any locks. */
  for (hi = apr_hash_first (pool, locked_dirs); hi; hi = apr_hash_next (hi))
    {
      const void *key;
      apr_ssize_t keylen;
      void *val;
      svn_stringbuf_t *strkey;

      apr_hash_this (hi, &key, &keylen, &val);
      strkey = svn_stringbuf_ncreate ((const char *)key, keylen, pool);
      SVN_ERR (svn_wc_unlock (strkey, pool));
    }

  return SVN_NO_ERROR;
}  


static svn_error_t *
remove_tmpfiles (apr_hash_t *tempfiles,
                 apr_pool_t *pool)
{
  apr_hash_index_t *hi;

  /* Split if there's nothing to be done. */
  if (! tempfiles)
    return SVN_NO_ERROR;

  /* Clean up any tempfiles. */
  for (hi = apr_hash_first (pool, tempfiles); hi; hi = apr_hash_next (hi))
    {
      const void *key;
      apr_ssize_t keylen;
      void *val;
      svn_node_kind_t kind;

      apr_hash_this (hi, &key, &keylen, &val);
      SVN_ERR (svn_io_check_path ((const char *)key, &kind, pool));
      if (kind == svn_node_file)
        SVN_ERR (svn_io_remove_file ((const char *)key, pool));
    }

  return SVN_NO_ERROR;
}



static svn_error_t *
reconcile_errors (svn_error_t *commit_err,
                  svn_error_t *unlock_err,
                  svn_error_t *bump_err,
                  svn_error_t *cleanup_err,
                  apr_pool_t *pool)
{
  svn_error_t *err;

  /* Early release (for good behavior). */
  if (! (commit_err || unlock_err || bump_err || cleanup_err))
    return SVN_NO_ERROR;

  /* If there was a commit error, start off our error chain with
     that. */
  if (commit_err)
    {
      commit_err = svn_error_quick_wrap 
        (commit_err, "Commit failed (details follow):");
      err = commit_err;
    }

  /* Else, create a new "general" error that will head off the errors
     that follow. */
  else
    err = svn_error_create (SVN_ERR_GENERAL, 0, NULL, pool,
                            "Commit succeeded, but other errors follow:");

  /* If there was an unlock error... */
  if (unlock_err)
    {
      /* Wrap the error with some headers. */
      unlock_err = svn_error_quick_wrap 
        (unlock_err, "Error unlocking locked dirs (details follow):");

      /* Append this error to the chain. */
      svn_error_compose (err, unlock_err);
    }

  /* If there was a bumping error... */
  if (bump_err)
    {
      /* Wrap the error with some headers. */
      bump_err = svn_error_quick_wrap 
        (bump_err, "Error bumping revisions post-commit (details follow):");

      /* Append this error to the chain. */
      svn_error_compose (err, bump_err);
    }

  /* If there was a cleanup error... */
  if (cleanup_err)
    {
      /* Wrap the error with some headers. */
      cleanup_err = svn_error_quick_wrap 
        (cleanup_err, "Error in post-commit clean-up (details follow):");

      /* Append this error to the chain. */
      svn_error_compose (err, cleanup_err);
    }

  return err;
}


svn_error_t *
svn_client_commit (svn_client_commit_info_t **commit_info,
                   const svn_delta_editor_t *before_editor,
                   void *before_edit_baton,
                   const svn_delta_editor_t *after_editor,
                   void *after_edit_baton,
                   svn_wc_notify_func_t notify_func,
                   void *notify_baton,
                   svn_client_auth_baton_t *auth_baton,
                   const apr_array_header_t *targets,
                   svn_client_get_commit_log_t log_msg_func,
                   void *log_msg_baton,
                   svn_stringbuf_t *xml_dst,
                   svn_revnum_t revision,
                   apr_pool_t *pool)
{
  const svn_delta_editor_t *editor;
  void *edit_baton;
  void *ra_baton, *session;
  svn_stringbuf_t *log_msg;
  svn_revnum_t committed_rev = SVN_INVALID_REVNUM;
  const char *committed_date = NULL;
  const char *committed_author = NULL;
  svn_ra_plugin_t *ra_lib;
  svn_stringbuf_t *base_dir, *base_url;
  apr_array_header_t *rel_targets;
  apr_hash_t *committables, *locked_dirs, *tempfiles = NULL;
  apr_array_header_t *commit_items;
  apr_status_t apr_err = 0;
  apr_file_t *xml_hnd = NULL;
  svn_error_t *cmt_err = NULL, *unlock_err = NULL;
  svn_error_t *bump_err = NULL, *cleanup_err = NULL;
  svn_boolean_t use_xml = (xml_dst && xml_dst->data) ? TRUE : FALSE;
  svn_boolean_t commit_in_progress = FALSE;
  svn_stringbuf_t *display_dir = svn_stringbuf_create (".", pool);
  int i;

  /* Condense the target list. */
  SVN_ERR (svn_path_condense_targets (&base_dir, &rel_targets, targets, pool));

  /* If we calculated only a base_dir and no relative targets, this
     must mean that we are being asked to commit a single directory.
     In order to do this properly, we need to anchor our commit up one
     directory level, so long as our anchor is still a versioned
     directory. */
  if ((! rel_targets) || (! rel_targets->nelts))
    {
      svn_stringbuf_t *parent_dir, *name;

      SVN_ERR (svn_wc_get_actual_target (base_dir, &parent_dir, &name, pool));
      if (name)
        {
          /* Our new "grandfather directory" is the parent directory
             of the former one. */
          svn_stringbuf_set (base_dir, parent_dir->data);

          /* Make the array if it wasn't already created. */
          if (! rel_targets)
            rel_targets = apr_array_make (pool, targets->nelts, sizeof (name));

          /* Now, push this name as a relative path to our new
             base directory. */
          (*((svn_stringbuf_t **)apr_array_push (rel_targets))) = name;
        }
    }

  /* Crawl the working copy for commit items. */
  if ((cmt_err = svn_client__harvest_committables (&committables, 
                                                   &locked_dirs,
                                                   base_dir,
                                                   rel_targets, 
                                                   pool)))
    goto cleanup;

  /* ### todo: Currently there should be only one hash entry, which
     has a hacked name until we have the entries files storing
     canonical repository URLs.  Then, the hacked name can go away
     and be replaced with a canonical repos URL, and from there we
     are poised to started handling nested working copies. */
  if (! ((commit_items = apr_hash_get (committables, 
                                       SVN_CLIENT__SINGLE_REPOS_NAME, 
                                       APR_HASH_KEY_STRING))))
    goto cleanup;

  /* Go get a log message.  If an error occurs, or no log message is
     specified, abort the operation. */
  if (log_msg_func)
    {
      cmt_err = (*log_msg_func)(&log_msg, commit_items, log_msg_baton, pool);
      if (cmt_err || (! log_msg))
        goto cleanup;
    }
  else
    log_msg = svn_stringbuf_create ("", pool);

  /* Sort and condense our COMMIT_ITEMS. */
  if ((cmt_err = svn_client__condense_commit_items (&base_url, 
                                                    commit_items, 
                                                    pool)))
    goto cleanup;

  /* If we're committing to XML ... */
  if (use_xml)
    {
      if ((cmt_err = get_xml_editor (&xml_hnd, &editor, &edit_baton, 
                                     xml_dst->data, pool)))
        goto cleanup;

      /* Make a note that we have a commit-in-progress. */
      commit_in_progress = TRUE;
    }

  /* Else we're commit to RA */
  else
    {
      svn_revnum_t head = SVN_INVALID_REVNUM;

      if ((cmt_err = get_ra_editor (&ra_baton, &session, &ra_lib, 
                                    &editor, &edit_baton, auth_baton,
                                    base_url, base_dir, log_msg,
                                    commit_items, &committed_rev, 
                                    &committed_date, &committed_author, 
                                    TRUE, pool)))
        goto cleanup;

      /* Make a note that we have a commit-in-progress. */
      commit_in_progress = TRUE;

      /* ### Temporary: If we have any non-added directories with
         property mods, and we're not committing to an XML file, make
         sure those directories are up-to-date.  Someday this should
         just be protected against by the server.  */
      for (i = 0; i < commit_items->nelts; i++)
        {
          svn_client_commit_item_t *item
            = ((svn_client_commit_item_t **) commit_items->elts)[i];
          if ((item->kind == svn_node_dir)
              && (item->state_flags & SVN_CLIENT_COMMIT_ITEM_PROP_MODS)
              && (! (item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)))
            {
              if (! SVN_IS_VALID_REVNUM (head))
                {
                  if ((cmt_err = ra_lib->get_latest_revnum (session, &head)))
                    goto cleanup;
                }

              if (item->revision != head)
                {             
                  cmt_err = svn_error_createf 
                    (SVN_ERR_WC_NOT_UP_TO_DATE, 0, NULL, pool,
                     "Cannot commit propchanges for directory '%s'",
                     item->path->data);
                  goto cleanup;
                }
            }
        }
    }

  /* Wrap the resulting editor with BEFORE and AFTER editors. */
  svn_delta_wrap_editor (&editor, &edit_baton,
                         before_editor, before_edit_baton,
                         editor, edit_baton, 
                         after_editor, after_edit_baton, pool);


  /* Calculate a display_dir. */
  if ((cmt_err = svn_path_get_absolute (&display_dir, display_dir, pool)))
    goto cleanup;

  /* Perform the commit. */
  cmt_err = svn_client__do_commit (base_url, commit_items, editor, edit_baton, 
                                   notify_func, notify_baton, display_dir,
                                   &tempfiles, pool);

  /* Make a note that our commit is finished. */
  commit_in_progress = FALSE;

  /* Unlock the locked directories. */
  if (! ((unlock_err = unlock_dirs (locked_dirs, pool))))
    locked_dirs = NULL;
  
  /* Bump the revision if the commit went well. */
  if (! cmt_err)
    {
      if (use_xml)
        committed_rev = revision;

      for (i = 0; i < commit_items->nelts; i++)
        {
          svn_client_commit_item_t *item
            = ((svn_client_commit_item_t **) commit_items->elts)[i];
          svn_boolean_t recurse = FALSE;
          
          if ((item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD) 
              && (item->kind == svn_node_dir)
              && (item->copyfrom_url))
            recurse = TRUE;

          if ((bump_err = svn_wc_process_committed (item->path, recurse,
                                                    committed_rev, 
                                                    committed_date,
                                                    committed_author, pool)))
            break;
        }
    }

  /* If we were committing into XML, close the xml file. */      
  if (use_xml)
    {
      if ((apr_err = apr_file_close (xml_hnd)))
        {
          cleanup_err = svn_error_createf (apr_err, 0, NULL, pool,
                                           "error closing %s", xml_dst->data);
          goto cleanup;
        }

      /* Use REVISION for COMMITTED_REV. */
      committed_rev = revision;
    }
  else  
    {
      /* We were committing to RA, so close the session. */
      if ((cleanup_err = ra_lib->close (session)))
        goto cleanup;
    }

  /* Sleep for one second to ensure timestamp integrity. */
  apr_sleep (APR_USEC_PER_SEC * 1);

 cleanup:
  /* Abort the commit if it is still in progress. */
  if (commit_in_progress)
    editor->abort_edit (edit_baton); /* ignore return value */

  /* Unlock any remaining locked dirs. */
  if (locked_dirs)
    unlock_err = unlock_dirs (locked_dirs, pool);

  /* Remove any outstanding temporary text-base files. */
  cleanup_err = remove_tmpfiles (tempfiles, pool);

  /* Fill in the commit_info structure */
  *commit_info = svn_client__make_commit_info (committed_rev, 
                                               committed_author, 
                                               committed_date, pool);

  return reconcile_errors (cmt_err, unlock_err, bump_err, cleanup_err, pool);
}




/* 
 * local variables:
 * eval: (load-file "../../tools/dev/svn-dev.el")
 * end: */
