You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2015/03/09 10:53:09 UTC

svn commit: r1665166 [2/5] - in /subversion/branches/move-tracking-2: ./ subversion/ subversion/bindings/javahl/native/ subversion/bindings/javahl/native/jniwrapper/ subversion/bindings/javahl/tests/org/apache/subversion/javahl/ subversion/bindings/swi...

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs/fs-loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs/fs-loader.h?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs/fs-loader.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs/fs-loader.h Mon Mar  9 09:53:06 2015
@@ -446,7 +446,7 @@ typedef struct id_vtable_t
 /*** Definitions of the abstract FS object types ***/
 
 /* These are transaction properties that correspond to the bitfields
-   in the 'flags' argument to svn_fs_lock().  */
+   in the 'flags' argument to svn_fs_begin_txn2().  */
 #define SVN_FS__PROP_TXN_CHECK_LOCKS           SVN_PROP_PREFIX "check-locks"
 #define SVN_FS__PROP_TXN_CHECK_OOD             SVN_PROP_PREFIX "check-ood"
 /* Set to "0" at the start of the txn, to "1" when svn:date changes. */

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_base/revs-txns.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_base/revs-txns.c?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_base/revs-txns.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_base/revs-txns.c Mon Mar  9 09:53:06 2015
@@ -711,6 +711,23 @@ txn_body_begin_txn(void *baton, trail_t
       SVN_ERR(txn_body_change_txn_prop(&cpargs, trail));
     }
 
+  /* Put a datestamp on the newly created txn, so we always know
+     exactly how old it is.  (This will help sysadmins identify
+     long-abandoned txns that may need to be manually removed.) Do
+     this before setting CLIENT_DATE so that it is not recorded as an
+     explicit setting. */
+  {
+    struct change_txn_prop_args cpargs;
+    svn_string_t date;
+    cpargs.fs = trail->fs;
+    cpargs.id = txn_id;
+    cpargs.name = SVN_PROP_REVISION_DATE;
+    date.data  = svn_time_to_cstring(apr_time_now(), trail->pool);
+    date.len = strlen(date.data);
+    cpargs.value = &date;
+    SVN_ERR(txn_body_change_txn_prop(&cpargs, trail));
+  }
+
   if (args->flags & SVN_FS_TXN_CLIENT_DATE)
     {
       struct change_txn_prop_args cpargs;
@@ -737,7 +754,6 @@ svn_fs_base__begin_txn(svn_fs_txn_t **tx
 {
   svn_fs_txn_t *txn;
   struct begin_txn_args args;
-  svn_string_t date;
 
   SVN_ERR(svn_fs__check_fs(fs, TRUE));
 
@@ -748,15 +764,7 @@ svn_fs_base__begin_txn(svn_fs_txn_t **tx
 
   *txn_p = txn;
 
-  /* Put a datestamp on the newly created txn, so we always know
-     exactly how old it is.  (This will help sysadmins identify
-     long-abandoned txns that may need to be manually removed.)  When
-     a txn is promoted to a revision, this property will be
-     automatically overwritten with a revision datestamp. */
-  date.data = svn_time_to_cstring(apr_time_now(), pool);
-  date.len = strlen(date.data);
-  return svn_fs_base__change_txn_prop(txn, SVN_PROP_REVISION_DATE,
-                                       &date, pool);
+  return SVN_NO_ERROR;
 }
 
 

Modified: subversion/branches/move-tracking-2/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra/ra_loader.c?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra/ra_loader.c Mon Mar  9 09:53:06 2015
@@ -269,6 +269,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;
@@ -278,6 +279,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;
@@ -293,8 +295,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)
@@ -347,16 +353,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;
 
@@ -380,10 +386,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);
 
@@ -401,7 +409,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;
     }
 
@@ -415,7 +423,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'"),
@@ -423,6 +431,7 @@ svn_error_t *svn_ra_open4(svn_ra_session
         }
     }
 
+  svn_pool_destroy(scratch_pool);
   *session_p = session;
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/move-tracking-2/subversion/libsvn_ra/ra_loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra/ra_loader.h?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra/ra_loader.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra/ra_loader.h Mon Mar  9 09:53:06 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/move-tracking-2/subversion/libsvn_ra/wrapper_template.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra/wrapper_template.h?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra/wrapper_template.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra/wrapper_template.h Mon Mar  9 09:53:06 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/move-tracking-2/subversion/libsvn_ra_local/ra_local.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_local/ra_local.h?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_local/ra_local.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_local/ra_local.h Mon Mar  9 09:53:06 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/move-tracking-2/subversion/libsvn_ra_local/ra_plugin.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_local/ra_plugin.c?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_local/ra_plugin.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_local/ra_plugin.c Mon Mar  9 09:53:06 2015
@@ -86,7 +86,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 +95,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 +551,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 +575,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

Modified: subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/commit.c?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/commit.c Mon Mar  9 09:53:06 2015
@@ -101,6 +101,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. */
@@ -1101,8 +1103,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,
@@ -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)
@@ -1539,7 +1587,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)

Modified: subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/merge.c?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/merge.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/merge.c Mon Mar  9 09:53:06 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/move-tracking-2/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/ra_serf.h?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/ra_serf.h Mon Mar  9 09:53:06 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/move-tracking-2/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/serf.c?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/serf.c Mon Mar  9 09:53:06 2015
@@ -180,17 +180,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);
         }
@@ -255,7 +255,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)
@@ -474,27 +474,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;
@@ -551,13 +553,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 +583,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 +614,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;
 }

Modified: subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/util.c?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/util.c Mon Mar  9 09:53:06 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
@@ -1132,7 +1132,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

