You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2015/06/23 14:55:47 UTC

svn commit: r1687045 [10/31] - in /subversion/branches/svn-mergeinfo-normalizer: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ doc/ subversion/bindings/javahl/ subversion/bindings/javahl/native/ subversion/bindings/javahl/nativ...

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra/ra_loader.c?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra/ra_loader.c Tue Jun 23 12:55:43 2015
@@ -143,7 +143,7 @@ load_ra_module(svn_ra__init_func_t *func
     const char *compat_funcname;
     apr_status_t status;
 
-    libname = apr_psprintf(pool, "libsvn_ra_%s-%d.so.%d",
+    libname = apr_psprintf(pool, "libsvn_ra_%s-" SVN_DSO_SUFFIX_FMT,
                            ra_name, SVN_VER_MAJOR, SVN_SOVERSION);
     funcname = apr_psprintf(pool, "svn_ra_%s__init", ra_name);
     compat_funcname = apr_psprintf(pool, "svn_ra_%s_init", ra_name);
@@ -266,6 +266,7 @@ svn_error_t *svn_ra_open4(svn_ra_session
                           apr_pool_t *pool)
 {
   apr_pool_t *sesspool = svn_pool_create(pool);
+  apr_pool_t *scratch_pool = svn_pool_create(sesspool);
   svn_ra_session_t *session;
   const struct ra_lib_defn *defn;
   const svn_ra__vtable_t *vtable = NULL;
@@ -275,6 +276,7 @@ svn_error_t *svn_ra_open4(svn_ra_session
 #ifdef CHOOSABLE_DAV_MODULE
   const char *http_library = DEFAULT_HTTP_LIBRARY;
 #endif
+  svn_auth_baton_t *auth_baton;
 
   /* Initialize the return variable. */
   *session_p = NULL;
@@ -290,8 +292,12 @@ svn_error_t *svn_ra_open4(svn_ra_session
                              repos_URL);
 
   if (callbacks->auth_baton)
-    SVN_ERR(svn_auth__apply_config_for_server(callbacks->auth_baton, config,
-                                              repos_URI.hostname, sesspool));
+    SVN_ERR(svn_auth__make_session_auth(&auth_baton,
+                                        callbacks->auth_baton, config,
+                                        repos_URI.hostname,
+                                        sesspool, scratch_pool));
+  else
+    auth_baton = NULL;
 
 #ifdef CHOOSABLE_DAV_MODULE
   if (config)
@@ -344,16 +350,16 @@ svn_error_t *svn_ra_open4(svn_ra_session
 
           if (! initfunc)
             SVN_ERR(load_ra_module(&initfunc, NULL, defn->ra_name,
-                                   sesspool));
+                                   scratch_pool));
           if (! initfunc)
             /* Library not found. */
             continue;
 
-          SVN_ERR(initfunc(svn_ra_version(), &vtable, sesspool));
+          SVN_ERR(initfunc(svn_ra_version(), &vtable, scratch_pool));
 
           SVN_ERR(check_ra_version(vtable->get_version(), scheme));
 
-          if (! has_scheme_of(vtable->get_schemes(sesspool), repos_URL))
+          if (! has_scheme_of(vtable->get_schemes(scratch_pool), repos_URL))
             /* Library doesn't support the scheme at runtime. */
             continue;
 
@@ -377,10 +383,12 @@ svn_error_t *svn_ra_open4(svn_ra_session
   /* Ask the library to open the session. */
   err = vtable->open_session(session, corrected_url_p,
                              repos_URL,
-                             callbacks, callback_baton, config, sesspool);
+                             callbacks, callback_baton, auth_baton,
+                             config, sesspool, scratch_pool);
 
   if (err)
     {
+      svn_pool_destroy(sesspool); /* Includes scratch_pool */
       if (err->apr_err == SVN_ERR_RA_SESSION_URL_MISMATCH)
         return svn_error_trace(err);
 
@@ -398,7 +406,7 @@ svn_error_t *svn_ra_open4(svn_ra_session
     {
       /* *session_p = NULL; */
       *corrected_url_p = apr_pstrdup(pool, *corrected_url_p);
-      svn_pool_destroy(sesspool);
+      svn_pool_destroy(sesspool); /* Includes scratch_pool */
       return SVN_NO_ERROR;
     }
 
@@ -412,7 +420,7 @@ svn_error_t *svn_ra_open4(svn_ra_session
         {
           /* Duplicate the uuid as it is allocated in sesspool */
           repository_uuid = apr_pstrdup(pool, repository_uuid);
-          svn_pool_destroy(sesspool);
+          svn_pool_destroy(sesspool); /* includes scratch_pool */
           return svn_error_createf(SVN_ERR_RA_UUID_MISMATCH, NULL,
                                    _("Repository UUID '%s' doesn't match "
                                      "expected UUID '%s'"),
@@ -420,6 +428,7 @@ svn_error_t *svn_ra_open4(svn_ra_session
         }
     }
 
+  svn_pool_destroy(scratch_pool);
   *session_p = session;
   return SVN_NO_ERROR;
 }
@@ -944,6 +953,7 @@ svn_error_t *svn_ra_get_locations(svn_ra
 {
   svn_error_t *err;
 
+  SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(peg_revision));
   SVN_ERR_ASSERT(svn_relpath_is_canonical(path));
   err = session->vtable->get_locations(session, locations, path,
                                        peg_revision, location_revisions, pool);
@@ -1111,6 +1121,8 @@ svn_error_t *svn_ra_replay(svn_ra_sessio
                            void *edit_baton,
                            apr_pool_t *pool)
 {
+  SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(revision)
+                 && SVN_IS_VALID_REVNUM(low_water_mark));
   return session->vtable->replay(session, revision, low_water_mark,
                                  text_deltas, editor, edit_baton, pool);
 }
@@ -1178,7 +1190,14 @@ svn_ra_replay_range(svn_ra_session_t *se
                     void *replay_baton,
                     apr_pool_t *pool)
 {
-  svn_error_t *err =
+  svn_error_t *err;
+
+  SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(start_revision)
+                 && SVN_IS_VALID_REVNUM(end_revision)
+                 && start_revision <= end_revision
+                 && SVN_IS_VALID_REVNUM(low_water_mark));
+
+  err =
     session->vtable->replay_range(session, start_revision, end_revision,
                                   low_water_mark, text_deltas,
                                   revstart_func, revfinish_func,

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra/ra_loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra/ra_loader.h?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra/ra_loader.h (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra/ra_loader.h Tue Jun 23 12:55:43 2015
@@ -61,8 +61,10 @@ typedef struct svn_ra__vtable_t {
                                const char *session_URL,
                                const svn_ra_callbacks2_t *callbacks,
                                void *callback_baton,
+                               svn_auth_baton_t *auth_baton,
                                apr_hash_t *config,
-                               apr_pool_t *pool);
+                               apr_pool_t *result_pool,
+                               apr_pool_t *scratch_pool);
   /* Backs svn_ra_dup_session */
   svn_error_t * (*dup_session)(svn_ra_session_t *new_session,
                                svn_ra_session_t *old_session,

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra/wrapper_template.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra/wrapper_template.h?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra/wrapper_template.h (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra/wrapper_template.h Tue Jun 23 12:55:43 2015
@@ -91,7 +91,9 @@ static svn_error_t *compat_open(void **s
   callbacks2->progress_baton = NULL;
 
   SVN_ERR(VTBL.open_session(sess, &session_url, repos_URL,
-                            callbacks2, callback_baton, config, sesspool));
+                            callbacks2, callback_baton,
+                            callbacks ? callbacks->auth_baton : NULL,
+                            config, sesspool, sesspool));
 
   if (strcmp(repos_URL, session_url) != 0)
     {

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_local/ra_local.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_local/ra_local.h?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_local/ra_local.h (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_local/ra_local.h Tue Jun 23 12:55:43 2015
@@ -63,6 +63,9 @@ typedef struct svn_ra_local__session_bat
   const svn_ra_callbacks2_t *callbacks;
   void *callback_baton;
 
+  /* Slave auth baton */
+  svn_auth_baton_t *auth_baton;
+
   const char *useragent;
 } svn_ra_local__session_baton_t;
 

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_local/ra_plugin.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_local/ra_plugin.c?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_local/ra_plugin.c (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_local/ra_plugin.c Tue Jun 23 12:55:43 2015
@@ -41,6 +41,7 @@
 #include "private/svn_repos_private.h"
 #include "private/svn_fspath.h"
 #include "private/svn_atomic.h"
+#include "private/svn_subr_private.h"
 
 #define APR_WANT_STRFUNC
 #include <apr_want.h>
@@ -86,7 +87,7 @@ get_username(svn_ra_session_t *session,
     {
       /* Get a username somehow, so we have some svn:author property to
          attach to a commit. */
-      if (sess->callbacks->auth_baton)
+      if (sess->auth_baton)
         {
           void *creds;
           svn_auth_cred_username_t *username_creds;
@@ -95,7 +96,7 @@ get_username(svn_ra_session_t *session,
           SVN_ERR(svn_auth_first_credentials(&creds, &iterstate,
                                              SVN_AUTH_CRED_USERNAME,
                                              sess->uuid, /* realmstring */
-                                             sess->callbacks->auth_baton,
+                                             sess->auth_baton,
                                              scratch_pool));
 
           /* No point in calling next_creds(), since that assumes that the
@@ -551,13 +552,16 @@ svn_ra_local__open(svn_ra_session_t *ses
                    const char *repos_URL,
                    const svn_ra_callbacks2_t *callbacks,
                    void *callback_baton,
+                   svn_auth_baton_t *auth_baton,
                    apr_hash_t *config,
-                   apr_pool_t *pool)
+                   apr_pool_t *result_pool,
+                   apr_pool_t *scratch_pool)
 {
   const char *client_string;
   svn_ra_local__session_baton_t *sess;
   const char *fs_path;
   static volatile svn_atomic_t cache_init_state = 0;
+  apr_pool_t *pool = result_pool;
 
   /* Initialise the FSFS memory cache size.  We can only do this once
      so one CONFIG will win the race and all others will be ignored
@@ -572,6 +576,7 @@ svn_ra_local__open(svn_ra_session_t *ses
   sess = apr_pcalloc(pool, sizeof(*sess));
   sess->callbacks = callbacks;
   sess->callback_baton = callback_baton;
+  sess->auth_baton = auth_baton;
 
   /* Look through the URL, figure out which part points to the
      repository, and which part is the path *within* the
@@ -1305,7 +1310,6 @@ svn_ra_local__get_dir(svn_ra_session_t *
   apr_hash_t *entries;
   apr_hash_index_t *hi;
   svn_ra_local__session_baton_t *sess = session->priv;
-  apr_pool_t *subpool;
   const char *abs_path = svn_fspath__join(sess->fs_path->data, path, pool);
 
   /* Open the revision's root. */
@@ -1321,29 +1325,28 @@ svn_ra_local__get_dir(svn_ra_session_t *
 
   if (dirents)
     {
+      apr_pool_t *iterpool = svn_pool_create(pool);
       /* Get the dir's entries. */
       SVN_ERR(svn_fs_dir_entries(&entries, root, abs_path, pool));
 
       /* Loop over the fs dirents, and build a hash of general
          svn_dirent_t's. */
       *dirents = apr_hash_make(pool);
-      subpool = svn_pool_create(pool);
       for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi))
         {
           const void *key;
           void *val;
-          apr_hash_t *prophash;
           const char *datestring, *entryname, *fullpath;
           svn_fs_dirent_t *fs_entry;
           svn_dirent_t *entry = svn_dirent_create(pool);
 
-          svn_pool_clear(subpool);
+          svn_pool_clear(iterpool);
 
           apr_hash_this(hi, &key, NULL, &val);
           entryname = (const char *) key;
           fs_entry = (svn_fs_dirent_t *) val;
 
-          fullpath = svn_dirent_join(abs_path, entryname, subpool);
+          fullpath = svn_dirent_join(abs_path, entryname, iterpool);
 
           if (dirent_fields & SVN_DIRENT_KIND)
             {
@@ -1358,15 +1361,15 @@ svn_ra_local__get_dir(svn_ra_session_t *
                 entry->size = 0;
               else
                 SVN_ERR(svn_fs_file_length(&(entry->size), root,
-                                           fullpath, subpool));
+                                           fullpath, iterpool));
             }
 
           if (dirent_fields & SVN_DIRENT_HAS_PROPS)
             {
               /* has_props? */
-              SVN_ERR(svn_fs_node_proplist(&prophash, root, fullpath,
-                                           subpool));
-              entry->has_props = (apr_hash_count(prophash) != 0);
+              SVN_ERR(svn_fs_node_has_props(&entry->has_props,
+                                            root, fullpath,
+                                            iterpool));
             }
 
           if ((dirent_fields & SVN_DIRENT_TIME)
@@ -1377,7 +1380,7 @@ svn_ra_local__get_dir(svn_ra_session_t *
               SVN_ERR(svn_repos_get_committed_info(&(entry->created_rev),
                                                    &datestring,
                                                    &(entry->last_author),
-                                                   root, fullpath, subpool));
+                                                   root, fullpath, iterpool));
               if (datestring)
                 SVN_ERR(svn_time_from_cstring(&(entry->time), datestring,
                                               pool));
@@ -1388,7 +1391,7 @@ svn_ra_local__get_dir(svn_ra_session_t *
           /* Store. */
           svn_hash_sets(*dirents, entryname, entry);
         }
-      svn_pool_destroy(subpool);
+      svn_pool_destroy(iterpool);
     }
 
   /* Handle props if requested. */
@@ -1692,23 +1695,13 @@ svn_ra_local__get_inherited_props(svn_ra
                                   apr_pool_t *scratch_pool)
 {
   svn_fs_root_t *root;
-  svn_revnum_t youngest_rev;
   svn_ra_local__session_baton_t *sess = session->priv;
   const char *abs_path = svn_fspath__join(sess->fs_path->data, path,
                                           scratch_pool);
   svn_node_kind_t node_kind;
 
   /* Open the revision's root. */
-  if (! SVN_IS_VALID_REVNUM(revision))
-    {
-      SVN_ERR(svn_fs_youngest_rev(&youngest_rev, sess->fs, scratch_pool));
-      SVN_ERR(svn_fs_revision_root(&root, sess->fs, youngest_rev,
-                                   scratch_pool));
-    }
-  else
-    {
-      SVN_ERR(svn_fs_revision_root(&root, sess->fs, revision, scratch_pool));
-    }
+  SVN_ERR(svn_fs_revision_root(&root, sess->fs, revision, scratch_pool));
 
   SVN_ERR(svn_fs_check_path(&node_kind, root, abs_path, scratch_pool));
   if (node_kind == svn_node_none)
@@ -1876,8 +1869,8 @@ svn_ra_local__init(const svn_version_t *
   SVN_ERR(svn_ver_check_list2(ra_local_version(), checklist, svn_ver_equal));
 
 #ifndef SVN_LIBSVN_CLIENT_LINKS_RA_LOCAL
-  /* This assumes that POOL was the pool used to load the dso. */
-  SVN_ERR(svn_fs_initialize(pool));
+  /* This means the library was loaded as a DSO, so use the DSO pool. */
+  SVN_ERR(svn_fs_initialize(svn_dso__pool()));
 #endif
 
   *vtable = &ra_local_vtable;

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/commit.c?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/commit.c Tue Jun 23 12:55:43 2015
@@ -71,6 +71,7 @@ typedef struct commit_context_t {
   const char *checked_in_url;    /* checked-in root to base CHECKOUTs from */
   const char *vcc_url;           /* vcc url */
 
+  int open_batons;               /* Number of open batons */
 } commit_context_t;
 
 #define USING_HTTPV2_COMMIT_SUPPORT(commit_ctx) ((commit_ctx)->txn_url != NULL)
@@ -101,6 +102,8 @@ typedef struct delete_context_t {
   svn_revnum_t revision;
 
   commit_context_t *commit_ctx;
+
+  svn_boolean_t non_recursive_if; /* Only create a non-recursive If header */
 } delete_context_t;
 
 /* Represents a directory. */
@@ -115,9 +118,6 @@ typedef struct dir_context_t {
      HTTP v2, for PROPPATCH in HTTP v2).  */
   const char *url;
 
-  /* How many pending changes we have left in this directory. */
-  unsigned int ref_count;
-
   /* Is this directory being added?  (Otherwise, just opened.) */
   svn_boolean_t added;
 
@@ -1101,8 +1101,15 @@ setup_delete_headers(serf_bucket_t *head
   serf_bucket_headers_set(headers, SVN_DAV_VERSION_NAME_HEADER,
                           apr_ltoa(pool, del->revision));
 
-  SVN_ERR(setup_if_header_recursive(&added, headers, del->commit_ctx,
-                                    del->relpath, pool));
+  if (! del->non_recursive_if)
+    SVN_ERR(setup_if_header_recursive(&added, headers, del->commit_ctx,
+                                      del->relpath, pool));
+  else
+    {
+      SVN_ERR(maybe_set_lock_token_header(headers, del->commit_ctx,
+                                          del->relpath, pool));
+      added = TRUE;
+    }
 
   if (added && del->commit_ctx->keep_locks)
     serf_bucket_headers_setn(headers, SVN_DAV_OPTIONS_HEADER,
@@ -1249,6 +1256,8 @@ open_root(void *edit_baton,
   const char *proppatch_target = NULL;
   apr_pool_t *scratch_pool = svn_pool_create(dir_pool);
 
+  commit_ctx->open_batons++;
+
   if (SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(commit_ctx->session))
     {
       post_response_ctx_t *prc;
@@ -1402,6 +1411,28 @@ open_root(void *edit_baton,
   return SVN_NO_ERROR;
 }
 
+/* Implements svn_ra_serf__request_body_delegate_t */
+static svn_error_t *
+create_delete_body(serf_bucket_t **body_bkt,
+                   void *baton,
+                   serf_bucket_alloc_t *alloc,
+                   apr_pool_t *pool /* request pool */,
+                   apr_pool_t *scratch_pool)
+{
+  delete_context_t *ctx = baton;
+  serf_bucket_t *body;
+
+  body = serf_bucket_aggregate_create(alloc);
+
+  svn_ra_serf__add_xml_header_buckets(body, alloc);
+
+  svn_ra_serf__merge_lock_token_list(ctx->commit_ctx->lock_tokens,
+                                     ctx->relpath, body, alloc, pool);
+
+  *body_bkt = body;
+  return SVN_NO_ERROR;
+}
+
 static svn_error_t *
 delete_entry(const char *path,
              svn_revnum_t revision,
@@ -1412,6 +1443,7 @@ delete_entry(const char *path,
   delete_context_t *delete_ctx;
   svn_ra_serf__handler_t *handler;
   const char *delete_target;
+  svn_error_t *err;
 
   if (USING_HTTPV2_COMMIT_SUPPORT(dir->commit_ctx))
     {
@@ -1446,7 +1478,23 @@ delete_entry(const char *path,
   handler->method = "DELETE";
   handler->path = delete_target;
 
-  SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
+  err = svn_ra_serf__context_run_one(handler, pool);
+  if (err && err->apr_err == SVN_ERR_RA_DAV_REQUEST_FAILED
+      && handler->sline.code == 400)
+    {
+      svn_error_clear(err);
+
+      /* Try again with non-standard body to overcome Apache Httpd
+         header limit */
+      delete_ctx->non_recursive_if = TRUE;
+      handler->body_type = "text/xml";
+      handler->body_delegate = create_delete_body;
+      handler->body_delegate_baton = delete_ctx;
+
+      SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
+    }
+  else
+    SVN_ERR(err);
 
   /* 204 No Content: item successfully deleted */
   if (handler->sline.code != 204)
@@ -1485,6 +1533,8 @@ add_directory(const char *path,
   dir->name = svn_relpath_basename(dir->relpath, NULL);
   dir->prop_changes = apr_hash_make(dir->pool);
 
+  dir->commit_ctx->open_batons++;
+
   if (USING_HTTPV2_COMMIT_SUPPORT(dir->commit_ctx))
     {
       dir->url = svn_path_url_add_component2(parent->commit_ctx->txn_root_url,
@@ -1539,7 +1589,9 @@ add_directory(const char *path,
       handler->header_delegate = setup_copy_dir_headers;
       handler->header_delegate_baton = dir;
     }
-
+  /* We have the same problem as with DELETE here: if there are too many
+     locks, the request fails. But in this case there is no way to retry
+     with a non-standard request. #### How to fix? */
   SVN_ERR(svn_ra_serf__context_run_one(handler, dir->pool));
 
   if (handler->sline.code != 201)
@@ -1573,6 +1625,8 @@ open_directory(const char *path,
   dir->name = svn_relpath_basename(dir->relpath, NULL);
   dir->prop_changes = apr_hash_make(dir->pool);
 
+  dir->commit_ctx->open_batons++;
+
   if (USING_HTTPV2_COMMIT_SUPPORT(dir->commit_ctx))
     {
       dir->url = svn_path_url_add_component2(parent->commit_ctx->txn_root_url,
@@ -1651,6 +1705,8 @@ close_directory(void *dir_baton,
                                  proppatch_ctx, dir->pool));
     }
 
+  dir->commit_ctx->open_batons--;
+
   return SVN_NO_ERROR;
 }
 
@@ -1670,8 +1726,6 @@ add_file(const char *path,
   new_file = apr_pcalloc(file_pool, sizeof(*new_file));
   new_file->pool = file_pool;
 
-  dir->ref_count++;
-
   new_file->parent_dir = dir;
   new_file->commit_ctx = dir->commit_ctx;
   new_file->relpath = apr_pstrdup(new_file->pool, path);
@@ -1682,6 +1736,8 @@ add_file(const char *path,
   new_file->copy_revision = copy_revision;
   new_file->prop_changes = apr_hash_make(new_file->pool);
 
+  dir->commit_ctx->open_batons++;
+
   /* Ensure that the file doesn't exist by doing a HEAD on the
      resource.  If we're using HTTP v2, we'll just look into the
      transaction root tree for this thing.  */
@@ -1792,8 +1848,6 @@ open_file(const char *path,
   new_file = apr_pcalloc(file_pool, sizeof(*new_file));
   new_file->pool = file_pool;
 
-  parent->ref_count++;
-
   new_file->parent_dir = parent;
   new_file->commit_ctx = parent->commit_ctx;
   new_file->relpath = apr_pstrdup(new_file->pool, path);
@@ -1802,6 +1856,8 @@ open_file(const char *path,
   new_file->base_revision = base_revision;
   new_file->prop_changes = apr_hash_make(new_file->pool);
 
+  parent->commit_ctx->open_batons++;
+
   if (USING_HTTPV2_COMMIT_SUPPORT(parent->commit_ctx))
     {
       new_file->url = svn_path_url_add_component2(parent->commit_ctx->txn_root_url,
@@ -1964,6 +2020,8 @@ close_file(void *file_baton,
                                  proppatch, scratch_pool));
     }
 
+  ctx->commit_ctx->open_batons--;
+
   return SVN_NO_ERROR;
 }
 
@@ -1977,6 +2035,11 @@ close_edit(void *edit_baton,
   const svn_commit_info_t *commit_info;
   svn_error_t *err = NULL;
 
+  if (ctx->open_batons > 0)
+    return svn_error_create(
+              SVN_ERR_FS_INCORRECT_EDITOR_COMPLETION, NULL,
+              _("Closing editor with directories or files open"));
+
   /* MERGE our activity */
   SVN_ERR(svn_ra_serf__run_merge(&commit_info,
                                  ctx->session,

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/get_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/get_file.c?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/get_file.c (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/get_file.c Tue Jun 23 12:55:43 2015
@@ -321,17 +321,19 @@ svn_ra_serf__get_file(svn_ra_session_t *
                       svn_stream_t *stream,
                       svn_revnum_t *fetched_rev,
                       apr_hash_t **props,
-                      apr_pool_t *pool)
+                      apr_pool_t *result_pool)
 {
   svn_ra_serf__session_t *session = ra_session->priv;
   const char *fetch_url;
   const svn_ra_serf__dav_props_t *which_props;
   svn_ra_serf__handler_t *propfind_handler;
+  apr_pool_t *scratch_pool = svn_pool_create(result_pool);
   struct file_prop_baton_t fb;
 
   /* Fetch properties. */
 
-  fetch_url = svn_path_url_add_component2(session->session_url.path, path, pool);
+  fetch_url = svn_path_url_add_component2(session->session_url.path, path,
+                                          scratch_pool);
 
   /* The simple case is if we want HEAD - then a GET on the fetch_url is fine.
    *
@@ -343,7 +345,7 @@ svn_ra_serf__get_file(svn_ra_session_t *
       SVN_ERR(svn_ra_serf__get_stable_url(&fetch_url, fetched_rev,
                                           session,
                                           fetch_url, revision,
-                                          pool, pool));
+                                          scratch_pool, scratch_pool));
       revision = SVN_INVALID_REVNUM;
     }
   /* REVISION is always SVN_INVALID_REVNUM  */
@@ -356,8 +358,8 @@ svn_ra_serf__get_file(svn_ra_session_t *
   else
       which_props = check_path_props;
 
-  fb.result_pool = pool;
-  fb.props = props ? apr_hash_make(pool) : NULL;
+  fb.result_pool = result_pool;
+  fb.props = props ? apr_hash_make(result_pool) : NULL;
   fb.kind = svn_node_unknown;
   fb.sha1_checksum = NULL;
 
@@ -365,9 +367,9 @@ svn_ra_serf__get_file(svn_ra_session_t *
                                                fetch_url, SVN_INVALID_REVNUM,
                                                "0", which_props,
                                                get_file_prop_cb, &fb,
-                                               pool));
+                                               scratch_pool));
 
-  SVN_ERR(svn_ra_serf__context_run_one(propfind_handler, pool));
+  SVN_ERR(svn_ra_serf__context_run_one(propfind_handler, scratch_pool));
 
   /* Verify that resource type is not collection. */
   if (fb.kind != svn_node_file)
@@ -382,7 +384,8 @@ svn_ra_serf__get_file(svn_ra_session_t *
   if (stream)
     {
       svn_boolean_t found;
-      SVN_ERR(try_get_wc_contents(&found, session, fb.sha1_checksum, stream, pool));
+      SVN_ERR(try_get_wc_contents(&found, session, fb.sha1_checksum, stream,
+                                  scratch_pool));
 
       /* No contents found in the WC, let's fetch from server. */
       if (!found)
@@ -391,11 +394,11 @@ svn_ra_serf__get_file(svn_ra_session_t *
           svn_ra_serf__handler_t *handler;
 
           /* Create the fetch context. */
-          stream_ctx = apr_pcalloc(pool, sizeof(*stream_ctx));
+          stream_ctx = apr_pcalloc(scratch_pool, sizeof(*stream_ctx));
           stream_ctx->result_stream = stream;
           stream_ctx->using_compression = session->using_compression;
 
-          handler = svn_ra_serf__create_handler(session, pool);
+          handler = svn_ra_serf__create_handler(session, scratch_pool);
 
           handler->method = "GET";
           handler->path = fetch_url;
@@ -414,12 +417,14 @@ svn_ra_serf__get_file(svn_ra_session_t *
 
           stream_ctx->handler = handler;
 
-          SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
+          SVN_ERR(svn_ra_serf__context_run_one(handler, scratch_pool));
 
           if (handler->sline.code != 200)
             return svn_error_trace(svn_ra_serf__unexpected_status(handler));
         }
     }
 
+  svn_pool_destroy(scratch_pool);
+
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/getlocations.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/getlocations.c?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/getlocations.c (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/getlocations.c Tue Jun 23 12:55:43 2015
@@ -193,9 +193,8 @@ svn_ra_serf__get_locations(svn_ra_sessio
 
   SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
 
-  SVN_ERR(svn_ra_serf__error_on_status(handler->sline,
-                                       handler->path,
-                                       handler->location));
+  if (handler->sline.code != 200)
+    SVN_ERR(svn_ra_serf__unexpected_status(handler));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/getlocationsegments.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/getlocationsegments.c?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/getlocationsegments.c (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/getlocationsegments.c Tue Jun 23 12:55:43 2015
@@ -196,12 +196,8 @@ svn_ra_serf__get_location_segments(svn_r
 
   err = svn_ra_serf__context_run_one(handler, pool);
 
-  if (!err)
-    {
-      err = svn_ra_serf__error_on_status(handler->sline,
-                                         handler->path,
-                                         handler->location);
-    }
+  if (!err && handler->sline.code != 200)
+    err = svn_ra_serf__unexpected_status(handler);
 
   if (err && (err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE))
     return svn_error_create(SVN_ERR_RA_NOT_IMPLEMENTED, err, NULL);

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/lock.c?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/lock.c (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/lock.c Tue Jun 23 12:55:43 2015
@@ -291,6 +291,7 @@ run_locks(svn_ra_serf__session_t *sess,
                                             ctx->handler->sline.reason);
                     break;
 
+                  case 404:
                   case 409:
                   case 500:
                     if (server_err)

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/log.c?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/log.c (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/log.c Tue Jun 23 12:55:43 2015
@@ -272,7 +272,7 @@ log_closed(svn_ra_serf__xml_estate_t *xe
       svn_log_entry_t *log_entry;
       const char *rev_str;
 
-      if (log_ctx->limit && (log_ctx->nest_level == 0)
+      if ((log_ctx->limit > 0) && (log_ctx->nest_level == 0)
           && (++log_ctx->count > log_ctx->limit))
         {
           return SVN_NO_ERROR;
@@ -598,8 +598,8 @@ svn_ra_serf__get_log(svn_ra_session_t *r
 
   SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
 
-  return svn_error_trace(
-              svn_ra_serf__error_on_status(handler->sline,
-                                           req_url,
-                                           handler->location));
+  if (handler->sline.code != 200)
+    SVN_ERR(svn_ra_serf__unexpected_status(handler));
+
+  return SVN_NO_ERROR;
 }

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/merge.c?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/merge.c (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/merge.c Tue Jun 23 12:55:43 2015
@@ -285,12 +285,12 @@ setup_merge_headers(serf_bucket_t *heade
   return SVN_NO_ERROR;
 }
 
-static void
-merge_lock_token_list(apr_hash_t *lock_tokens,
-                      const char *parent,
-                      serf_bucket_t *body,
-                      serf_bucket_alloc_t *alloc,
-                      apr_pool_t *pool)
+void
+svn_ra_serf__merge_lock_token_list(apr_hash_t *lock_tokens,
+                                   const char *parent,
+                                   serf_bucket_t *body,
+                                   serf_bucket_alloc_t *alloc,
+                                   apr_pool_t *pool)
 {
   apr_hash_index_t *hi;
 
@@ -378,7 +378,8 @@ create_merge_body(serf_bucket_t **bkt,
                                      "D:creator-displayname", SVN_VA_NULL);
   svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:prop");
 
-  merge_lock_token_list(ctx->lock_tokens, NULL, body_bkt, alloc, pool);
+  svn_ra_serf__merge_lock_token_list(ctx->lock_tokens, NULL, body_bkt,
+                                     alloc, pool);
 
   svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:merge");
 

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/mergeinfo.c?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/mergeinfo.c (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/mergeinfo.c Tue Jun 23 12:55:43 2015
@@ -228,8 +228,8 @@ svn_ra_serf__get_mergeinfo(svn_ra_sessio
 
   SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
 
-  SVN_ERR(svn_ra_serf__error_on_status(handler->sline, handler->path,
-                                       handler->location));
+  if (handler->sline.code != 200)
+    SVN_ERR(svn_ra_serf__unexpected_status(handler));
 
   if (apr_hash_count(mergeinfo_ctx->result_catalog))
     *catalog = mergeinfo_ctx->result_catalog;

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/ra_serf.h?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/ra_serf.h Tue Jun 23 12:55:43 2015
@@ -154,6 +154,7 @@ struct svn_ra_serf__session_t {
   /* Callback functions to get info from WC */
   const svn_ra_callbacks2_t *wc_callbacks;
   void *wc_callback_baton;
+  svn_auth_baton_t *auth_baton;
 
   /* Callback function to send progress info to the client */
   svn_ra_progress_notify_func_t progress_func;
@@ -1021,6 +1022,13 @@ svn_ra_serf__svnname_from_wirename(const
 
 /** MERGE-related functions **/
 
+void
+svn_ra_serf__merge_lock_token_list(apr_hash_t *lock_tokens,
+                                   const char *parent,
+                                   serf_bucket_t *body,
+                                   serf_bucket_alloc_t *alloc,
+                                   apr_pool_t *pool);
+
 /* Create an MERGE request aimed at the SESSION url, requesting the
    merge of the resource identified by MERGE_RESOURCE_URL.
    LOCK_TOKENS is a hash mapping paths to lock tokens owned by the

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/replay.c?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/replay.c (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/replay.c Tue Jun 23 12:55:43 2015
@@ -427,10 +427,11 @@ replay_closed(svn_ra_serf__xml_estate_t
     {
       struct replay_node_t *node = ctx->current_node;
 
-      if (! node || ! node->file || ! node->stream)
+      if (! node || ! node->file)
         return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);
 
-      SVN_ERR(svn_stream_close(node->stream));
+      if (node->stream)
+        SVN_ERR(svn_stream_close(node->stream));
 
       node->stream = NULL;
     }
@@ -565,10 +566,10 @@ svn_ra_serf__replay(svn_ra_session_t *ra
 
   SVN_ERR(svn_ra_serf__context_run_one(handler, scratch_pool));
 
-  return svn_error_trace(
-              svn_ra_serf__error_on_status(handler->sline,
-                                           handler->path,
-                                           handler->location));
+  if (handler->sline.code != 200)
+    SVN_ERR(svn_ra_serf__unexpected_status(handler));
+
+  return SVN_NO_ERROR;
 }
 
 /* The maximum number of outstanding requests at any time. When this
@@ -646,9 +647,10 @@ svn_ra_serf__replay_range(svn_ra_session
   int active_reports = 0;
   const char *include_path;
   svn_boolean_t done;
+  apr_pool_t *subpool = svn_pool_create(scratch_pool);
 
   SVN_ERR(svn_ra_serf__report_resource(&report_target, session,
-                                       scratch_pool));
+                                       subpool));
 
   /* Prior to 1.8, mod_dav_svn expect to get replay REPORT requests
      aimed at the session URL.  But that's incorrect -- these reports
@@ -671,7 +673,7 @@ svn_ra_serf__replay_range(svn_ra_session
     {
       SVN_ERR(svn_ra_serf__get_relative_path(&include_path,
                                              session->session_url.path,
-                                             session, scratch_pool));
+                                             session, subpool));
     }
   else
     {
@@ -689,7 +691,7 @@ svn_ra_serf__replay_range(svn_ra_session
         {
           struct revision_report_t *rev_ctx;
           svn_ra_serf__handler_t *handler;
-          apr_pool_t *rev_pool = svn_pool_create(scratch_pool);
+          apr_pool_t *rev_pool = svn_pool_create(subpool);
           svn_ra_serf__xml_context_t *xmlctx;
           const char *replay_target;
 
@@ -769,13 +771,23 @@ svn_ra_serf__replay_range(svn_ra_session
 
       /* Run the serf loop. */
       done = FALSE;
-      SVN_ERR(svn_ra_serf__context_run_wait(&done, session, scratch_pool));
+      {
+        svn_error_t *err = svn_ra_serf__context_run_wait(&done, session,
+                                                         subpool);
+
+        if (err)
+          {
+            svn_pool_destroy(subpool); /* Unregister all requests! */
+            return svn_error_trace(err);
+          }
+      }
 
       /* The done handler of reports decrements active_reports when a report
          is done. This same handler reports (fatal) report errors, so we can
          just loop here. */
     }
 
+  svn_pool_destroy(subpool);
   return SVN_NO_ERROR;
 }
 #undef MAX_OUTSTANDING_REQUESTS

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/serf.c?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/serf.c Tue Jun 23 12:55:43 2015
@@ -148,7 +148,8 @@ load_http_auth_types(apr_pool_t *pool, s
 static svn_error_t *
 load_config(svn_ra_serf__session_t *session,
             apr_hash_t *config_hash,
-            apr_pool_t *pool)
+            apr_pool_t *result_pool,
+            apr_pool_t *scratch_pool)
 {
   svn_config_t *config, *config_client;
   const char *server_group;
@@ -180,17 +181,17 @@ load_config(svn_ra_serf__session_t *sess
   svn_config_get(config, &timeout_str, SVN_CONFIG_SECTION_GLOBAL,
                  SVN_CONFIG_OPTION_HTTP_TIMEOUT, NULL);
 
-  if (session->wc_callbacks->auth_baton)
+  if (session->auth_baton)
     {
       if (config_client)
         {
-          svn_auth_set_parameter(session->wc_callbacks->auth_baton,
+          svn_auth_set_parameter(session->auth_baton,
                                  SVN_AUTH_PARAM_CONFIG_CATEGORY_CONFIG,
                                  config_client);
         }
       if (config)
         {
-          svn_auth_set_parameter(session->wc_callbacks->auth_baton,
+          svn_auth_set_parameter(session->auth_baton,
                                  SVN_AUTH_PARAM_CONFIG_CATEGORY_SERVERS,
                                  config);
         }
@@ -202,7 +203,7 @@ load_config(svn_ra_serf__session_t *sess
                  SVN_CONFIG_OPTION_HTTP_PROXY_EXCEPTIONS, "");
   if (! svn_cstring_match_glob_list(session->session_url.hostname,
                                     svn_cstring_split(exceptions, ",",
-                                                      TRUE, pool)))
+                                                      TRUE, scratch_pool)))
     {
       svn_config_get(config, &proxy_host, SVN_CONFIG_SECTION_GLOBAL,
                      SVN_CONFIG_OPTION_HTTP_PROXY_HOST, NULL);
@@ -255,7 +256,7 @@ load_config(svn_ra_serf__session_t *sess
                                SERF_LOG_INFO));
 #endif
 
-  server_group = svn_auth_get_parameter(session->wc_callbacks->auth_baton,
+  server_group = svn_auth_get_parameter(session->auth_baton,
                                         SVN_AUTH_PARAM_SERVER_GROUP);
 
   if (server_group)
@@ -335,7 +336,7 @@ load_config(svn_ra_serf__session_t *sess
                                                  (apr_uint32_t)log_components,
                                                  SERF_LOG_DEFAULT_LAYOUT,
                                                  stderr,
-                                                 pool);
+                                                 result_pool);
 
       if (!status)
           serf_logging_add_output(session->context, output);
@@ -433,7 +434,7 @@ load_config(svn_ra_serf__session_t *sess
     }
 
   /* Setup authentication. */
-  SVN_ERR(load_http_auth_types(pool, config, server_group,
+  SVN_ERR(load_http_auth_types(result_pool, config, server_group,
                                &session->authn_types));
   serf_config_authn_types(session->context, session->authn_types);
   serf_config_credentials_callback(session->context,
@@ -474,27 +475,29 @@ svn_ra_serf__open(svn_ra_session_t *sess
                   const char *session_URL,
                   const svn_ra_callbacks2_t *callbacks,
                   void *callback_baton,
+                  svn_auth_baton_t *auth_baton,
                   apr_hash_t *config,
-                  apr_pool_t *pool)
+                  apr_pool_t *result_pool,
+                  apr_pool_t *scratch_pool)
 {
   apr_status_t status;
   svn_ra_serf__session_t *serf_sess;
   apr_uri_t url;
   const char *client_string = NULL;
   svn_error_t *err;
-  apr_pool_t *subpool;
 
   if (corrected_url)
     *corrected_url = NULL;
 
-  serf_sess = apr_pcalloc(pool, sizeof(*serf_sess));
-  serf_sess->pool = svn_pool_create(pool);
+  serf_sess = apr_pcalloc(result_pool, sizeof(*serf_sess));
+  serf_sess->pool = result_pool;
   if (config)
-    SVN_ERR(svn_config_copy_config(&serf_sess->config, config, pool));
+    SVN_ERR(svn_config_copy_config(&serf_sess->config, config, result_pool));
   else
     serf_sess->config = NULL;
   serf_sess->wc_callbacks = callbacks;
   serf_sess->wc_callback_baton = callback_baton;
+  serf_sess->auth_baton = auth_baton;
   serf_sess->progress_func = callbacks->progress_func;
   serf_sess->progress_baton = callbacks->progress_baton;
   serf_sess->cancel_func = callbacks->cancel_func;
@@ -540,7 +543,7 @@ svn_ra_serf__open(svn_ra_session_t *sess
      this, if we find an intervening proxy does not support chunked requests.  */
   serf_sess->using_chunked_requests = TRUE;
 
-  SVN_ERR(load_config(serf_sess, config, serf_sess->pool));
+  SVN_ERR(load_config(serf_sess, config, serf_sess->pool, scratch_pool));
 
   serf_sess->conns[0] = apr_pcalloc(serf_sess->pool,
                                     sizeof(*serf_sess->conns[0]));
@@ -551,13 +554,16 @@ svn_ra_serf__open(svn_ra_session_t *sess
 
   /* create the user agent string */
   if (callbacks->get_client_string)
-    SVN_ERR(callbacks->get_client_string(callback_baton, &client_string, pool));
+    SVN_ERR(callbacks->get_client_string(callback_baton, &client_string,
+                                         scratch_pool));
 
   if (client_string)
-    serf_sess->useragent = apr_pstrcat(pool, get_user_agent_string(pool), " ",
+    serf_sess->useragent = apr_pstrcat(result_pool,
+                                       get_user_agent_string(scratch_pool),
+                                       " ",
                                        client_string, SVN_VA_NULL);
   else
-    serf_sess->useragent = get_user_agent_string(pool);
+    serf_sess->useragent = get_user_agent_string(result_pool);
 
   /* go ahead and tell serf about the connection. */
   status =
@@ -578,24 +584,29 @@ svn_ra_serf__open(svn_ra_session_t *sess
 
   session->priv = serf_sess;
 
-  /* This subpool not only avoids having a lot of temporary state in the long
-     living session pool, but it also works around a bug in serf
-     <= r2319 / 1.3.4 where serf doesn't report the request as failed/cancelled
-     when the authorization request handler fails to handle the request.
-
-     In this specific case the serf connection is cleaned up by the pool
-     handlers before our handler is cleaned up (via subpools). Using a
-     subpool here cleans up our handler before the connection is cleaned. */
-  subpool = svn_pool_create(pool);
+  /* The following code explicitly works around a bug in serf <= r2319 / 1.3.8
+     where serf doesn't report the request as failed/cancelled when the
+     authorization request handler fails to handle the request.
+
+     As long as we allocate the request in a subpool of the serf connection
+     pool, we know that the handler is always cleaned before the connection.
+
+     Luckily our caller now passes us two pools which handle this case.
+   */
+#if defined(SVN_DEBUG) && !SERF_VERSION_AT_LEAST(1,4,0)
+  /* Currently ensured by svn_ra_open4().
+     If failing causes segfault in basic_tests.py 48, "basic auth test" */
+  SVN_ERR_ASSERT((serf_sess->pool != scratch_pool)
+                 && apr_pool_is_ancestor(serf_sess->pool, scratch_pool));
+#endif
 
   err = svn_ra_serf__exchange_capabilities(serf_sess, corrected_url,
-                                           pool, subpool);
+                                           result_pool, scratch_pool);
 
   /* serf should produce a usable error code instead of APR_EGENERAL */
   if (err && err->apr_err == APR_EGENERAL)
     err = svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, err,
                             _("Connection to '%s' failed"), session_URL);
-  svn_pool_clear(subpool);
   SVN_ERR(err);
 
   /* We have set up a useful connection (that doesn't indication a redirect).
@@ -604,9 +615,7 @@ svn_ra_serf__open(svn_ra_session_t *sess
      problems in any proxy.  */
   if ((corrected_url == NULL || *corrected_url == NULL)
       && serf_sess->detect_chunking && !serf_sess->http10)
-    SVN_ERR(svn_ra_serf__probe_proxy(serf_sess, subpool));
-
-  svn_pool_destroy(subpool);
+    SVN_ERR(svn_ra_serf__probe_proxy(serf_sess, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -751,7 +760,8 @@ ra_serf_dup_session(svn_ra_session_t *ne
 
   new_sess->context = serf_context_create(result_pool);
 
-  SVN_ERR(load_config(new_sess, old_sess->config, result_pool));
+  SVN_ERR(load_config(new_sess, old_sess->config,
+                      result_pool, scratch_pool));
 
   new_sess->conns[0] = apr_pcalloc(result_pool,
                                    sizeof(*new_sess->conns[0]));

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/stat.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/stat.c?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/stat.c (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/stat.c Tue Jun 23 12:55:43 2015
@@ -193,6 +193,9 @@ fill_dirent_propfunc(void *baton,
         {
           if (*val->data)
             {
+              /* Note: 1.8.x and earlier servers send the count proper; 1.9.0
+               * and newer send "1" if there are properties and "0" otherwise.
+               */
               apr_int64_t deadprop_count;
               SVN_ERR(svn_cstring_atoi64(&deadprop_count, val->data));
               fdb->entry->has_props = deadprop_count > 0;
@@ -472,6 +475,7 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
   svn_ra_serf__handler_t *props_handler = NULL;
   const char *path;
   struct get_dir_baton_t gdb;
+  svn_error_t *err = SVN_NO_ERROR;
 
   gdb.result_pool = result_pool;
   gdb.is_directory = FALSE;
@@ -542,10 +546,17 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
 
   if (dirent_handler)
     {
-      SVN_ERR(svn_ra_serf__context_run_wait(&dirent_handler->done,
+      err = svn_error_trace(
+              svn_ra_serf__context_run_wait(&dirent_handler->done,
                                             session,
                                             scratch_pool));
 
+      if (err)
+        {
+          svn_pool_clear(scratch_pool); /* Unregisters outstanding requests */
+          return err;
+        }
+
       if (gdb.supports_deadprop_count == svn_tristate_false
           && session->supports_deadprop_count == svn_tristate_unknown
           && dirent_fields & SVN_DIRENT_HAS_PROPS)
@@ -571,23 +582,27 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
 
   if (props_handler)
     {
-      SVN_ERR(svn_ra_serf__context_run_wait(&props_handler->done,
+      err = svn_error_trace(
+              svn_ra_serf__context_run_wait(&props_handler->done,
                                             session,
                                             scratch_pool));
     }
 
   /* And dirent again for the case when we had to send the request again */
-  if (dirent_handler)
+  if (! err && dirent_handler)
     {
-      SVN_ERR(svn_ra_serf__context_run_wait(&dirent_handler->done,
+      err = svn_error_trace(
+              svn_ra_serf__context_run_wait(&dirent_handler->done,
                                             session,
                                             scratch_pool));
     }
 
-  if (gdb.supports_deadprop_count != svn_tristate_unknown)
+  if (!err && gdb.supports_deadprop_count != svn_tristate_unknown)
     session->supports_deadprop_count = gdb.supports_deadprop_count;
 
-  svn_pool_destroy(scratch_pool);
+  svn_pool_destroy(scratch_pool); /* Unregisters outstanding requests */
+
+  SVN_ERR(err);
 
   if (!gdb.is_directory)
     return svn_error_create(SVN_ERR_FS_NOT_DIRECTORY, NULL,

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/update.c?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/update.c Tue Jun 23 12:55:43 2015
@@ -2759,7 +2759,7 @@ make_update_reporter(svn_ra_session_t *r
                                             update_editor,
                                             update_baton,
                                             depth, has_target,
-                                            sess->pool));
+                                            result_pool));
       update_editor = filter_editor;
       update_baton = filter_baton;
     }

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/util.c?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_serf/util.c Tue Jun 23 12:55:43 2015
@@ -313,11 +313,11 @@ ssl_server_cert(void *baton, int failure
     {
       svn_error_t *err;
 
-      svn_auth_set_parameter(conn->session->wc_callbacks->auth_baton,
+      svn_auth_set_parameter(conn->session->auth_baton,
                              SVN_AUTH_PARAM_SSL_SERVER_CERT_INFO,
                              &cert_info);
 
-      svn_auth_set_parameter(conn->session->wc_callbacks->auth_baton,
+      svn_auth_set_parameter(conn->session->auth_baton,
                              SVN_AUTH_PARAM_SSL_SERVER_FAILURES,
                              &svn_failures);
 
@@ -327,13 +327,13 @@ ssl_server_cert(void *baton, int failure
       err = svn_auth_first_credentials(&creds, &state,
                                        SVN_AUTH_CRED_SSL_SERVER_AUTHORITY,
                                        realmstring,
-                                       conn->session->wc_callbacks->auth_baton,
+                                       conn->session->auth_baton,
                                        scratch_pool);
 
-      svn_auth_set_parameter(conn->session->wc_callbacks->auth_baton,
+      svn_auth_set_parameter(conn->session->auth_baton,
                              SVN_AUTH_PARAM_SSL_SERVER_CERT_INFO, NULL);
 
-      svn_auth_set_parameter(conn->session->wc_callbacks->auth_baton,
+      svn_auth_set_parameter(conn->session->auth_baton,
                              SVN_AUTH_PARAM_SSL_SERVER_FAILURES, NULL);
 
       if (err)
@@ -360,11 +360,11 @@ ssl_server_cert(void *baton, int failure
       return APR_SUCCESS;
     }
 
-  svn_auth_set_parameter(conn->session->wc_callbacks->auth_baton,
+  svn_auth_set_parameter(conn->session->auth_baton,
                          SVN_AUTH_PARAM_SSL_SERVER_FAILURES,
                          &svn_failures);
 
-  svn_auth_set_parameter(conn->session->wc_callbacks->auth_baton,
+  svn_auth_set_parameter(conn->session->auth_baton,
                          SVN_AUTH_PARAM_SSL_SERVER_CERT_INFO,
                          &cert_info);
 
@@ -373,7 +373,7 @@ ssl_server_cert(void *baton, int failure
   SVN_ERR(svn_auth_first_credentials(&creds, &state,
                                      SVN_AUTH_CRED_SSL_SERVER_TRUST,
                                      realmstring,
-                                     conn->session->wc_callbacks->auth_baton,
+                                     conn->session->auth_baton,
                                      scratch_pool));
   if (creds)
     {
@@ -394,7 +394,7 @@ ssl_server_cert(void *baton, int failure
         }
     }
 
-  svn_auth_set_parameter(conn->session->wc_callbacks->auth_baton,
+  svn_auth_set_parameter(conn->session->auth_baton,
                          SVN_AUTH_PARAM_SSL_SERVER_CERT_INFO, NULL);
 
   /* Are there non accepted failures left? */
@@ -648,7 +648,7 @@ handle_client_cert(void *data,
                                            &conn->ssl_client_auth_state,
                                            SVN_AUTH_CRED_SSL_CLIENT_CERT,
                                            realm,
-                                           session->wc_callbacks->auth_baton,
+                                           session->auth_baton,
                                            pool));
       }
     else
@@ -700,7 +700,7 @@ handle_client_cert_pw(void *data,
                                            &conn->ssl_client_pw_auth_state,
                                            SVN_AUTH_CRED_SSL_CLIENT_CERT_PW,
                                            cert_path,
-                                           session->wc_callbacks->auth_baton,
+                                           session->auth_baton,
                                            pool));
       }
     else
@@ -947,6 +947,22 @@ svn_ra_serf__context_run_wait(svn_boolea
   return SVN_NO_ERROR;
 }
 
+/* Ensure that a handler is no longer scheduled on the connection.
+
+   Eventually serf will have a reliable way to cancel existing requests,
+   but currently it doesn't even have a way to relyable identify a request
+   after rescheduling, for auth reasons.
+
+   So the only thing we can do today is reset the connection, which
+   will cancel all outstanding requests and prepare the connection
+   for re-use.
+*/
+static void
+svn_ra_serf__unschedule_handler(svn_ra_serf__handler_t *handler)
+{
+  serf_connection_reset(handler->conn->conn);
+  handler->scheduled = FALSE;
+}
 
 svn_error_t *
 svn_ra_serf__context_run_one(svn_ra_serf__handler_t *handler,
@@ -960,6 +976,15 @@ svn_ra_serf__context_run_one(svn_ra_serf
   /* Wait until the response logic marks its DONE status.  */
   err = svn_ra_serf__context_run_wait(&handler->done, handler->session,
                                       scratch_pool);
+
+  if (handler->scheduled)
+    {
+      /* We reset the connection (breaking  pipelining, etc.), as
+         if we didn't the next data would still be handled by this handler,
+         which is done as far as our caller is concerned. */
+      svn_ra_serf__unschedule_handler(handler);
+    }
+
   return svn_error_trace(err);
 }
 
@@ -1082,7 +1107,9 @@ svn_ra_serf__expect_empty_body(serf_requ
 
   hdrs = serf_bucket_response_get_headers(response);
   val = serf_bucket_headers_get(hdrs, "Content-Type");
-  if (val && strncasecmp(val, "text/xml", sizeof("text/xml") - 1) == 0)
+  if (val
+      && (handler->sline.code < 200 || handler->sline.code >= 300)
+      && strncasecmp(val, "text/xml", sizeof("text/xml") - 1) == 0)
     {
       svn_ra_serf__server_error_t *server_err;
 
@@ -1095,7 +1122,7 @@ svn_ra_serf__expect_empty_body(serf_requ
     }
   else
     {
-      /* The body was not text/xml, so we don't know what to do with it.
+      /* The body was not text/xml, or we got a success code.
          Toss anything that arrives.  */
       handler->discard_body = TRUE;
     }
@@ -1132,7 +1159,7 @@ svn_ra_serf__credentials_callback(char *
                                            &session->auth_state,
                                            SVN_AUTH_CRED_SIMPLE,
                                            realm,
-                                           session->wc_callbacks->auth_baton,
+                                           session->auth_baton,
                                            session->pool);
         }
       else
@@ -1453,7 +1480,13 @@ handle_response_cb(serf_request_t *reque
     {
       handler->discard_body = TRUE; /* Discard further data */
       handler->done = TRUE; /* Mark as done */
-      handler->scheduled = FALSE;
+      /* handler->scheduled is still TRUE, as we still expect data.
+         If we would return an error outer-status the connection
+         would have to be restarted. With scheduled still TRUE
+         destroying the handler's pool will still reset the
+         connection, avoiding the posibility of returning
+         an error for this handler when a new request is
+         scheduled. */
       outer_status = APR_EAGAIN; /* Exit context loop */
     }
 
@@ -1762,8 +1795,9 @@ svn_ra_serf__error_on_status(serf_status
         return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,
                                  _("'%s' path not found"), path);
       case 405:
-        return svn_error_createf(SVN_ERR_FS_OUT_OF_DATE, NULL,
-                                 _("'%s' is out of date"), path);
+        return svn_error_createf(SVN_ERR_RA_DAV_METHOD_NOT_ALLOWED, NULL,
+                                 _("HTTP method is not allowed on '%s'"),
+                                 path);
       case 409:
         return svn_error_createf(SVN_ERR_FS_CONFLICT, NULL,
                                  _("'%s' conflicts"), path);
@@ -1802,9 +1836,10 @@ svn_error_t *
 svn_ra_serf__unexpected_status(svn_ra_serf__handler_t *handler)
 {
   /* Is it a standard error status? */
-  SVN_ERR(svn_ra_serf__error_on_status(handler->sline,
-                                       handler->path,
-                                       handler->location));
+  if (handler->sline.code != 405)
+    SVN_ERR(svn_ra_serf__error_on_status(handler->sline,
+                                         handler->path,
+                                         handler->location));
 
   switch (handler->sline.code)
     {
@@ -1817,6 +1852,11 @@ svn_ra_serf__unexpected_status(svn_ra_se
                                  _("Path '%s' already exists"),
                                  handler->path);
 
+      case 405:
+        return svn_error_createf(SVN_ERR_RA_DAV_METHOD_NOT_ALLOWED, NULL,
+                                 _("The HTTP method '%s' is not allowed"
+                                   " on '%s'"),
+                                 handler->method, handler->path);
       default:
         return svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
                                  _("Unexpected HTTP status %d '%s' on '%s' "
@@ -1874,14 +1914,14 @@ response_done(serf_request_t *request,
    handlers registered in no freed memory.
 
    This fallback kills the connection for this case, which will make serf
-   unregister any*/
+   unregister any outstanding requests on it. */
 static apr_status_t
 handler_cleanup(void *baton)
 {
   svn_ra_serf__handler_t *handler = baton;
-  if (handler->scheduled && handler->conn && handler->conn->conn)
+  if (handler->scheduled)
     {
-      serf_connection_reset(handler->conn->conn);
+      svn_ra_serf__unschedule_handler(handler);
     }
 
   return APR_SUCCESS;

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_svn/client.c?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_svn/client.c Tue Jun 23 12:55:43 2015
@@ -616,7 +616,9 @@ static svn_error_t *open_session(svn_ra_
                                  apr_hash_t *config,
                                  const svn_ra_callbacks2_t *callbacks,
                                  void *callbacks_baton,
-                                 apr_pool_t *pool)
+                                 svn_auth_baton_t *auth_baton,
+                                 apr_pool_t *result_pool,
+                                 apr_pool_t *scratch_pool)
 {
   svn_ra_svn__session_baton_t *sess;
   svn_ra_svn_conn_t *conn;
@@ -624,6 +626,7 @@ static svn_error_t *open_session(svn_ra_
   apr_uint64_t minver, maxver;
   apr_array_header_t *mechlist, *server_caplist, *repos_caplist;
   const char *client_string = NULL;
+  apr_pool_t *pool = result_pool;
 
   sess = apr_palloc(pool, sizeof(*sess));
   sess->pool = pool;
@@ -636,6 +639,7 @@ static svn_error_t *open_session(svn_ra_
   sess->callbacks = callbacks;
   sess->callbacks_baton = callbacks_baton;
   sess->bytes_read = sess->bytes_written = 0;
+  sess->auth_baton = auth_baton;
 
   if (config)
     SVN_ERR(svn_config_copy_config(&sess->config, config, pool));
@@ -804,6 +808,7 @@ static svn_error_t *ra_svn_open(svn_ra_s
                                 const char *url,
                                 const svn_ra_callbacks2_t *callbacks,
                                 void *callback_baton,
+                                svn_auth_baton_t *auth_baton,
                                 apr_hash_t *config,
                                 apr_pool_t *result_pool,
                                 apr_pool_t *scratch_pool)
@@ -839,32 +844,21 @@ static svn_error_t *ra_svn_open(svn_ra_s
                ? svn_hash_gets(config, SVN_CONFIG_CATEGORY_CONFIG)
                : NULL;
   cfg = config ? svn_hash_gets(config, SVN_CONFIG_CATEGORY_SERVERS) : NULL;
-  svn_auth_set_parameter(callbacks->auth_baton,
+  svn_auth_set_parameter(auth_baton,
                          SVN_AUTH_PARAM_CONFIG_CATEGORY_CONFIG, cfg_client);
-  svn_auth_set_parameter(callbacks->auth_baton,
+  svn_auth_set_parameter(auth_baton,
                          SVN_AUTH_PARAM_CONFIG_CATEGORY_SERVERS, cfg);
 
   /* We open the session in a subpool so we can get rid of it if we
      reparent with a server that doesn't support reparenting. */
   SVN_ERR(open_session(&sess, url, &uri, tunnel, tunnel_argv, config,
-                       callbacks, callback_baton, sess_pool));
+                       callbacks, callback_baton,
+                       auth_baton, sess_pool, scratch_pool));
   session->priv = sess;
 
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *ra_svn_open_pool(svn_ra_session_t *session,
-                                     const char **corrected_url,
-                                     const char *url,
-                                     const svn_ra_callbacks2_t *callbacks,
-                                     void *callback_baton,
-                                     apr_hash_t *config,
-                                     apr_pool_t *pool)
-{
-  return ra_svn_open(session, corrected_url, url, callbacks, callback_baton,
-                     config, pool, pool);
-}
-
 static svn_error_t *ra_svn_dup_session(svn_ra_session_t *new_session,
                                        svn_ra_session_t *old_session,
                                        const char *new_session_url,
@@ -875,7 +869,7 @@ static svn_error_t *ra_svn_dup_session(s
 
   SVN_ERR(ra_svn_open(new_session, NULL, new_session_url,
                       old_sess->callbacks, old_sess->callbacks_baton,
-                      old_sess->config,
+                      old_sess->auth_baton, old_sess->config,
                       result_pool, scratch_pool));
 
   return SVN_NO_ERROR;
@@ -912,7 +906,7 @@ static svn_error_t *ra_svn_reparent(svn_
   if (! err)
     err = open_session(&new_sess, url, &uri, sess->tunnel_name, sess->tunnel_argv,
                        sess->config, sess->callbacks, sess->callbacks_baton,
-                       sess_pool);
+                       sess->auth_baton, sess_pool, sess_pool);
   /* We destroy the new session pool on error, since it is allocated in
      the main session pool. */
   if (err)
@@ -1784,7 +1778,7 @@ perform_ra_svn_log(svn_error_t **outer_e
           - Except if the server sends more than a >= 1 limit top level items
           - Or when the callback reported a SVN_ERR_CEASE_INVOCATION
             in an earlier invocation. */
-      if (! (limit && (nest_level == 0) && (++nreceived > limit))
+      if (! ((limit > 0) && (nest_level == 0) && (++nreceived > limit))
           && ! *outer_error)
         {
           svn_error_t *err;
@@ -1812,7 +1806,7 @@ perform_ra_svn_log(svn_error_t **outer_e
                           SVN_PROP_REVISION_LOG, message);
 
           err = receiver(receiver_baton, log_entry, iterpool);
-          if (err && err->apr_err == SVN_ERR_CEASE_INVOCATION)
+          if (svn_error_find_cause(err, SVN_ERR_CEASE_INVOCATION))
             {
               *outer_error = svn_error_trace(
                                 svn_error_compose_create(*outer_error, err));
@@ -2000,14 +1994,15 @@ static svn_error_t *ra_svn_get_locations
 }
 
 static svn_error_t *
-ra_svn_get_location_segments(svn_ra_session_t *session,
-                             const char *path,
-                             svn_revnum_t peg_revision,
-                             svn_revnum_t start_rev,
-                             svn_revnum_t end_rev,
-                             svn_location_segment_receiver_t receiver,
-                             void *receiver_baton,
-                             apr_pool_t *pool)
+perform_get_location_segments(svn_error_t **outer_error,
+                              svn_ra_session_t *session,
+                              const char *path,
+                              svn_revnum_t peg_revision,
+                              svn_revnum_t start_rev,
+                              svn_revnum_t end_rev,
+                              svn_location_segment_receiver_t receiver,
+                              void *receiver_baton,
+                              apr_pool_t *pool)
 {
   svn_ra_svn__session_baton_t *sess_baton = session->priv;
   svn_ra_svn_conn_t *conn = sess_baton->conn;
@@ -2054,7 +2049,17 @@ ra_svn_get_location_segments(svn_ra_sess
           segment->path = ret_path;
           segment->range_start = range_start;
           segment->range_end = range_end;
-          SVN_ERR(receiver(segment, receiver_baton, iterpool));
+
+          if (!*outer_error)
+            {
+              svn_error_t *err = svn_error_trace(receiver(segment, receiver_baton,
+                                                          iterpool));
+
+              if (svn_error_find_cause(err, SVN_ERR_CEASE_INVOCATION))
+                *outer_error = err;
+              else
+                SVN_ERR(err);
+            }
         }
     }
   svn_pool_destroy(iterpool);
@@ -2066,6 +2071,26 @@ ra_svn_get_location_segments(svn_ra_sess
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+ra_svn_get_location_segments(svn_ra_session_t *session,
+                             const char *path,
+                             svn_revnum_t peg_revision,
+                             svn_revnum_t start_rev,
+                             svn_revnum_t end_rev,
+                             svn_location_segment_receiver_t receiver,
+                             void *receiver_baton,
+                             apr_pool_t *pool)
+{
+  svn_error_t *outer_err = SVN_NO_ERROR;
+  svn_error_t *err;
+
+  err = svn_error_trace(
+            perform_get_location_segments(&outer_err, session, path,
+                                          peg_revision, start_rev, end_rev,
+                                          receiver, receiver_baton, pool));
+  return svn_error_compose_create(outer_err, err);
+}
+
 static svn_error_t *ra_svn_get_file_revs(svn_ra_session_t *session,
                                          const char *path,
                                          svn_revnum_t start, svn_revnum_t end,
@@ -2726,10 +2751,16 @@ ra_svn_replay_range(svn_ra_session_t *se
 
       SVN_ERR(svn_ra_svn__read_tuple(sess->conn, iterpool,
                                      "wl", &word, &list));
+
       if (strcmp(word, "revprops") != 0)
-        return svn_error_createf(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
-                                 _("Expected 'revprops', found '%s'"),
-                                 word);
+        {
+          if (strcmp(word, "failure") == 0)
+            SVN_ERR(svn_ra_svn__handle_failure_status(list, iterpool));
+
+          return svn_error_createf(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
+                                   _("Expected 'revprops', found '%s'"),
+                                   word);
+        }
 
       SVN_ERR(svn_ra_svn__parse_proplist(list, iterpool, &rev_props));
 
@@ -2872,7 +2903,7 @@ static const svn_ra__vtable_t ra_svn_vta
   svn_ra_svn_version,
   ra_svn_get_description,
   ra_svn_get_schemes,
-  ra_svn_open_pool,
+  ra_svn_open,
   ra_svn_dup_session,
   ra_svn_reparent,
   ra_svn_get_session_url,

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_svn/cyrus_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_svn/cyrus_auth.c?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_svn/cyrus_auth.c (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_svn/cyrus_auth.c Tue Jun 23 12:55:43 2015
@@ -867,7 +867,7 @@ svn_ra_svn__do_cyrus_auth(svn_ra_svn__se
   realmstring = apr_psprintf(pool, "%s %s", sess->realm_prefix, realm);
 
   /* Initialize the credential baton. */
-  cred_baton.auth_baton = sess->callbacks->auth_baton;
+  cred_baton.auth_baton = sess->auth_baton;
   cred_baton.realmstring = realmstring;
   cred_baton.pool = pool;
 

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_svn/editorp.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_svn/editorp.c?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_svn/editorp.c (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_svn/editorp.c Tue Jun 23 12:55:43 2015
@@ -633,7 +633,7 @@ static svn_error_t *ra_svn_handle_close_
 
   /* Close the directory and destroy the baton. */
   SVN_CMD_ERR(ds->editor->close_directory(entry->baton, pool));
-  svn_hash_sets(ds->tokens, token, NULL);
+  apr_hash_set(ds->tokens, token->data, token->len, NULL);
   svn_pool_destroy(entry->pool);
   return SVN_NO_ERROR;
 }
@@ -812,7 +812,7 @@ static svn_error_t *ra_svn_handle_close_
 
   /* Close the file and destroy the baton. */
   SVN_CMD_ERR(ds->editor->close_file(entry->baton, text_checksum, pool));
-  svn_hash_sets(ds->tokens, token, NULL);
+  apr_hash_set(ds->tokens, token->data, token->len, NULL);
   if (--ds->file_refs == 0)
     svn_pool_clear(ds->file_pool);
   return SVN_NO_ERROR;
@@ -843,6 +843,14 @@ static svn_error_t *ra_svn_handle_close_
 {
   SVN_CMD_ERR(ds->editor->close_edit(ds->edit_baton, pool));
   ds->done = TRUE;
+#ifdef SVN_DEBUG
+  /* Before enabling this in non-maintainer mode:
+     *  Note that this code is used on both client *and* server */
+  if (apr_hash_count(ds->tokens) != 0)
+    return svn_error_create(
+              SVN_ERR_FS_INCORRECT_EDITOR_COMPLETION, NULL,
+              _("Closing editor with directories or files open"));
+#endif
   if (ds->aborted)
     *ds->aborted = FALSE;
   return svn_ra_svn__write_cmd_response(conn, pool, "");

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_svn/internal_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_svn/internal_auth.c?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_svn/internal_auth.c (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_svn/internal_auth.c Tue Jun 23 12:55:43 2015
@@ -95,7 +95,7 @@ svn_ra_svn__do_internal_auth(svn_ra_svn_
     {
       SVN_ERR(svn_auth_first_credentials(&creds, &iterstate,
                                          SVN_AUTH_CRED_SIMPLE, realmstring,
-                                         sess->callbacks->auth_baton, pool));
+                                         sess->auth_baton, pool));
       if (!creds)
         return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
                                 _("Can't get password"));

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_svn/ra_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_svn/ra_svn.h?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_svn/ra_svn.h (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_ra_svn/ra_svn.h Tue Jun 23 12:55:43 2015
@@ -123,6 +123,7 @@ struct svn_ra_svn__session_baton_t {
   apr_pool_t *pool;
   svn_ra_svn_conn_t *conn;
   svn_boolean_t is_tunneled;
+  svn_auth_baton_t *auth_baton;
   const char *url;
   const char *user;
   const char *hostname; /* The remote hostname. */

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_repos/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_repos/commit.c?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_repos/commit.c (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_repos/commit.c Tue Jun 23 12:55:43 2015
@@ -124,6 +124,7 @@ struct dir_baton
   svn_revnum_t base_rev;        /* the revision I'm based on  */
   svn_boolean_t was_copied; /* was this directory added with history? */
   apr_pool_t *pool; /* my personal pool, in which I am allocated. */
+  svn_boolean_t checked_write; /* TRUE after successfull write check */
 };
 
 
@@ -131,6 +132,7 @@ struct file_baton
 {
   struct edit_baton *edit_baton;
   const char *path; /* the -absolute- path to this file in the fs */
+  svn_boolean_t checked_write; /* TRUE after successfull write check */
 };
 
 
@@ -171,6 +173,30 @@ out_of_date(const char *path, svn_node_k
                            path);
 }
 
+/* Perform an out of date check for base_rev against created rev,
+   and a sanity check of base_rev. */
+static svn_error_t *
+check_out_of_date(struct edit_baton *eb,
+                  const char *path,
+                  svn_node_kind_t kind,
+                  svn_revnum_t base_rev,
+                  svn_revnum_t created_rev)
+{
+  if (base_rev < created_rev)
+    {
+      return out_of_date(path, kind);
+    }
+  else if (base_rev > created_rev)
+    {
+      if (base_rev > svn_fs_txn_base_revision(eb->txn))
+        return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL, 
+                                 _("No such revision %ld"),
+                                 base_rev);
+    }
+
+  return SVN_NO_ERROR;
+}
+
 
 static svn_error_t *
 invoke_commit_cb(svn_commit_callback2_t commit_cb,
@@ -364,14 +390,18 @@ add_file_or_directory(const char *path,
   /* Build a new child baton. */
   if (is_dir)
     {
-      *return_baton = make_dir_baton(eb, pb, full_path, was_copied,
-                                     SVN_INVALID_REVNUM, pool);
+      struct dir_baton *new_db = make_dir_baton(eb, pb, full_path, was_copied,
+                                                SVN_INVALID_REVNUM, pool);
+
+      new_db->checked_write = TRUE; /* Just created */
+      *return_baton = new_db;
     }
   else
     {
       struct file_baton *new_fb = apr_pcalloc(pool, sizeof(*new_fb));
       new_fb->edit_baton = eb;
       new_fb->path = full_path;
+      new_fb->checked_write = TRUE; /* Just created */
       *return_baton = new_fb;
     }
 
@@ -392,11 +422,16 @@ open_root(void *edit_baton,
   struct edit_baton *eb = edit_baton;
   svn_revnum_t youngest;
 
-  /* Ignore BASE_REVISION.  We always build our transaction against
-     HEAD.  However, we will keep it in our dir baton for out of
-     dateness checks.  */
+  /* We always build our transaction against HEAD.  However, we will
+     sanity-check BASE_REVISION and keep it in our dir baton for out
+     of dateness checks.  */
   SVN_ERR(svn_fs_youngest_rev(&youngest, eb->fs, eb->pool));
 
+  if (base_revision > youngest)
+    return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
+                             _("No such revision %ld (HEAD is %ld)"),
+                             base_revision, youngest);
+
   /* Unless we've been instructed to use a specific transaction, we'll
      make our own. */
   if (eb->txn_owner)
@@ -443,7 +478,6 @@ delete_entry(const char *path,
   struct dir_baton *parent = parent_baton;
   struct edit_baton *eb = parent->edit_baton;
   svn_node_kind_t kind;
-  svn_revnum_t cr_rev;
   svn_repos_authz_access_t required = svn_authz_write;
   const char *full_path;
 
@@ -468,14 +502,18 @@ delete_entry(const char *path,
 
   /* Now, make sure we're deleting the node we *think* we're
      deleting, else return an out-of-dateness error. */
-  SVN_ERR(svn_fs_node_created_rev(&cr_rev, eb->txn_root, full_path, pool));
-  if (SVN_IS_VALID_REVNUM(revision) && (revision < cr_rev))
-    return svn_error_trace(out_of_date(full_path, kind));
+  if (SVN_IS_VALID_REVNUM(revision))
+    {
+      svn_revnum_t cr_rev;
+
+      SVN_ERR(svn_fs_node_created_rev(&cr_rev, eb->txn_root, full_path, pool));
+      SVN_ERR(check_out_of_date(eb, full_path, kind, revision, cr_rev));
+    }
 
   /* This routine is a mindless wrapper.  We call svn_fs_delete()
      because that will delete files and recursively delete
      directories.  */
-  return svn_fs_delete(eb->txn_root, full_path, pool);
+  return svn_error_trace(svn_fs_delete(eb->txn_root, full_path, pool));
 }
 
 
@@ -530,18 +568,23 @@ apply_textdelta(void *file_baton,
                 void **handler_baton)
 {
   struct file_baton *fb = file_baton;
+  struct edit_baton *eb = fb->edit_baton;
 
-  /* Check for write authorization. */
-  SVN_ERR(check_authz(fb->edit_baton, fb->path,
-                      fb->edit_baton->txn_root,
-                      svn_authz_write, pool));
+  if (!fb->checked_write)
+    {
+      /* Check for write authorization. */
+      SVN_ERR(check_authz(eb, fb->path, eb->txn_root,
+                          svn_authz_write, pool));
+      fb->checked_write = TRUE;
+    }
 
-  return svn_fs_apply_textdelta(handler, handler_baton,
-                                fb->edit_baton->txn_root,
-                                fb->path,
-                                base_checksum,
-                                NULL,
-                                pool);
+  return svn_error_trace(
+          svn_fs_apply_textdelta(handler, handler_baton,
+                                 eb->txn_root,
+                                 fb->path,
+                                 base_checksum,
+                                 NULL,
+                                 pool));
 }
 
 
@@ -585,8 +628,9 @@ open_file(const char *path,
 
   /* If the node our caller has is an older revision number than the
      one in our transaction, return an out-of-dateness error. */
-  if (SVN_IS_VALID_REVNUM(base_revision) && (base_revision < cr_rev))
-    return svn_error_trace(out_of_date(full_path, svn_node_file));
+  if (SVN_IS_VALID_REVNUM(base_revision))
+    SVN_ERR(check_out_of_date(eb, full_path, svn_node_file,
+                              base_revision, cr_rev));
 
   /* Build a new file baton */
   new_fb = apr_pcalloc(pool, sizeof(*new_fb));
@@ -611,9 +655,13 @@ change_file_prop(void *file_baton,
   struct file_baton *fb = file_baton;
   struct edit_baton *eb = fb->edit_baton;
 
-  /* Check for write authorization. */
-  SVN_ERR(check_authz(eb, fb->path, eb->txn_root,
-                      svn_authz_write, pool));
+  if (!fb->checked_write)
+    {
+      /* Check for write authorization. */
+      SVN_ERR(check_authz(eb, fb->path, eb->txn_root,
+                          svn_authz_write, pool));
+      fb->checked_write = TRUE;
+    }
 
   return svn_repos_fs_change_node_prop(eb->txn_root, fb->path,
                                        name, value, pool);
@@ -658,19 +706,24 @@ change_dir_prop(void *dir_baton,
   struct edit_baton *eb = db->edit_baton;
 
   /* Check for write authorization. */
-  SVN_ERR(check_authz(eb, db->path, eb->txn_root,
-                      svn_authz_write, pool));
-
-  if (SVN_IS_VALID_REVNUM(db->base_rev))
+  if (!db->checked_write)
     {
-      /* Subversion rule:  propchanges can only happen on a directory
-         which is up-to-date. */
-      svn_revnum_t created_rev;
-      SVN_ERR(svn_fs_node_created_rev(&created_rev,
-                                      eb->txn_root, db->path, pool));
+      SVN_ERR(check_authz(eb, db->path, eb->txn_root,
+                          svn_authz_write, pool));
+
+      if (SVN_IS_VALID_REVNUM(db->base_rev))
+        {
+          /* Subversion rule:  propchanges can only happen on a directory
+             which is up-to-date. */
+          svn_revnum_t created_rev;
+          SVN_ERR(svn_fs_node_created_rev(&created_rev,
+                                          eb->txn_root, db->path, pool));
+
+          SVN_ERR(check_out_of_date(eb, db->path, svn_node_dir,
+                                    db->base_rev, created_rev));
+        }
 
-      if (db->base_rev < created_rev)
-        return svn_error_trace(out_of_date(db->path, svn_node_dir));
+      db->checked_write = TRUE; /* Skip on further prop changes */
     }
 
   return svn_repos_fs_change_node_prop(eb->txn_root, db->path,

Modified: subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_repos/delta.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_repos/delta.c?rev=1687045&r1=1687044&r2=1687045&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_repos/delta.c (original)
+++ subversion/branches/svn-mergeinfo-normalizer/subversion/libsvn_repos/delta.c Tue Jun 23 12:55:43 2015
@@ -321,7 +321,7 @@ svn_repos_dir_delta2(svn_fs_root_t *src_
   SVN_ERR(svn_fs_node_relation(&relation, tgt_root, tgt_fullpath,
                                src_root, src_fullpath, pool));
 
-  if (relation == svn_fs_node_same)
+  if (relation == svn_fs_node_unchanged)
     {
       /* They are the same node!  No-op (you gotta love those). */
       goto cleanup;