Modified: subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/client.c?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/client.c Mon Mar  9 09:53:06 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)
@@ -2872,7 +2866,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/move-tracking-2/subversion/libsvn_ra_svn/cyrus_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/cyrus_auth.c?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/cyrus_auth.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/cyrus_auth.c Mon Mar  9 09:53:06 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/move-tracking-2/subversion/libsvn_ra_svn/editorp.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/editorp.c?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/editorp.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/editorp.c Mon Mar  9 09:53:06 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;

Modified: subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/internal_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/internal_auth.c?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/internal_auth.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/internal_auth.c Mon Mar  9 09:53:06 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/move-tracking-2/subversion/libsvn_ra_svn/ra_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/ra_svn.h?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/ra_svn.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/ra_svn.h Mon Mar  9 09:53:06 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/move-tracking-2/subversion/libsvn_repos/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_repos/commit.c?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_repos/commit.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_repos/commit.c Mon Mar  9 09:53:06 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/move-tracking-2/subversion/libsvn_repos/rev_hunt.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_repos/rev_hunt.c?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_repos/rev_hunt.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_repos/rev_hunt.c Mon Mar  9 09:53:06 2015
@@ -310,9 +310,8 @@ svn_repos_deleted_rev(svn_fs_t *fs,
                       svn_revnum_t *deleted,
                       apr_pool_t *pool)
 {
-  apr_pool_t *subpool;
-  svn_fs_root_t *start_root, *root, *copy_root;
-  const char *copy_path;
+  apr_pool_t *iterpool;
+  svn_fs_root_t *start_root, *root;
   svn_revnum_t mid_rev;
   svn_node_kind_t kind;
   svn_fs_node_relation_t node_relation;
@@ -379,6 +378,8 @@ svn_repos_deleted_rev(svn_fs_t *fs,
                                    root, path, pool));
       if (node_relation != svn_fs_node_unrelated)
         {
+          svn_fs_root_t *copy_root;
+          const char *copy_path;
           SVN_ERR(svn_fs_closest_copy(&copy_root, &copy_path, root,
                                       path, pool));
           if (!copy_root ||
@@ -432,15 +433,15 @@ svn_repos_deleted_rev(svn_fs_t *fs,
   */
 
   mid_rev = (start + end) / 2;
-  subpool = svn_pool_create(pool);
+  iterpool = svn_pool_create(pool);
 
   while (1)
     {
-      svn_pool_clear(subpool);
+      svn_pool_clear(iterpool);
 
       /* Get revision root and node id for mid_rev at that revision. */
-      SVN_ERR(svn_fs_revision_root(&root, fs, mid_rev, subpool));
-      SVN_ERR(svn_fs_check_path(&kind, root, path, pool));
+      SVN_ERR(svn_fs_revision_root(&root, fs, mid_rev, iterpool));
+      SVN_ERR(svn_fs_check_path(&kind, root, path, iterpool));
       if (kind == svn_node_none)
         {
           /* Case D: Look lower in the range. */
@@ -449,13 +450,15 @@ svn_repos_deleted_rev(svn_fs_t *fs,
         }
       else
         {
+          svn_fs_root_t *copy_root;
+          const char *copy_path;
           /* Determine the relationship between the start node
              and the current node. */
           SVN_ERR(svn_fs_node_relation(&node_relation, start_root, path,
-                                       root, path, pool));
+                                       root, path, iterpool));
           if (node_relation != svn_fs_node_unrelated)
-          SVN_ERR(svn_fs_closest_copy(&copy_root, &copy_path, root,
-                                      path, subpool));
+            SVN_ERR(svn_fs_closest_copy(&copy_root, &copy_path, root,
+                                        path, iterpool));
           if (node_relation == svn_fs_node_unrelated ||
               (copy_root &&
                (svn_fs_revision_root_revision(copy_root) > start)))
@@ -479,7 +482,7 @@ svn_repos_deleted_rev(svn_fs_t *fs,
         }
     }
 
-  svn_pool_destroy(subpool);
+  svn_pool_destroy(iterpool);
   return SVN_NO_ERROR;
 }
 
@@ -666,8 +669,7 @@ svn_repos_trace_node_locations(svn_fs_t
   /* First - let's sort the array of the revisions from the greatest revision
    * downward, so it will be easier to search on. */
   location_revisions = apr_array_copy(pool, location_revisions_orig);
-  qsort(location_revisions->elts, location_revisions->nelts,
-        sizeof(*revision_ptr), svn_sort_compare_revisions);
+  svn_sort__array(location_revisions, svn_sort_compare_revisions);
 
   revision_ptr = (svn_revnum_t *)location_revisions->elts;
   revision_ptr_end = revision_ptr + location_revisions->nelts;

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/auth.c?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/auth.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/auth.c Mon Mar  9 09:53:06 2015
@@ -109,10 +109,10 @@ struct svn_auth_baton_t
 
   /* run-time parameters needed by providers. */
   apr_hash_t *parameters;
+  apr_hash_t *slave_parameters;
 
   /* run-time credentials cache. */
   apr_hash_t *creds_cache;
-
 };
 
 /* Abstracted iteration baton */
@@ -125,6 +125,7 @@ struct svn_auth_iterstate_t
   const char *realmstring;      /* The original realmstring passed in */
   const char *cache_key;        /* key to use in auth_baton's creds_cache */
   svn_auth_baton_t *auth_baton; /* the original auth_baton. */
+  apr_hash_t *parameters;
 };
 
 
@@ -142,6 +143,7 @@ svn_auth_open(svn_auth_baton_t **auth_ba
   ab = apr_pcalloc(pool, sizeof(*ab));
   ab->tables = apr_hash_make(pool);
   ab->parameters = apr_hash_make(pool);
+  /* ab->slave_parameters = NULL; */
   ab->creds_cache = apr_hash_make(pool);
   ab->pool = pool;
 
@@ -170,7 +172,8 @@ svn_auth_open(svn_auth_baton_t **auth_ba
   *auth_baton = ab;
 }
 
-
+/* Magic pointer value to allow storing 'NULL' in an apr_hash_t */
+static const void *auth_NULL = NULL;
 
 void
 svn_auth_set_parameter(svn_auth_baton_t *auth_baton,
@@ -178,17 +181,36 @@ svn_auth_set_parameter(svn_auth_baton_t
                        const void *value)
 {
   if (auth_baton)
-    svn_hash_sets(auth_baton->parameters, name, value);
+    {
+      if (auth_baton->slave_parameters)
+        {
+          if (!value)
+            value = &auth_NULL;
+
+          svn_hash_sets(auth_baton->slave_parameters, name, value);
+        }
+      else
+        svn_hash_sets(auth_baton->parameters, name, value);
+    }
 }
 
 const void *
 svn_auth_get_parameter(svn_auth_baton_t *auth_baton,
                        const char *name)
 {
-  if (auth_baton)
-    return svn_hash_gets(auth_baton->parameters, name);
-  else
+  const void *value;
+  if (!auth_baton)
     return NULL;
+  else if (!auth_baton->slave_parameters)
+    return svn_hash_gets(auth_baton->parameters, name);
+
+  value = svn_hash_gets(auth_baton->slave_parameters, name);
+
+  if (value)
+    return (value == &auth_NULL) ? NULL
+                                : value;
+
+  return svn_hash_gets(auth_baton->parameters, name);
 }
 
 
@@ -218,6 +240,7 @@ svn_auth_first_credentials(void **creden
   svn_boolean_t got_first = FALSE;
   svn_auth_iterstate_t *iterstate;
   const char *cache_key;
+  apr_hash_t *parameters;
 
   if (! auth_baton)
     return svn_error_create(SVN_ERR_AUTHN_NO_PROVIDER, NULL,
@@ -230,6 +253,26 @@ svn_auth_first_credentials(void **creden
                              _("No provider registered for '%s' credentials"),
                              cred_kind);
 
+  if (auth_baton->slave_parameters)
+    {
+      apr_hash_index_t *hi;
+      parameters = apr_hash_copy(pool, auth_baton->parameters);
+
+      for (hi = apr_hash_first(pool, auth_baton->slave_parameters);
+            hi;
+            hi = apr_hash_next(hi))
+        {
+          const void *value = apr_hash_this_val(hi);
+
+          if (value == &auth_NULL)
+            value = NULL;
+
+          svn_hash_sets(parameters, apr_hash_this_key(hi), value);
+        }
+    }
+  else
+    parameters = auth_baton->parameters;
+
   /* First, see if we have cached creds in the auth_baton. */
   cache_key = make_cache_key(cred_kind, realmstring, pool);
   creds = svn_hash_gets(auth_baton->creds_cache, cache_key);
@@ -247,7 +290,7 @@ svn_auth_first_credentials(void **creden
                                    svn_auth_provider_object_t *);
           SVN_ERR(provider->vtable->first_credentials(&creds, &iter_baton,
                                                       provider->provider_baton,
-                                                      auth_baton->parameters,
+                                                      parameters,
                                                       realmstring,
                                                       auth_baton->pool));
 
@@ -274,6 +317,7 @@ svn_auth_first_credentials(void **creden
       iterstate->realmstring = apr_pstrdup(pool, realmstring);
       iterstate->cache_key = cache_key;
       iterstate->auth_baton = auth_baton;
+      iterstate->parameters = parameters;
       *state = iterstate;
 
       /* Put the creds in the cache */
@@ -319,7 +363,7 @@ svn_auth_next_credentials(void **credent
           SVN_ERR(provider->vtable->next_credentials(&creds,
                                                      state->provider_iter_baton,
                                                      provider->provider_baton,
-                                                     auth_baton->parameters,
+                                                     state->parameters,
                                                      state->realmstring,
                                                      auth_baton->pool));
         }
@@ -687,10 +731,12 @@ svn_auth_get_platform_specific_client_pr
 }
 
 svn_error_t *
-svn_auth__apply_config_for_server(svn_auth_baton_t *auth_baton,
-                                  apr_hash_t *config,
-                                  const char *server_name,
-                                  apr_pool_t *scratch_pool)
+svn_auth__make_session_auth(svn_auth_baton_t **session_auth_baton,
+                            const svn_auth_baton_t *auth_baton,
+                            apr_hash_t *config,
+                            const char *server_name,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool)
 {
   svn_boolean_t store_passwords = SVN_CONFIG_DEFAULT_OPTION_STORE_PASSWORDS;
   svn_boolean_t store_auth_creds = SVN_CONFIG_DEFAULT_OPTION_STORE_AUTH_CREDS;
@@ -702,6 +748,12 @@ svn_auth__apply_config_for_server(svn_au
   svn_config_t *servers = NULL;
   const char *server_group = NULL;
 
+  struct svn_auth_baton_t *ab;
+
+  ab = apr_pmemdup(result_pool, auth_baton, sizeof(*ab));
+
+  ab->slave_parameters = apr_hash_make(result_pool);
+
   /* The 'store-passwords' and 'store-auth-creds' parameters used to
   * live in SVN_CONFIG_CATEGORY_CONFIG. For backward compatibility,
   * if values for these parameters have already been set by our
@@ -716,11 +768,11 @@ svn_auth__apply_config_for_server(svn_au
   * "store-auth-creds = yes" -- they'll get the expected behaviour.
   */
 
-  if (svn_auth_get_parameter(auth_baton,
+  if (svn_auth_get_parameter(ab,
                               SVN_AUTH_PARAM_DONT_STORE_PASSWORDS) != NULL)
     store_passwords = FALSE;
 
-  if (svn_auth_get_parameter(auth_baton,
+  if (svn_auth_get_parameter(ab,
                               SVN_AUTH_PARAM_NO_AUTH_CACHE) != NULL)
     store_auth_creds = FALSE;
 
@@ -806,46 +858,32 @@ svn_auth__apply_config_for_server(svn_au
 
   /* Save auth caching parameters in the auth parameter hash. */
   if (! store_passwords)
-    svn_auth_set_parameter(auth_baton,
+    svn_auth_set_parameter(ab,
                            SVN_AUTH_PARAM_DONT_STORE_PASSWORDS, "");
 
-  svn_auth_set_parameter(auth_baton,
+  svn_auth_set_parameter(ab,
                          SVN_AUTH_PARAM_STORE_PLAINTEXT_PASSWORDS,
                          store_plaintext_passwords);
 
   if (! store_pp)
-    svn_auth_set_parameter(auth_baton,
+    svn_auth_set_parameter(ab,
                            SVN_AUTH_PARAM_DONT_STORE_SSL_CLIENT_CERT_PP,
                            "");
 
-  svn_auth_set_parameter(auth_baton,
+  svn_auth_set_parameter(ab,
                          SVN_AUTH_PARAM_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT,
                          store_pp_plaintext);
 
   if (! store_auth_creds)
-    svn_auth_set_parameter(auth_baton,
-                            SVN_AUTH_PARAM_NO_AUTH_CACHE, "");
+    svn_auth_set_parameter(ab,
+                           SVN_AUTH_PARAM_NO_AUTH_CACHE, "");
 
-  /* ### This setting may have huge side-effects when the auth baton is shared
-     ### between different ra sessions, as it will change which server settings
-     ### will be used for all future auth requests.
-     ###
-     ### E.g. when you connect using a ssl client cert that is specified in the
-     ### config file, you might have it when you first connect... but if you
-     ### then connect to another repository, you might not see the same
-     ### settings when the SSL connection is built up again later on.
-     ###
-     ### Most current usages should probably have been keyed on the realm
-     ### string instead of this magic flag that changes when multiple repositories
-     ### are used.
-     ###
-     ### This especially affects long living ra sessions, such as those on the
-     ### reuse-ra-session branch.
-   */
   if (server_group)
-    svn_auth_set_parameter(auth_baton,
+    svn_auth_set_parameter(ab,
                            SVN_AUTH_PARAM_SERVER_GROUP,
-                           apr_pstrdup(auth_baton->pool, server_group));
+                           apr_pstrdup(ab->pool, server_group));
+
+  *session_auth_baton = ab;
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/config_win.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/config_win.c?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/config_win.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/config_win.c Mon Mar  9 09:53:06 2015
@@ -197,15 +197,15 @@ svn_config__parse_registry(svn_config_t
                      &hkey);
   if (err != ERROR_SUCCESS)
     {
-      const int is_enoent = APR_STATUS_IS_ENOENT(APR_FROM_OS_ERROR(err));
-      if (!is_enoent)
-        return svn_error_createf(SVN_ERR_BAD_FILENAME, NULL,
+      apr_status_t apr_err = APR_FROM_OS_ERROR(err);
+      svn_boolean_t is_enoent = APR_STATUS_IS_ENOENT(apr_err);
+
+      if (must_exist || !is_enoent)
+        return svn_error_createf(SVN_ERR_BAD_FILENAME,
+                                 is_enoent ? NULL
+                                           : svn_error_wrap_apr(apr_err, NULL),
                                  _("Can't open registry key '%s'"),
                                  svn_dirent_local_style(file, pool));
-      else if (must_exist && is_enoent)
-        return svn_error_createf(SVN_ERR_BAD_FILENAME, NULL,
-                                 _("Can't find registry key '%s'"),
-                                 svn_dirent_local_style(file, pool));
       else
         return SVN_NO_ERROR;
     }

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/error.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/error.c?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/error.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/error.c Mon Mar  9 09:53:06 2015
@@ -28,6 +28,10 @@
 #include <apr_pools.h>
 #include <apr_strings.h>
 
+#if defined(SVN_DEBUG) && APR_HAS_THREADS
+#include <apr_thread_proc.h>
+#endif
+
 #include <zlib.h>
 
 #ifndef SVN_ERR__TRACING
@@ -38,12 +42,56 @@
 #include "svn_pools.h"
 #include "svn_utf.h"
 
+#include "private/svn_error_private.h"
+#include "svn_private_config.h"
+
+#if defined(SVN_DEBUG) && APR_HAS_THREADS
+#include "private/svn_atomic.h"
+#include "pools.h"
+#endif
+
+
 #ifdef SVN_DEBUG
-/* XXX FIXME: These should be protected by a thread mutex.
-   svn_error__locate and make_error_internal should cooperate
-   in locking and unlocking it. */
+#  if APR_HAS_THREADS
+static apr_threadkey_t *error_file_key = NULL;
+static apr_threadkey_t *error_line_key = NULL;
+
+/* No-op destructor for apr_threadkey_private_create(). */
+static void null_threadkey_dtor(void *stuff) {}
+
+/* Handler for svn_atomic__init_once used by svn_error__locate to
+   initialize the thread-local error location storage.
+   This function will never return an error. */
+static svn_error_t *
+locate_init_once(void *ignored_baton, apr_pool_t *ignored_pool)
+{
+  /* Strictly speaking, this is a memory leak, since we're creating an
+     unmanaged, top-level pool and never destroying it.  We do this
+     because this pool controls the lifetime of the thread-local
+     storage for error locations, and that storage must always be
+     available. */
+  apr_pool_t *threadkey_pool = svn_pool__create_unmanaged(TRUE);
+  apr_status_t status;
+
+  status = apr_threadkey_private_create(&error_file_key,
+                                        null_threadkey_dtor,
+                                        threadkey_pool);
+  if (status == APR_SUCCESS)
+    status = apr_threadkey_private_create(&error_line_key,
+                                          null_threadkey_dtor,
+                                          threadkey_pool);
+
+  /* If anything went wrong with the creation of the thread-local
+     storage, we'll revert to the old, thread-agnostic behaviour */
+  if (status != APR_SUCCESS)
+    error_file_key = error_line_key = NULL;
+
+  return SVN_NO_ERROR;
+}
+#  endif  /* APR_HAS_THREADS */
 
-/* XXX TODO: Define mutex here #if APR_HAS_THREADS */
+/* These location variables will be used in no-threads mode or if
+   thread-local storage is not available. */
 static const char * volatile error_file = NULL;
 static long volatile error_line = -1;
 
@@ -51,9 +99,6 @@ static long volatile error_line = -1;
 static const char SVN_FILE_LINE_UNDEFINED[] = "svn:<undefined>";
 #endif /* SVN_DEBUG */
 
-#include "svn_private_config.h"
-#include "private/svn_error_private.h"
-
 
 /*
  * Undefine the helpers for creating errors.
@@ -76,11 +121,27 @@ static const char SVN_FILE_LINE_UNDEFINE
 void
 svn_error__locate(const char *file, long line)
 {
-#if defined(SVN_DEBUG)
-  /* XXX TODO: Lock mutex here */
+#ifdef SVN_DEBUG
+#  if APR_HAS_THREADS
+  static volatile svn_atomic_t init_status = 0;
+  svn_error_clear(svn_atomic__init_once(&init_status,
+                                        locate_init_once,
+                                        NULL, NULL));
+
+  if (error_file_key && error_line_key)
+    {
+      apr_status_t status;
+      status = apr_threadkey_private_set((char*)file, error_file_key);
+      if (status == APR_SUCCESS)
+        status = apr_threadkey_private_set((void*)line, error_line_key);
+      if (status == APR_SUCCESS)
+        return;
+    }
+#  endif  /* APR_HAS_THREADS */
+
   error_file = file;
   error_line = line;
-#endif
+#endif /* SVN_DEBUG */
 }
 
 
@@ -103,6 +164,9 @@ make_error_internal(apr_status_t apr_err
 {
   apr_pool_t *pool;
   svn_error_t *new_error;
+#ifdef SVN_DEBUG
+  apr_status_t status = APR_ENOTIMPL;
+#endif
 
   /* Reuse the child's pool, or create our own. */
   if (child)
@@ -121,16 +185,34 @@ make_error_internal(apr_status_t apr_err
   new_error->apr_err = apr_err;
   new_error->child   = child;
   new_error->pool    = pool;
-#if defined(SVN_DEBUG)
-  new_error->file    = error_file;
-  new_error->line    = error_line;
-  /* XXX TODO: Unlock mutex here */
+
+#ifdef SVN_DEBUG
+#if APR_HAS_THREADS
+  if (error_file_key && error_line_key)
+    {
+      void *item;
+      status = apr_threadkey_private_get(&item, error_file_key);
+      if (status == APR_SUCCESS)
+        {
+          new_error->file = item;
+          status = apr_threadkey_private_get(&item, error_line_key);
+          if (status == APR_SUCCESS)
+            new_error->line = (long)item;
+        }
+    }
+#  endif  /* APR_HAS_THREADS */
+
+  if (status != APR_SUCCESS)
+    {
+      new_error->file = error_file;
+      new_error->line = error_line;
+    }
 
   if (! child)
       apr_pool_cleanup_register(pool, new_error,
                                 err_abort,
                                 apr_pool_cleanup_null);
-#endif
+#endif /* SVN_DEBUG */
 
   return new_error;
 }

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/hash.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/hash.c?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/hash.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/hash.c Mon Mar  9 09:53:06 2015
@@ -31,10 +31,14 @@
 #include <apr_hash.h>
 #include <apr_file_io.h>
 
+#ifndef SVN_HASH__GETS_SETS
+#define SVN_HASH__GETS_SETS
+#endif
+#include "svn_hash.h"
+
 #include "svn_types.h"
 #include "svn_string.h"
 #include "svn_error.h"
-#include "svn_hash.h"
 #include "svn_sorts.h"
 #include "svn_io.h"
 #include "svn_pools.h"
@@ -45,7 +49,6 @@
 
 #include "svn_private_config.h"
 
-
 
 
 /*
@@ -560,6 +563,20 @@ svn_hash_from_cstring_keys(apr_hash_t **
 }
 
 
+void *
+svn_hash__gets(apr_hash_t *ht, const char *key)
+{
+  return apr_hash_get(ht, key, APR_HASH_KEY_STRING);
+}
+
+
+void
+svn_hash__sets(apr_hash_t *ht, const char *key, const void *val)
+{
+  apr_hash_set(ht, key, APR_HASH_KEY_STRING, val);
+}
+
+
 
 /*** Specialized getter APIs ***/
 

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/pool.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/pool.c?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/pool.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/pool.c Mon Mar  9 09:53:06 2015
@@ -26,12 +26,15 @@
 #include <stdlib.h>
 #include <stdio.h>
 
+#include <apr.h>
+#include <apr_version.h>
 #include <apr_general.h>
 #include <apr_pools.h>
 #include <apr_thread_mutex.h>
 
 #include "svn_pools.h"
 
+#include "pools.h"
 
 #if APR_POOL_DEBUG
 /* file_line for the non-debug case. */
@@ -140,3 +143,24 @@ svn_pool_create_allocator(svn_boolean_t
 
   return allocator;
 }
+
+
+/*
+ * apr_pool_create_core_ex was introduced in APR 1.3.0, then
+ * deprecated and renamed to apr_pool_create_unmanaged_ex in 1.3.3.
+ * Since our minimum requirement is APR 1.3.0, one or the other of
+ * these functions will always be available.
+ */
+#if !APR_VERSION_AT_LEAST(1,3,3)
+#define apr_pool_create_unmanaged_ex apr_pool_create_core_ex
+#endif
+
+/* Private function that creates an unmanaged pool. */
+apr_pool_t *
+svn_pool__create_unmanaged(svn_boolean_t thread_safe)
+{
+  apr_pool_t *pool;
+  apr_pool_create_unmanaged_ex(&pool, abort_on_pool_failure,
+                               svn_pool_create_allocator(thread_safe));
+  return pool;
+}

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/sqlite.c?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/sqlite.c Mon Mar  9 09:53:06 2015
@@ -1307,7 +1307,7 @@ svn_sqlite__finish_transaction(svn_sqlit
       err2 = get_internal_statement(&stmt, db,
                                     STMT_INTERNAL_ROLLBACK_TRANSACTION);
       if (!err2)
-        err2 = svn_sqlite__step_done(stmt);
+        err2 = svn_error_trace(svn_sqlite__step_done(stmt));
 
       if (err2 && err2->apr_err == SVN_ERR_SQLITE_BUSY)
         {
@@ -1330,14 +1330,14 @@ svn_sqlite__finish_transaction(svn_sqlit
              help diagnosing the original error and help in finding where
              a reset statement is missing. */
 
-          err2 = reset_all_statements(db, err2);
+          err2 = svn_error_trace(reset_all_statements(db, err2));
           err2 = svn_error_compose_create(
-                      svn_sqlite__step_done(stmt),
+                      svn_error_trace(svn_sqlite__step_done(stmt)),
                       err2);
+
         }
 
-      return svn_error_compose_create(err,
-                                      err2);
+      return svn_error_compose_create(err, err2);
     }
 
   SVN_ERR(get_internal_statement(&stmt, db, STMT_INTERNAL_COMMIT_TRANSACTION));
@@ -1358,7 +1358,7 @@ svn_sqlite__finish_savepoint(svn_sqlite_
                                     STMT_INTERNAL_ROLLBACK_TO_SAVEPOINT_SVN);
 
       if (!err2)
-        err2 = svn_sqlite__step_done(stmt);
+        err2 = svn_error_trace(svn_sqlite__step_done(stmt));
 
       if (err2 && err2->apr_err == SVN_ERR_SQLITE_BUSY)
         {
@@ -1368,8 +1368,10 @@ svn_sqlite__finish_savepoint(svn_sqlite_
              ### See huge comment in svn_sqlite__finish_transaction for
                  further details */
 
-          err2 = reset_all_statements(db, err2);
-          err2 = svn_error_compose_create(svn_sqlite__step_done(stmt), err2);
+          err2 = svn_error_trace(reset_all_statements(db, err2));
+          err2 = svn_error_compose_create(
+                      svn_error_trace(svn_sqlite__step_done(stmt)),
+                      err2);
         }
 
       err = svn_error_compose_create(err, err2);
@@ -1377,9 +1379,9 @@ svn_sqlite__finish_savepoint(svn_sqlite_
                                     STMT_INTERNAL_RELEASE_SAVEPOINT_SVN);
 
       if (!err2)
-        err2 = svn_sqlite__step_done(stmt);
+        err2 = svn_error_trace(svn_sqlite__step_done(stmt));
 
-      return svn_error_trace(svn_error_compose_create(err, err2));
+      return svn_error_compose_create(err, err2);
     }
 
   SVN_ERR(get_internal_statement(&stmt, db,

Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/conflicts.c?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_wc/conflicts.c Mon Mar  9 09:53:06 2015
@@ -2338,7 +2338,7 @@ static svn_error_t *
 resolve_prop_conflict_on_node(svn_boolean_t *did_resolve,
                               svn_wc__db_t *db,
                               const char *local_abspath,
-                              const svn_skel_t *conflicts,
+                              svn_skel_t *conflicts,
                               const char *conflicted_propname,
                               svn_wc_conflict_choice_t conflict_choice,
                               const char *merged_file,
@@ -2357,6 +2357,8 @@ resolve_prop_conflict_on_node(svn_boolea
   svn_skel_t *work_items = NULL;
   svn_wc_operation_t operation;
   svn_boolean_t prop_conflicted;
+  apr_hash_t *actual_props;
+  svn_boolean_t resolved_all, resolved_all_prop;
 
   *did_resolve = FALSE;
 
@@ -2372,12 +2374,35 @@ resolve_prop_conflict_on_node(svn_boolea
                                               db, local_abspath, conflicts,
                                               scratch_pool, scratch_pool));
 
+  if (!conflicted_props)
+    {
+      /* We have a pre 1.8 property conflict. Just mark it resolved */
+
+      SVN_ERR(remove_artifact_file_if_exists(&work_items, did_resolve,
+                                             db, local_abspath, prop_reject_file,
+                                             scratch_pool, scratch_pool));
+      SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath, FALSE, TRUE, FALSE,
+                                      work_items, scratch_pool));
+      SVN_ERR(svn_wc__wq_run(db, local_abspath, cancel_func, cancel_baton,
+                             scratch_pool));
+      return SVN_NO_ERROR;
+    }
+
+  if (conflicted_propname[0] != '\0'
+      && !svn_hash_gets(conflicted_props, conflicted_propname))
+    {
+      return SVN_NO_ERROR; /* This property is not conflicted! */
+    }
+
   if (operation == svn_wc_operation_merge)
       SVN_ERR(svn_wc__db_read_pristine_props(&old_props, db, local_abspath,
                                              scratch_pool, scratch_pool));
     else
       old_props = their_old_props;
 
+  SVN_ERR(svn_wc__db_read_props(&actual_props, db, local_abspath,
+                                scratch_pool, scratch_pool));
+
   /* We currently handle *_conflict as *_full as this argument is currently
      always applied for all conflicts on a node at the same time. Giving
      an error would break some tests that assumed that this would just
@@ -2405,11 +2430,7 @@ resolve_prop_conflict_on_node(svn_boolea
     case svn_wc_conflict_choose_merged:
       if ((merged_file || merged_value) && conflicted_propname[0] != '\0')
         {
-          apr_hash_t *actual_props;
-
-          SVN_ERR(svn_wc__db_read_props(&actual_props, db, local_abspath,
-                                        scratch_pool, scratch_pool));
-          resolve_from = actual_props;
+          resolve_from = apr_hash_copy(scratch_pool, actual_props);
 
           if (!merged_value)
             {
@@ -2433,15 +2454,26 @@ resolve_prop_conflict_on_node(svn_boolea
                               _("Invalid 'conflict_result' argument"));
     }
 
-  if (conflicted_props && apr_hash_count(conflicted_props) && resolve_from)
+
+  if (resolve_from)
     {
       apr_hash_index_t *hi;
-      apr_hash_t *actual_props;
+      apr_hash_t *apply_on_props;
 
-      SVN_ERR(svn_wc__db_read_props(&actual_props, db, local_abspath,
-                                    scratch_pool, scratch_pool));
+      if (conflicted_propname[0] == '\0')
+        {
+          /* Apply to all conflicted properties */
+          apply_on_props = conflicted_props;
+        }
+      else
+        {
+          /* Apply to a single property */
+          apply_on_props = apr_hash_make(scratch_pool);
+          svn_hash_sets(apply_on_props, conflicted_propname, "");
+        }
 
-      for (hi = apr_hash_first(scratch_pool, conflicted_props);
+      /* Apply the selected changes */
+      for (hi = apr_hash_first(scratch_pool, apply_on_props);
            hi;
            hi = apr_hash_next(hi))
         {
@@ -2452,28 +2484,67 @@ resolve_prop_conflict_on_node(svn_boolea
 
           svn_hash_sets(actual_props, propname, new_value);
         }
-      SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, actual_props,
-                                      FALSE, NULL, NULL,
-                                      scratch_pool));
     }
+  /*else the user accepted the properties as-is */
 
-  /* Legacy behavior: Only report property conflicts as resolved when the
-     property reject file exists
+  /* This function handles conflicted_propname "" as resolving
+     all property conflicts... Just what we need here */
+  SVN_ERR(svn_wc__conflict_skel_resolve(&resolved_all, conflicts,
+                                        db, local_abspath,
+                                        FALSE, conflicted_propname,
+                                        FALSE,
+                                        scratch_pool, scratch_pool));
 
-     If not the UI shows the conflict as already resolved
-     (and in this case we just remove the in-db conflict) */
+  if (!resolved_all)
+    {
+      /* Are there still property conflicts left? (or only...) */
+      SVN_ERR(svn_wc__conflict_read_info(NULL, NULL, NULL, &prop_conflicted,
+                                         NULL, db, local_abspath, conflicts,
+                                         scratch_pool, scratch_pool));
 
-  {
-    svn_skel_t *work_item;
+      resolved_all_prop = (! prop_conflicted);
+    }
+  else
+    {
+      resolved_all_prop = TRUE;
+      conflicts = NULL;
+    }
 
-    SVN_ERR(remove_artifact_file_if_exists(&work_item, did_resolve,
-                                           db, local_abspath, prop_reject_file,
-                                           scratch_pool, scratch_pool));
-    work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
-  }
+  if (resolved_all_prop)
+    {
+      /* Legacy behavior: Only report property conflicts as resolved when the
+         property reject file exists
+
+         If not the UI shows the conflict as already resolved
+         (and in this case we just remove the in-db conflict) */
+      SVN_ERR(remove_artifact_file_if_exists(&work_items, did_resolve,
+                                             db, local_abspath,
+                                             prop_reject_file,
+                                             scratch_pool, scratch_pool));
+    }
+  else
+    {
+      /* Create a new prej file, based on the remaining conflicts */
+      SVN_ERR(svn_wc__wq_build_prej_install(&work_items,
+                                            db, local_abspath,
+                                            scratch_pool, scratch_pool));
+      *did_resolve = TRUE; /* We resolved a property conflict */
+    }
+
+  /* This installs the updated conflict skel */
+  SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, actual_props,
+                                  FALSE, conflicts, work_items,
+                                  scratch_pool));
+
+  if (resolved_all)
+    {
+      /* Remove the whole conflict. Should probably be integrated
+         into the op_set_props() call */
+      SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath,
+                                          FALSE, TRUE, FALSE,
+                                          NULL, scratch_pool));
+    }
 
-  SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath, FALSE, TRUE, FALSE,
-                                      work_items, scratch_pool));
   SVN_ERR(svn_wc__wq_run(db, local_abspath, cancel_func, cancel_baton,
                          scratch_pool));
 
@@ -2570,7 +2641,8 @@ resolve_tree_conflict_on_node(svn_boolea
                   const char *dup_abspath;
 
                   if (!resolve_later
-                      || err->apr_err != SVN_ERR_WC_OBSTRUCTED_UPDATE)
+                      || (err->apr_err != SVN_ERR_WC_OBSTRUCTED_UPDATE
+                          && err->apr_err != SVN_ERR_WC_FOUND_CONFLICT))
                     return svn_error_trace(err);
 
                   svn_error_clear(err);
@@ -2651,7 +2723,8 @@ resolve_tree_conflict_on_node(svn_boolea
                   const char *dup_abspath;
 
                   if (!resolve_later
-                      || err->apr_err != SVN_ERR_WC_OBSTRUCTED_UPDATE)
+                      || (err->apr_err != SVN_ERR_WC_OBSTRUCTED_UPDATE
+                          && err->apr_err != SVN_ERR_WC_FOUND_CONFLICT))
                     return svn_error_trace(err);
 
                   svn_error_clear(err);
@@ -3014,33 +3087,11 @@ svn_wc__resolve_conflicts(svn_wc_context
                           void *notify_baton,
                           apr_pool_t *scratch_pool)
 {
-  svn_node_kind_t kind;
-  svn_boolean_t conflicted;
   struct conflict_status_walker_baton cswb;
   apr_pool_t *iterpool = NULL;
   svn_error_t *err;
 
-  /* ### the underlying code does NOT support resolving individual
-     ### properties. bail out if the caller tries it.  */
-  if (resolve_prop != NULL && *resolve_prop != '\0')
-    return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
-                            U_("Resolving a single property is not (yet) "
-                               "supported."));
-
-  /* ### Just a versioned check? */
-  /* Conflicted is set to allow invoking on actual only nodes */
-  SVN_ERR(svn_wc__db_read_info(NULL, &kind, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, &conflicted,
-                               NULL, NULL, NULL, NULL, NULL, NULL,
-                               wc_ctx->db, local_abspath,
-                               scratch_pool, scratch_pool));
-
-  /* When the implementation still used the entry walker, depth
-     unknown was translated to infinity. */
-  if (kind != svn_node_dir)
-    depth = svn_depth_empty;
-  else if (depth == svn_depth_unknown)
+  if (depth == svn_depth_unknown)
     depth = svn_depth_infinity;
 
   cswb.db = wc_ctx->db;

Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/externals.c?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_wc/externals.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_wc/externals.c Mon Mar  9 09:53:06 2015
@@ -1496,8 +1496,8 @@ svn_wc__external_remove(svn_wc_context_t
   else
     {
       SVN_ERR(svn_wc__db_base_remove(wc_ctx->db, local_abspath,
-                                     FALSE, FALSE, FALSE,
-                                     SVN_INVALID_REVNUM,
+                                     FALSE, TRUE, FALSE,
+                                     0,
                                      NULL, NULL, scratch_pool));
       SVN_ERR(svn_wc__wq_run(wc_ctx->db, local_abspath,
                              cancel_func, cancel_baton,

Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/status.c?rev=1665166&r1=1665165&r2=1665166&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_wc/status.c Mon Mar  9 09:53:06 2015
@@ -69,6 +69,7 @@ typedef struct svn_wc__internal_status_t
   svn_wc_status3_t s; /* First member; same pointer*/
 
   svn_boolean_t has_descendants;
+  svn_boolean_t op_root;
 
   /* Make sure to update hash_stash() when adding values here */
 } svn_wc__internal_status_t;
@@ -587,7 +588,8 @@ assemble_status(svn_wc__internal_status_
      This filter should match the filter in is_sendable_status() */
   if (! get_all)
     if (((node_status == svn_wc_status_none)
-         || (node_status == svn_wc_status_normal))
+         || (node_status == svn_wc_status_normal)
+         || (node_status == svn_wc_status_deleted && !info->op_root))
 
         && (! switched_p)
         && (! info->locked)
@@ -606,6 +608,7 @@ assemble_status(svn_wc__internal_status_
   inner_stat = apr_pcalloc(result_pool, sizeof(*inner_stat));
   stat = &inner_stat->s;
   inner_stat->has_descendants = info->has_descendants;
+  inner_stat->op_root = info->op_root;
 
   switch (info->kind)
     {
@@ -1484,6 +1487,7 @@ hash_stash(void *baton,
   /* Copy the internal/private data. */
   svn_wc__internal_status_t *is = new_status;
   is->has_descendants = old_status->has_descendants;
+  is->op_root = old_status->op_root;
 
   assert(! svn_hash_gets(stat_hash, path));
   svn_hash_sets(stat_hash, apr_pstrdup(hash_pool, path), new_status);
@@ -1865,7 +1869,9 @@ is_sendable_status(const svn_wc__interna
 
   /* If the text, property or tree state is interesting, send it. */
   if ((status->node_status != svn_wc_status_none)
-       && (status->node_status != svn_wc_status_normal))
+       && (status->node_status != svn_wc_status_normal)
+       && !(status->node_status == svn_wc_status_deleted
+            && !i_status->op_root))
     return TRUE;
 
   /* If it's switched, send it. */