You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2012/03/05 21:34:28 UTC

svn commit: r1297221 [3/7] - in /subversion/branches/ev2-export: ./ build/ac-macros/ build/generator/ build/win32/ notes/ subversion/bindings/javahl/native/ subversion/bindings/javahl/tests/org/apache/subversion/javahl/ subversion/bindings/swig/include...

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/locks.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/locks.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/locks.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/locks.c Mon Mar  5 20:34:22 2012
@@ -412,7 +412,7 @@ handle_lock(serf_request_t *request,
       if (err && APR_STATUS_IS_EOF(err->apr_err))
         {
           ctx->done = TRUE;
-          err = svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED,
+          err = svn_error_createf(SVN_ERR_RA_DAV_FORBIDDEN,
                                   err,
                                   _("Lock request failed: %d %s"),
                                   ctx->status_code, ctx->reason);
@@ -572,44 +572,43 @@ svn_ra_serf__lock(svn_ra_session_t *ra_s
                   svn_boolean_t force,
                   svn_ra_lock_callback_t lock_func,
                   void *lock_baton,
-                  apr_pool_t *pool)
+                  apr_pool_t *scratch_pool)
 {
   svn_ra_serf__session_t *session = ra_session->priv;
   apr_hash_index_t *hi;
-  apr_pool_t *subpool;
+  apr_pool_t *iterpool;
 
-  subpool = svn_pool_create(pool);
+  iterpool = svn_pool_create(scratch_pool);
 
   /* ### TODO for issue 2263: Send all the locks over the wire at once.  This
      loop is just a temporary shim. */
-  for (hi = apr_hash_first(pool, path_revs); hi; hi = apr_hash_next(hi))
+  for (hi = apr_hash_first(scratch_pool, path_revs);
+       hi;
+       hi = apr_hash_next(hi))
     {
       svn_ra_serf__handler_t *handler;
       svn_ra_serf__xml_parser_t *parser_ctx;
       const char *req_url;
       lock_info_t *lock_ctx;
-      const void *key;
-      void *val;
       svn_error_t *err;
       svn_error_t *new_err = NULL;
 
-      svn_pool_clear(subpool);
+      svn_pool_clear(iterpool);
 
-      lock_ctx = apr_pcalloc(subpool, sizeof(*lock_ctx));
+      lock_ctx = apr_pcalloc(iterpool, sizeof(*lock_ctx));
 
-      apr_hash_this(hi, &key, NULL, &val);
-      lock_ctx->pool = subpool;
-      lock_ctx->path = key;
-      lock_ctx->revision = *((svn_revnum_t*)val);
-      lock_ctx->lock = svn_lock_create(subpool);
-      lock_ctx->lock->path = key;
+      lock_ctx->pool = iterpool;
+      lock_ctx->path = svn__apr_hash_index_key(hi);
+      lock_ctx->revision = *((svn_revnum_t*)svn__apr_hash_index_val(hi));
+      lock_ctx->lock = svn_lock_create(iterpool);
+      lock_ctx->lock->path = lock_ctx->path;
       lock_ctx->lock->comment = comment;
 
       lock_ctx->force = force;
       req_url = svn_path_url_add_component2(session->session_url.path,
-                                            lock_ctx->path, subpool);
+                                            lock_ctx->path, iterpool);
 
-      handler = apr_pcalloc(subpool, sizeof(*handler));
+      handler = apr_pcalloc(iterpool, sizeof(*handler));
 
       handler->method = "LOCK";
       handler->path = req_url;
@@ -617,9 +616,9 @@ svn_ra_serf__lock(svn_ra_session_t *ra_s
       handler->conn = session->conns[0];
       handler->session = session;
 
-      parser_ctx = apr_pcalloc(subpool, sizeof(*parser_ctx));
+      parser_ctx = apr_pcalloc(iterpool, sizeof(*parser_ctx));
 
-      parser_ctx->pool = subpool;
+      parser_ctx->pool = iterpool;
       parser_ctx->user_data = lock_ctx;
       parser_ctx->start = start_lock;
       parser_ctx->end = end_lock;
@@ -636,16 +635,18 @@ svn_ra_serf__lock(svn_ra_session_t *ra_s
       handler->response_baton = parser_ctx;
 
       svn_ra_serf__request_create(handler);
-      err = svn_ra_serf__context_run_wait(&lock_ctx->done, session, subpool);
+      err = svn_ra_serf__context_run_wait(&lock_ctx->done, session, iterpool);
 
       if (lock_func)
         new_err = lock_func(lock_baton, lock_ctx->path, TRUE, lock_ctx->lock,
-                            err, subpool);
+                            err, iterpool);
       svn_error_clear(err);
 
       SVN_ERR(new_err);
     }
 
+  svn_pool_destroy(iterpool);
+
   return SVN_NO_ERROR;
 }
 
@@ -677,45 +678,44 @@ svn_ra_serf__unlock(svn_ra_session_t *ra
                     svn_boolean_t force,
                     svn_ra_lock_callback_t lock_func,
                     void *lock_baton,
-                    apr_pool_t *pool)
+                    apr_pool_t *scratch_pool)
 {
   svn_ra_serf__session_t *session = ra_session->priv;
   apr_hash_index_t *hi;
-  apr_pool_t *subpool;
+  apr_pool_t *iterpool;
 
-  subpool = svn_pool_create(pool);
+  iterpool = svn_pool_create(scratch_pool);
 
   /* ### TODO for issue 2263: Send all the locks over the wire at once.  This
      loop is just a temporary shim. */
-  for (hi = apr_hash_first(pool, path_tokens); hi; hi = apr_hash_next(hi))
+  for (hi = apr_hash_first(scratch_pool, path_tokens);
+       hi;
+       hi = apr_hash_next(hi))
     {
       svn_ra_serf__handler_t *handler;
       svn_ra_serf__simple_request_context_t *ctx;
       const char *req_url, *path, *token;
-      const void *key;
-      void *val;
       svn_lock_t *existing_lock = NULL;
       struct unlock_context_t unlock_ctx;
-      svn_error_t *lock_err = NULL;
+      svn_error_t *err = NULL;
+      svn_error_t *new_err = NULL;
+
 
-      svn_pool_clear(subpool);
+      svn_pool_clear(iterpool);
 
-      ctx = apr_pcalloc(subpool, sizeof(*ctx));
-      ctx->pool = subpool;
+      ctx = apr_pcalloc(iterpool, sizeof(*ctx));
+      ctx->pool = iterpool;
 
-      apr_hash_this(hi, &key, NULL, &val);
-      path = key;
-      token = val;
+      path = svn__apr_hash_index_key(hi);
+      token = svn__apr_hash_index_val(hi);
 
       if (force && (!token || token[0] == '\0'))
         {
           SVN_ERR(svn_ra_serf__get_lock(ra_session, &existing_lock, path,
-                                        subpool));
+                                        iterpool));
           token = existing_lock->token;
           if (!token)
             {
-              svn_error_t *err;
-
               err = svn_error_createf(SVN_ERR_RA_NOT_LOCKED, NULL,
                                       _("'%s' is not locked in the repository"),
                                       path);
@@ -723,22 +723,29 @@ svn_ra_serf__unlock(svn_ra_session_t *ra
               if (lock_func)
                 {
                   svn_error_t *err2;
-                  err2 = lock_func(lock_baton, path, FALSE, NULL, err, subpool);
+                  err2 = lock_func(lock_baton, path, FALSE, NULL, err,
+                                   iterpool);
                   svn_error_clear(err);
+                  err = NULL;
                   if (err2)
-                    return err2;
+                    return svn_error_trace(err2);
+                }
+              else
+                {
+                  svn_error_clear(err);
+                  err = NULL;
                 }
               continue;
             }
         }
 
       unlock_ctx.force = force;
-      unlock_ctx.token = apr_pstrcat(subpool, "<", token, ">", (char *)NULL);
+      unlock_ctx.token = apr_pstrcat(iterpool, "<", token, ">", (char *)NULL);
 
       req_url = svn_path_url_add_component2(session->session_url.path, path,
-                                            subpool);
+                                            iterpool);
 
-      handler = apr_pcalloc(subpool, sizeof(*handler));
+      handler = apr_pcalloc(iterpool, sizeof(*handler));
 
       handler->method = "UNLOCK";
       handler->path = req_url;
@@ -752,7 +759,7 @@ svn_ra_serf__unlock(svn_ra_session_t *ra
       handler->response_baton = ctx;
 
       svn_ra_serf__request_create(handler);
-      SVN_ERR(svn_ra_serf__context_run_wait(&ctx->done, session, subpool));
+      SVN_ERR(svn_ra_serf__context_run_wait(&ctx->done, session, iterpool));
 
       switch (ctx->status)
         {
@@ -760,23 +767,25 @@ svn_ra_serf__unlock(svn_ra_session_t *ra
             break; /* OK */
           case 403:
             /* Api users expect this specific error code to detect failures */
-            lock_err = svn_error_createf(SVN_ERR_FS_LOCK_OWNER_MISMATCH, NULL,
-                                         _("Unlock request failed: %d %s"),
-                                         ctx->status, ctx->reason);
+            err = svn_error_createf(SVN_ERR_FS_LOCK_OWNER_MISMATCH, NULL,
+                                    _("Unlock request failed: %d %s"),
+                                    ctx->status, ctx->reason);
             break;
           default:
-            lock_err = svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
-                                   _("Unlock request failed: %d %s"),
-                                   ctx->status, ctx->reason);
+            err = svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
+                                    _("Unlock request failed: %d %s"),
+                                    ctx->status, ctx->reason);
         }
 
       if (lock_func)
-        {
-          SVN_ERR(lock_func(lock_baton, path, FALSE, existing_lock,
-                            lock_err, subpool));
-          svn_error_clear(lock_err);
-        }
+        new_err = lock_func(lock_baton, path, FALSE, existing_lock, err,
+                            iterpool);
+
+      svn_error_clear(err);
+      SVN_ERR(new_err);
     }
 
+  svn_pool_destroy(iterpool);
+
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h Mon Mar  5 20:34:22 2012
@@ -148,6 +148,9 @@ struct svn_ra_serf__session_t {
   svn_cancel_func_t cancel_func;
   void *cancel_baton;
 
+  /* Ev2 shim callbacks */
+  svn_delta_shim_callbacks_t *shim_callbacks;
+
   /* Error that we've received but not yet returned upstream. */
   svn_error_t *pending_error;
 
@@ -1454,6 +1457,11 @@ svn_ra_serf__error_on_status(int status_
                              const char *path,
                              const char *location);
 
+svn_error_t *
+svn_ra_serf__register_editor_shim_callbacks(svn_ra_session_t *session,
+                                    svn_delta_shim_callbacks_t *callbacks);
+
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c Mon Mar  5 20:34:22 2012
@@ -1157,7 +1157,8 @@ static const svn_ra__vtable_t serf_vtabl
   svn_ra_serf__replay,
   svn_ra_serf__has_capability,
   svn_ra_serf__replay_range,
-  svn_ra_serf__get_deleted_rev
+  svn_ra_serf__get_deleted_rev,
+  svn_ra_serf__register_editor_shim_callbacks
 };
 
 svn_error_t *

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c Mon Mar  5 20:34:22 2012
@@ -38,6 +38,7 @@
 #include "svn_private_config.h"
 #include "svn_string.h"
 #include "svn_xml.h"
+#include "../libsvn_ra/ra_loader.h"
 #include "private/svn_dep_compat.h"
 #include "private/svn_fspath.h"
 
@@ -2466,3 +2467,13 @@ svn_ra_serf__error_on_status(int status_
 
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_ra_serf__register_editor_shim_callbacks(svn_ra_session_t *ra_session,
+                                    svn_delta_shim_callbacks_t *callbacks)
+{
+  svn_ra_serf__session_t *session = ra_session->priv;
+
+  session->shim_callbacks = callbacks;
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_svn/client.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_svn/client.c Mon Mar  5 20:34:22 2012
@@ -2496,6 +2496,18 @@ ra_svn_get_deleted_rev(svn_ra_session_t 
   return svn_ra_svn_read_cmd_response(conn, pool, "r", revision_deleted);
 }
 
+static svn_error_t *
+ra_svn_register_editor_shim_callbacks(svn_ra_session_t *session,
+                                      svn_delta_shim_callbacks_t *callbacks)
+{
+  svn_ra_svn__session_baton_t *sess_baton = session->priv;
+  svn_ra_svn_conn_t *conn = sess_baton->conn;
+
+  conn->shim_callbacks = callbacks;
+
+  return SVN_NO_ERROR;
+}
+
 
 static const svn_ra__vtable_t ra_svn_vtable = {
   svn_ra_svn_version,
@@ -2532,7 +2544,8 @@ static const svn_ra__vtable_t ra_svn_vta
   ra_svn_replay,
   ra_svn_has_capability,
   ra_svn_replay_range,
-  ra_svn_get_deleted_rev
+  ra_svn_get_deleted_rev,
+  ra_svn_register_editor_shim_callbacks
 };
 
 svn_error_t *

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_svn/cyrus_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_svn/cyrus_auth.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_svn/cyrus_auth.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_svn/cyrus_auth.c Mon Mar  5 20:34:22 2012
@@ -125,7 +125,7 @@ static int check_result(svn_error_t *err
       svn_error_clear(err);
       return -1;
     }
-    
+
   return 0;
 }
 
@@ -180,9 +180,9 @@ svn_ra_svn__sasl_common_init(apr_pool_t 
                  sasl_mutex_free_cb);
   free_mutexes = apr_array_make(sasl_pool, 0, sizeof(svn_mutex__t *));
   return svn_mutex__init(&array_mutex, TRUE, sasl_pool);
-    
+
 #endif /* APR_HAS_THREADS */
-  
+
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_svn/editorp.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_svn/editorp.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_svn/editorp.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_svn/editorp.c Mon Mar  5 20:34:22 2012
@@ -408,8 +408,6 @@ void svn_ra_svn_get_editor(const svn_del
 {
   svn_delta_editor_t *ra_svn_editor = svn_delta_default_editor(pool);
   ra_svn_edit_baton_t *eb;
-  svn_delta_shim_callbacks_t *shim_callbacks =
-                                    svn_delta_shim_callbacks_default(pool);
 
   eb = apr_palloc(pool, sizeof(*eb));
   eb->conn = conn;
@@ -439,7 +437,7 @@ void svn_ra_svn_get_editor(const svn_del
   *edit_baton = eb;
 
   svn_error_clear(svn_editor__insert_shims(editor, edit_baton, *editor,
-                                           *edit_baton, shim_callbacks,
+                                           *edit_baton, conn->shim_callbacks,
                                            pool, pool));
 }
 

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_svn/marshal.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_svn/marshal.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_svn/marshal.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_svn/marshal.c Mon Mar  5 20:34:22 2012
@@ -125,6 +125,14 @@ svn_error_t *svn_ra_svn_set_capabilities
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_ra_svn__set_shim_callbacks(svn_ra_svn_conn_t *conn,
+                               svn_delta_shim_callbacks_t *shim_callbacks)
+{
+  conn->shim_callbacks = shim_callbacks;
+  return SVN_NO_ERROR;
+}
+
 svn_boolean_t svn_ra_svn_has_capability(svn_ra_svn_conn_t *conn,
                                         const char *capability)
 {

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_svn/ra_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_svn/ra_svn.h?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_svn/ra_svn.h (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_svn/ra_svn.h Mon Mar  5 20:34:22 2012
@@ -87,6 +87,7 @@ struct svn_ra_svn_conn_st {
   apr_hash_t *capabilities;
   int compression_level;
   char *remote_ip;
+  svn_delta_shim_callbacks_t *shim_callbacks;
   apr_pool_t *pool;
 };
 

Modified: subversion/branches/ev2-export/subversion/libsvn_repos/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_repos/commit.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_repos/commit.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_repos/commit.c Mon Mar  5 20:34:22 2012
@@ -783,31 +783,45 @@ abort_edit(void *edit_baton,
 
 
 static svn_error_t *
-prop_fetch_func(apr_hash_t **props,
-                void *baton,
-                const char *path,
-                svn_revnum_t base_revision,
-                apr_pool_t *result_pool,
-                apr_pool_t *scratch_pool)
+rationalize_shim_path(const char **fs_path,
+                      struct edit_baton *eb,
+                      const char *path,
+                      apr_pool_t *result_pool,
+                      apr_pool_t *scratch_pool)
 {
-  struct edit_baton *eb = baton;
-  svn_fs_root_t *fs_root;
-  svn_error_t *err;
-
   if (svn_path_is_url(path))
     {
       /* This is a copyfrom URL. */
       path = svn_uri_skip_ancestor(eb->repos_url, path, scratch_pool);
-      path = svn_fspath__canonicalize(path, scratch_pool);
+      *fs_path = svn_fspath__canonicalize(path, scratch_pool);
     }
   else
     {
       /* This is a base-relative path. */
       if (path[0] != '/')
         /* Get an absolute path for use in the FS. */
-        path = svn_fspath__join(eb->base_path, path, scratch_pool);
+        *fs_path = svn_fspath__join(eb->base_path, path, scratch_pool);
+      else
+        *fs_path = path;
     }
 
+  return SVN_NO_ERROR;
+}
+
+
+static svn_error_t *
+fetch_props_func(apr_hash_t **props,
+                 void *baton,
+                 const char *path,
+                 svn_revnum_t base_revision,
+                 apr_pool_t *result_pool,
+                 apr_pool_t *scratch_pool)
+{
+  struct edit_baton *eb = baton;
+  svn_fs_root_t *fs_root;
+  svn_error_t *err;
+
+  SVN_ERR(rationalize_shim_path(&path, eb, path, scratch_pool, scratch_pool));
   SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs,
                                svn_fs_txn_base_revision(eb->txn),
                                scratch_pool));
@@ -825,7 +839,7 @@ prop_fetch_func(apr_hash_t **props,
 }
 
 static svn_error_t *
-kind_fetch_func(svn_kind_t *kind,
+fetch_kind_func(svn_kind_t *kind,
                 void *baton,
                 const char *path,
                 svn_revnum_t base_revision,
@@ -838,27 +852,14 @@ kind_fetch_func(svn_kind_t *kind,
   if (!SVN_IS_VALID_REVNUM(base_revision))
     base_revision = svn_fs_txn_base_revision(eb->txn);
 
-  if (svn_path_is_url(path))
-    {
-      /* This is a copyfrom URL. */
-      path = svn_uri_skip_ancestor(eb->repos_url, path, scratch_pool);
-      path = svn_fspath__canonicalize(path, scratch_pool);
-    }
-  else
-    {
-      /* This is a base-relative path. */
-      if (path[0] != '/')
-        /* Get an absolute path for use in the FS. */
-        path = svn_fspath__join(eb->base_path, path, scratch_pool);
-    }
-
+  SVN_ERR(rationalize_shim_path(&path, eb, path, scratch_pool, scratch_pool));
   SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs, base_revision, scratch_pool));
 
   SVN_ERR(svn_fs_check_path(&node_kind, fs_root, path, scratch_pool));
   *kind = svn__kind_from_node_kind(node_kind, FALSE);
 
   return SVN_NO_ERROR;
-} 
+}
 
 static svn_error_t *
 fetch_base_func(const char **filename,
@@ -878,20 +879,7 @@ fetch_base_func(const char **filename,
   if (!SVN_IS_VALID_REVNUM(base_revision))
     base_revision = svn_fs_txn_base_revision(eb->txn);
 
-  if (svn_path_is_url(path))
-    {
-      /* This is a copyfrom URL. */
-      path = svn_uri_skip_ancestor(eb->repos_url, path, scratch_pool);
-      path = svn_fspath__canonicalize(path, scratch_pool);
-    }
-  else
-    {
-      /* This is a base-relative path. */
-      if (path[0] != '/')
-        /* Get an absolute path for use in the FS. */
-        path = svn_fspath__join(eb->base_path, path, scratch_pool);
-    }
-
+  SVN_ERR(rationalize_shim_path(&path, eb, path, scratch_pool, scratch_pool));
   SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs, base_revision, scratch_pool));
 
   err = svn_fs_file_contents(&contents, fs_root, path, scratch_pool);
@@ -987,8 +975,8 @@ svn_repos_get_commit_editor5(const svn_d
   *edit_baton = eb;
   *editor = e;
 
-  shim_callbacks->fetch_props_func = prop_fetch_func;
-  shim_callbacks->fetch_kind_func = kind_fetch_func;
+  shim_callbacks->fetch_props_func = fetch_props_func;
+  shim_callbacks->fetch_kind_func = fetch_kind_func;
   shim_callbacks->fetch_base_func = fetch_base_func;
   shim_callbacks->fetch_baton = eb;
 

Modified: subversion/branches/ev2-export/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_repos/dump.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_repos/dump.c Mon Mar  5 20:34:22 2012
@@ -864,8 +864,14 @@ fetch_props_func(apr_hash_t **props,
 {
   struct edit_baton *eb = baton;
   svn_error_t *err;
+  svn_fs_root_t *fs_root;
+
+  if (!SVN_IS_VALID_REVNUM(base_revision))
+    base_revision = eb->current_rev - 1;
 
-  err = svn_fs_node_proplist(props, eb->fs_root, path, result_pool);
+  SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs, base_revision, scratch_pool));
+
+  err = svn_fs_node_proplist(props, fs_root, path, result_pool);
   if (err && err->apr_err == SVN_ERR_FS_NOT_FOUND)
     {
       svn_error_clear(err);
@@ -890,10 +896,9 @@ fetch_kind_func(svn_kind_t *kind,
   svn_fs_root_t *fs_root;
 
   if (!SVN_IS_VALID_REVNUM(base_revision))
-    fs_root = eb->fs_root;
-  else
-    SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs, base_revision,
-                                 scratch_pool));
+    base_revision = eb->current_rev - 1;
+
+  SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs, base_revision, scratch_pool));
 
   SVN_ERR(svn_fs_check_path(&node_kind, fs_root, path, scratch_pool));
   *kind = svn__kind_from_node_kind(node_kind, FALSE);
@@ -917,10 +922,9 @@ fetch_base_func(const char **filename,
   svn_fs_root_t *fs_root;
 
   if (!SVN_IS_VALID_REVNUM(base_revision))
-    fs_root = eb->fs_root;
-  else
-    SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs, base_revision,
-                                 scratch_pool));
+    base_revision = eb->current_rev - 1;
+
+  SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs, base_revision, scratch_pool));
 
   err = svn_fs_file_contents(&contents, fs_root, path, scratch_pool);
   if (err && err->apr_err == SVN_ERR_FS_NOT_FOUND)
@@ -1391,10 +1395,9 @@ svn_repos_verify_fs2(svn_repos_t *repos,
                                "(youngest revision is %ld)"),
                              end_rev, youngest);
 
-  /* Verify global/auxiliary data before verifying revisions. */
-  if (start_rev == 0)
-    SVN_ERR(svn_fs_verify(svn_fs_path(fs, pool), cancel_func, cancel_baton,
-                          pool));
+  /* Verify global/auxiliary data and backend-specific data first. */
+  SVN_ERR(svn_fs_verify(svn_fs_path(fs, pool), cancel_func, cancel_baton,
+                        start_rev, end_rev, pool));
 
   /* Create a notify object that we can reuse within the loop. */
   if (notify_func)
@@ -1415,7 +1418,7 @@ svn_repos_verify_fs2(svn_repos_t *repos,
       /* Get cancellable dump editor, but with our close_directory handler. */
       SVN_ERR(get_dump_editor((const svn_delta_editor_t **)&dump_editor,
                               &dump_edit_baton, fs, rev, "",
-                              svn_stream_empty(pool),
+                              svn_stream_empty(iterpool),
                               NULL, NULL,
                               verify_close_directory,
                               notify_func, notify_baton,
@@ -1432,6 +1435,10 @@ svn_repos_verify_fs2(svn_repos_t *repos,
       SVN_ERR(svn_repos_replay2(to_root, "", SVN_INVALID_REVNUM, FALSE,
                                 cancel_editor, cancel_edit_baton,
                                 NULL, NULL, iterpool));
+      /* While our editor close_edit implementation is a no-op, we still
+         do this for completeness. */
+      SVN_ERR(cancel_editor->close_edit(cancel_edit_baton, iterpool));
+
       SVN_ERR(svn_fs_revision_proplist(&props, fs, rev, iterpool));
 
       if (notify_func)

Modified: subversion/branches/ev2-export/subversion/libsvn_repos/hooks.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_repos/hooks.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_repos/hooks.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_repos/hooks.c Mon Mar  5 20:34:22 2012
@@ -171,8 +171,8 @@ env_from_env_hash(apr_hash_t *env_hash,
   apr_hash_index_t *hi;
   const char **env;
   const char **envp;
-  
-  if (!env_hash)
+
+  if (!env_hash || apr_hash_count(env_hash) == 0)
     return NULL;
 
   env = apr_palloc(result_pool,

Modified: subversion/branches/ev2-export/subversion/libsvn_repos/load-fs-vtable.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_repos/load-fs-vtable.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_repos/load-fs-vtable.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_repos/load-fs-vtable.c Mon Mar  5 20:34:22 2012
@@ -487,7 +487,7 @@ new_revision_record(void **revision_bato
      several separate operations. It is highly susceptible to race conditions.
      Calculate the revision 'offset' for finding copyfrom sources.
      It might be positive or negative. */
-  rb->rev_offset = (apr_int32_t) (rb->rev) - (head_rev + 1);
+  rb->rev_offset = (apr_int32_t) ((rb->rev) - (head_rev + 1));
 
   if ((rb->rev > 0) && (! rb->skipped))
     {
@@ -506,7 +506,7 @@ new_revision_record(void **revision_bato
       if (!SVN_IS_VALID_REVNUM(pb->oldest_old_rev))
         pb->oldest_old_rev = rb->rev;
     }
-  
+
   /* If we're skipping this revision, try to notify someone. */
   if (rb->skipped && pb->notify_func)
     {

Modified: subversion/branches/ev2-export/subversion/libsvn_repos/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_repos/log.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_repos/log.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_repos/log.c Mon Mar  5 20:34:22 2012
@@ -268,7 +268,38 @@ detect_changed(apr_hash_t **changed,
       /* Pre-1.6 revision files don't store the change path kind, so fetch
          it manually. */
       if (item->node_kind == svn_node_unknown)
-        SVN_ERR(svn_fs_check_path(&item->node_kind, root, path, subpool));
+        {
+          svn_fs_root_t *check_root = root;
+          const char *check_path = path;
+
+          /* Deleted items don't exist so check earlier revision.  We
+             know the parent must exist and could be a copy */
+          if (change->change_kind == svn_fs_path_change_delete)
+            {
+              svn_fs_history_t *history;
+              svn_revnum_t prev_rev;
+              const char *parent_path, *name;
+
+              svn_fspath__split(&parent_path, &name, path, subpool);
+
+              SVN_ERR(svn_fs_node_history(&history, root, parent_path,
+                                          subpool));
+
+              /* Two calls because the first call returns the original
+                 revision as the deleted child means it is 'interesting' */
+              SVN_ERR(svn_fs_history_prev(&history, history, TRUE, subpool));
+              SVN_ERR(svn_fs_history_prev(&history, history, TRUE, subpool));
+
+              SVN_ERR(svn_fs_history_location(&parent_path, &prev_rev, history,
+                                              subpool));
+              SVN_ERR(svn_fs_revision_root(&check_root, fs, prev_rev, subpool));
+              check_path = svn_fspath__join(parent_path, name, subpool);
+            }
+
+          SVN_ERR(svn_fs_check_path(&item->node_kind, check_root, check_path,
+                                    subpool));
+        }
+
 
       if ((action == 'A') || (action == 'R'))
         {
@@ -1121,7 +1152,6 @@ send_log(svn_revnum_t rev,
       && log_target_history_as_mergeinfo
       && apr_hash_count(log_target_history_as_mergeinfo))
     {
-      svn_boolean_t path_is_in_history = FALSE;
       apr_hash_index_t *hi;
       apr_pool_t *subpool = svn_pool_create(pool);
 
@@ -1134,10 +1164,12 @@ send_log(svn_revnum_t rev,
            hi;
            hi = apr_hash_next(hi))
         {
+          svn_boolean_t path_is_in_history = FALSE;
           const char *changed_path = svn__apr_hash_index_key(hi);
           apr_hash_index_t *hi2;
           apr_pool_t *inner_subpool = svn_pool_create(subpool);
 
+          /* Look at each path on the log target's mergeinfo. */
           for (hi2 = apr_hash_first(inner_subpool,
                                     log_target_history_as_mergeinfo);
                hi2;
@@ -1148,6 +1180,8 @@ send_log(svn_revnum_t rev,
               apr_array_header_t *rangelist =
                 svn__apr_hash_index_val(hi2);
 
+              /* Check whether CHANGED_PATH at revision REV is a child of
+                 a (path, revision) tuple in LOG_TARGET_HISTORY_AS_MERGEINFO. */
               if (svn_fspath__skip_ancestor(mergeinfo_path, changed_path))
                 {
                   int i;
@@ -1777,7 +1811,7 @@ store_search(svn_mergeinfo_t processed,
                                                   sizeof(svn_merge_range_t*));
       svn_merge_range_t *range = apr_palloc(processed_pool,
                                             sizeof(svn_merge_range_t));
-      
+
       range->start = start;
       range->end = end;
       range->inheritable = TRUE;
@@ -2234,17 +2268,40 @@ svn_repos_get_logs4(svn_repos_t *repos,
       int i;
       apr_pool_t *iterpool = svn_pool_create(pool);
 
+      /* If we are provided an authz callback function, use it to
+         verify that the user has read access to the root path in the
+         first of our revisions.
+
+         ### FIXME:  Strictly speaking, we should be checking this
+         ### access in every revision along the line.  But currently,
+         ### there are no known authz implementations which concern
+         ### themselves with per-revision access.  */
+      if (authz_read_func)
+        {
+          svn_boolean_t readable;
+          svn_fs_root_t *rev_root;
+
+          SVN_ERR(svn_fs_revision_root(&rev_root, fs,
+                                       descending_order ? end : start, pool));
+          SVN_ERR(authz_read_func(&readable, rev_root, "",
+                                  authz_read_baton, pool));
+          if (! readable)
+            return svn_error_create(SVN_ERR_AUTHZ_UNREADABLE, NULL, NULL);
+        }
+
       send_count = end - start + 1;
       if (limit && send_count > limit)
         send_count = limit;
       for (i = 0; i < send_count; ++i)
         {
-          svn_revnum_t rev = start + i;
+          svn_revnum_t rev;
 
           svn_pool_clear(iterpool);
 
           if (descending_order)
             rev = end - i;
+          else
+            rev = start + i;
           SVN_ERR(send_log(rev, fs, NULL, NULL, discover_changed_paths, FALSE,
                            FALSE, revprops, FALSE, receiver,
                            receiver_baton, authz_read_func,

Modified: subversion/branches/ev2-export/subversion/libsvn_repos/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_repos/replay.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_repos/replay.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_repos/replay.c Mon Mar  5 20:34:22 2012
@@ -352,6 +352,116 @@ is_within_base_path(const char *path, co
   return FALSE;
 }
 
+/* Given PATH deleted under ROOT, return in READABLE whether the path was
+   readable prior to the deletion.  Consult COPIES (a stack of 'struct
+   copy_info') and AUTHZ_READ_FUNC. */
+static svn_error_t *
+was_readable(svn_boolean_t *readable,
+             svn_fs_root_t *root,
+             const char *path,
+             apr_array_header_t *copies,
+             svn_repos_authz_func_t authz_read_func,
+             void *authz_read_baton,
+             apr_pool_t *result_pool,
+             apr_pool_t *scratch_pool)
+{
+  svn_fs_root_t *inquire_root;
+  const char *inquire_path;
+  struct copy_info *info = NULL;
+  const char *relpath;
+
+  /* Short circuit. */
+  if (! authz_read_func)
+    {
+      *readable = TRUE;
+      return SVN_NO_ERROR;
+    }
+
+  if (copies->nelts != 0)
+    info = APR_ARRAY_IDX(copies, copies->nelts - 1, struct copy_info *);
+
+  /* Are we under a copy? */
+  if (info && (relpath = svn_relpath_skip_ancestor(info->path, path)))
+    {
+      SVN_ERR(svn_fs_revision_root(&inquire_root, svn_fs_root_fs(root),
+                                   info->copyfrom_rev, scratch_pool));
+      inquire_path = svn_fspath__join(info->copyfrom_path, relpath,
+                                      scratch_pool);
+    }
+  else
+    {
+      /* Compute the revision that ROOT is based on.  (Note that ROOT is not
+         r0's root, since this function is only called for deletions.)
+         ### Need a more succinct way to express this */
+      svn_revnum_t inquire_rev = SVN_INVALID_REVNUM;
+      if (svn_fs_is_txn_root(root))
+        inquire_rev = svn_fs_txn_root_base_revision(root);
+      if (svn_fs_is_revision_root(root))
+        inquire_rev =  svn_fs_revision_root_revision(root)-1;
+      SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(inquire_rev));
+
+      SVN_ERR(svn_fs_revision_root(&inquire_root, svn_fs_root_fs(root),
+                                   inquire_rev, scratch_pool));
+      inquire_path = path;
+    }
+
+  SVN_ERR(authz_read_func(readable, inquire_root, inquire_path,
+                          authz_read_baton, result_pool));
+
+  return SVN_NO_ERROR;
+}
+
+/* Initialize COPYFROM_ROOT, COPYFROM_PATH, and COPYFROM_REV with the
+   revision root, fspath, and revnum of the copyfrom of CHANGE, which
+   corresponds to PATH under ROOT.  If the copyfrom info is valid
+   (i.e., is not (NULL, SVN_INVALID_REVNUM)), then initialize SRC_READABLE
+   too, consulting AUTHZ_READ_FUNC and AUTHZ_READ_BATON if provided. */
+static svn_error_t *
+fill_copyfrom(svn_fs_root_t **copyfrom_root,
+              const char **copyfrom_path,
+              svn_revnum_t *copyfrom_rev,
+              svn_boolean_t *src_readable,
+              svn_fs_root_t *root,
+              svn_fs_path_change2_t *change,
+              svn_repos_authz_func_t authz_read_func,
+              void *authz_read_baton,
+              const char *path,
+              apr_pool_t *result_pool,
+              apr_pool_t *scratch_pool)
+{
+  if (! change->copyfrom_known)
+    {
+      SVN_ERR(svn_fs_copied_from(&(change->copyfrom_rev),
+                                 &(change->copyfrom_path),
+                                 root, path, result_pool));
+      change->copyfrom_known = TRUE;
+    }
+  *copyfrom_rev = change->copyfrom_rev;
+  *copyfrom_path = change->copyfrom_path;
+
+  if (*copyfrom_path && SVN_IS_VALID_REVNUM(*copyfrom_rev))
+    {
+      SVN_ERR(svn_fs_revision_root(copyfrom_root,
+                                   svn_fs_root_fs(root),
+                                   *copyfrom_rev, result_pool));
+
+      if (authz_read_func)
+        {
+          SVN_ERR(authz_read_func(src_readable, *copyfrom_root,
+                                  *copyfrom_path,
+                                  authz_read_baton, result_pool));
+        }
+      else
+        *src_readable = TRUE;
+    }
+  else
+    {
+      *copyfrom_root = NULL;
+      /* SRC_READABLE left uninitialized */
+    }
+  return SVN_NO_ERROR;
+}
+
 static svn_error_t *
 path_driver_cb_func(void **dir_baton,
                     void *parent_baton,
@@ -368,7 +478,6 @@ path_driver_cb_func(void **dir_baton,
   void *file_baton = NULL;
   svn_revnum_t copyfrom_rev;
   const char *copyfrom_path;
-  svn_boolean_t src_readable = TRUE;
   svn_fs_root_t *source_root = cb->compare_root;
   const char *source_fspath = NULL;
   const char *base_path = cb->base_path;
@@ -384,9 +493,9 @@ path_driver_cb_func(void **dir_baton,
   while (cb->copies->nelts > 0
          && ! svn_dirent_is_ancestor(APR_ARRAY_IDX(cb->copies,
                                                    cb->copies->nelts - 1,
-                                                   struct copy_info).path,
+                                                   struct copy_info *)->path,
                                      edit_path))
-    cb->copies->nelts--;
+    apr_array_pop(cb->copies);
 
   change = apr_hash_get(cb->changed_paths, edit_path, APR_HASH_KEY_STRING);
   if (! change)
@@ -419,8 +528,18 @@ path_driver_cb_func(void **dir_baton,
 
   /* Handle any deletions. */
   if (do_delete)
-    SVN_ERR(editor->delete_entry(edit_path, SVN_INVALID_REVNUM,
-                                 parent_baton, pool));
+    {
+      svn_boolean_t readable;
+
+      /* Issue #4121: delete under under a copy, of a path that was unreadable
+         at its pre-copy location. */
+      SVN_ERR(was_readable(&readable, root, edit_path, cb->copies,
+                            cb->authz_read_func, cb->authz_read_baton,
+                            pool, pool));
+      if (readable)
+        SVN_ERR(editor->delete_entry(edit_path, SVN_INVALID_REVNUM,
+                                     parent_baton, pool));
+    }
 
   /* Fetch the node kind if it makes sense to do so. */
   if (! do_delete || do_add)
@@ -437,31 +556,14 @@ path_driver_cb_func(void **dir_baton,
   /* Handle any adds/opens. */
   if (do_add)
     {
-      svn_fs_root_t *copyfrom_root = NULL;
-      /* Was this node copied? */
-      if (! change->copyfrom_known)
-        {
-          SVN_ERR(svn_fs_copied_from(&(change->copyfrom_rev),
-                                     &(change->copyfrom_path),
-                                     root, edit_path, pool));
-          change->copyfrom_known = TRUE;
-        }
-      copyfrom_rev = change->copyfrom_rev;
-      copyfrom_path = change->copyfrom_path;
+      svn_boolean_t src_readable;
+      svn_fs_root_t *copyfrom_root;
 
-      if (copyfrom_path && SVN_IS_VALID_REVNUM(copyfrom_rev))
-        {
-          SVN_ERR(svn_fs_revision_root(&copyfrom_root,
-                                       svn_fs_root_fs(root),
-                                       copyfrom_rev, pool));
-
-          if (cb->authz_read_func)
-            {
-              SVN_ERR(cb->authz_read_func(&src_readable, copyfrom_root,
-                                          copyfrom_path,
-                                          cb->authz_read_baton, pool));
-            }
-        }
+      /* Was this node copied? */
+      SVN_ERR(fill_copyfrom(&copyfrom_root, &copyfrom_path, &copyfrom_rev,
+                            &src_readable, root, change,
+                            cb->authz_read_func, cb->authz_read_baton,
+                            edit_path, pool, pool));
 
       /* If we have a copyfrom path, and we can't read it or we're just
          ignoring it, or the copyfrom rev is prior to the low water mark
@@ -511,11 +613,13 @@ path_driver_cb_func(void **dir_baton,
              (possibly nested) copy operation. */
           if (change->node_kind == svn_node_dir)
             {
-              struct copy_info *info = &APR_ARRAY_PUSH(cb->copies,
-                                                       struct copy_info);
+              struct copy_info *info = apr_pcalloc(cb->pool, sizeof(*info));
+
               info->path = apr_pstrdup(cb->pool, edit_path);
               info->copyfrom_path = apr_pstrdup(cb->pool, copyfrom_path);
               info->copyfrom_rev = copyfrom_rev;
+
+              APR_ARRAY_PUSH(cb->copies, struct copy_info *) = info;
             }
 
           /* Save the source so that we can use it later, when we
@@ -531,11 +635,13 @@ path_driver_cb_func(void **dir_baton,
              past... */
           if (change->node_kind == svn_node_dir && cb->copies->nelts > 0)
             {
-              struct copy_info *info = &APR_ARRAY_PUSH(cb->copies,
-                                                       struct copy_info);
+              struct copy_info *info = apr_pcalloc(cb->pool, sizeof(*info));
+
               info->path = apr_pstrdup(cb->pool, edit_path);
               info->copyfrom_path = NULL;
               info->copyfrom_rev = SVN_INVALID_REVNUM;
+
+              APR_ARRAY_PUSH(cb->copies, struct copy_info *) = info;
             }
           source_root = NULL;
           source_fspath = NULL;
@@ -568,9 +674,9 @@ path_driver_cb_func(void **dir_baton,
          delta source. */
       if (cb->copies->nelts > 0)
         {
-          struct copy_info *info = &APR_ARRAY_IDX(cb->copies,
-                                                  cb->copies->nelts - 1,
-                                                  struct copy_info);
+          struct copy_info *info = APR_ARRAY_IDX(cb->copies,
+                                                 cb->copies->nelts - 1,
+                                                 struct copy_info *);
           if (info->copyfrom_path)
             {
               const char *relpath = svn_relpath_skip_ancestor(info->path,
@@ -597,45 +703,31 @@ path_driver_cb_func(void **dir_baton,
     {
       if (change->prop_mod)
         {
-          if (cb->compare_root)
-            {
-              apr_array_header_t *prop_diffs;
-              apr_hash_t *old_props;
-              apr_hash_t *new_props;
-              int i;
-
-              if (source_root)
-                SVN_ERR(svn_fs_node_proplist(&old_props, source_root,
-                                             source_fspath, pool));
-              else
-                old_props = apr_hash_make(pool);
-
-              SVN_ERR(svn_fs_node_proplist(&new_props, root, edit_path, pool));
-
-              SVN_ERR(svn_prop_diffs(&prop_diffs, new_props, old_props,
-                                     pool));
-
-              for (i = 0; i < prop_diffs->nelts; ++i)
-                {
-                  svn_prop_t *pc = &APR_ARRAY_IDX(prop_diffs, i, svn_prop_t);
-                   if (change->node_kind == svn_node_dir)
-                     SVN_ERR(editor->change_dir_prop(*dir_baton, pc->name,
-                                                     pc->value, pool));
-                   else if (change->node_kind == svn_node_file)
-                     SVN_ERR(editor->change_file_prop(file_baton, pc->name,
-                                                      pc->value, pool));
-                }
-            }
+          apr_array_header_t *prop_diffs;
+          apr_hash_t *old_props;
+          apr_hash_t *new_props;
+          int i;
+
+          if (source_root)
+            SVN_ERR(svn_fs_node_proplist(&old_props, source_root,
+                                         source_fspath, pool));
           else
+            old_props = apr_hash_make(pool);
+
+          SVN_ERR(svn_fs_node_proplist(&new_props, root, edit_path, pool));
+
+          SVN_ERR(svn_prop_diffs(&prop_diffs, new_props, old_props,
+                                 pool));
+
+          for (i = 0; i < prop_diffs->nelts; ++i)
             {
-              /* Just do a dummy prop change to signal that there are *any*
-                 propmods. */
-              if (change->node_kind == svn_node_dir)
-                SVN_ERR(editor->change_dir_prop(*dir_baton, "", NULL,
-                                                pool));
-              else if (change->node_kind == svn_node_file)
-                SVN_ERR(editor->change_file_prop(file_baton, "", NULL,
-                                                 pool));
+              svn_prop_t *pc = &APR_ARRAY_IDX(prop_diffs, i, svn_prop_t);
+               if (change->node_kind == svn_node_dir)
+                 SVN_ERR(editor->change_dir_prop(*dir_baton, pc->name,
+                                                 pc->value, pool));
+               else if (change->node_kind == svn_node_file)
+                 SVN_ERR(editor->change_file_prop(file_baton, pc->name,
+                                                  pc->value, pool));
             }
         }
 
@@ -806,7 +898,7 @@ svn_repos_replay2(svn_fs_root_t *root,
                                    pool));
     }
 
-  cb_baton.copies = apr_array_make(pool, 4, sizeof(struct copy_info));
+  cb_baton.copies = apr_array_make(pool, 4, sizeof(struct copy_info *));
   cb_baton.pool = pool;
 
   /* Determine the revision to use throughout the edit, and call

Modified: subversion/branches/ev2-export/subversion/libsvn_repos/rev_hunt.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_repos/rev_hunt.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_repos/rev_hunt.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_repos/rev_hunt.c Mon Mar  5 20:34:22 2012
@@ -154,6 +154,8 @@ svn_repos_get_committed_info(svn_revnum_
                              const char *path,
                              apr_pool_t *pool)
 {
+  apr_hash_t *revprops;
+  
   svn_fs_t *fs = svn_fs_root_fs(root);
 
   /* ### It might be simpler just to declare that revision
@@ -164,13 +166,16 @@ svn_repos_get_committed_info(svn_revnum_
   /* Get the CR field out of the node's skel. */
   SVN_ERR(svn_fs_node_created_rev(committed_rev, root, path, pool));
 
-  /* Get the date property of this revision. */
-  SVN_ERR(svn_fs_revision_prop(&committed_date_s, fs, *committed_rev,
-                               SVN_PROP_REVISION_DATE, pool));
-
-  /* Get the author property of this revision. */
-  SVN_ERR(svn_fs_revision_prop(&last_author_s, fs, *committed_rev,
-                               SVN_PROP_REVISION_AUTHOR, pool));
+  /* Get the revision properties of this revision. */
+  SVN_ERR(svn_fs_revision_proplist(&revprops, fs, *committed_rev, pool));
+
+  /* Extract date and author from these revprops. */
+  committed_date_s = apr_hash_get(revprops,
+                                  SVN_PROP_REVISION_DATE,
+                                  sizeof(SVN_PROP_REVISION_DATE)-1);
+  last_author_s = apr_hash_get(revprops,
+                               SVN_PROP_REVISION_AUTHOR,
+                               sizeof(SVN_PROP_REVISION_AUTHOR)-1);
 
   *committed_date = committed_date_s ? committed_date_s->data : NULL;
   *last_author = last_author_s ? last_author_s->data : NULL;

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/cache-inprocess.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/cache-inprocess.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/cache-inprocess.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/cache-inprocess.c Mon Mar  5 20:34:22 2012
@@ -201,7 +201,7 @@ inprocess_cache_get_internal(char **buff
 
       *size = entry->size;
     }
-    
+
   return SVN_NO_ERROR;
 }
 
@@ -223,7 +223,7 @@ inprocess_cache_get(void **value_p,
                                                       cache,
                                                       key,
                                                       result_pool));
-    
+
   /* deserialize the buffer content. Usually, this will directly
      modify the buffer content directly.
    */
@@ -445,7 +445,7 @@ inprocess_cache_iter(svn_boolean_t *comp
   b.user_baton = user_baton;
 
   SVN_MUTEX__WITH_LOCK(cache->mutex,
-                       svn_iter_apr_hash(completed, cache->hash, 
+                       svn_iter_apr_hash(completed, cache->hash,
                                          iter_cb, &b, scratch_pool));
 
   return SVN_NO_ERROR;

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/cache-membuffer.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/cache-membuffer.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/cache-membuffer.c Mon Mar  5 20:34:22 2012
@@ -136,6 +136,13 @@
  */
 #define NO_OFFSET APR_UINT64_MAX
 
+/* To save space in our group structure, we only use 32 bit size values
+ * and, therefore, limit the size of each entry to just below 4GB.
+ * Supporting larger items is not a good idea as the data transfer
+ * to and from the cache would block other threads for a very long time.
+ */
+#define MAX_ITEM_SIZE ((apr_uint32_t)(0 - ITEM_ALIGNMENT))
+
 /* Debugging / corruption detection support.
  * If you define this macro, the getter functions will performed expensive
  * checks on the item data, requested keys and entry types. If there is
@@ -395,6 +402,11 @@ struct svn_membuffer_t
    */
   apr_uint64_t data_used;
 
+  /* Largest entry size that we would accept.  For total cache sizes
+   * less than 4TB (sic!), this is determined by the total cache size.
+   */
+  apr_uint64_t max_entry_size;
+
 
   /* Number of used dictionary entries, i.e. number of cached items.
    * In conjunction with hit_count, this is used calculate the average
@@ -591,7 +603,7 @@ get_group_index(svn_membuffer_t **cache,
 
   if (key == NULL)
     return NO_INDEX;
-  
+
   err = svn_checksum(&checksum, svn_checksum_md5, key, len, pool);
   if (err != NULL)
   {
@@ -949,6 +961,7 @@ svn_cache__membuffer_cache_create(svn_me
   apr_uint32_t group_count;
   apr_uint32_t group_init_size;
   apr_uint64_t data_size;
+  apr_uint64_t max_entry_size;
 
   /* Determine a reasonable number of cache segments. Segmentation is
    * only useful for multi-threaded / multi-core servers as it reduces
@@ -992,8 +1005,19 @@ svn_cache__membuffer_cache_create(svn_me
    */
   data_size = total_size - directory_size;
 
+  /* For cache sizes > 4TB, individual cache segments will be larger
+   * than 16GB allowing for >4GB entries.  But caching chunks larger
+   * than 4GB is simply not supported.
+   */
+  max_entry_size = data_size / 4 > MAX_ITEM_SIZE
+                 ? MAX_ITEM_SIZE
+                 : data_size / 4;
+  
   /* to keep the entries small, we use 32 bit indices only
-   * -> we need to ensure that no more then 4G entries exist
+   * -> we need to ensure that no more then 4G entries exist.
+   * 
+   * Note, that this limit could only be exceeded in a very
+   * theoretical setup with about 1EB of cache.
    */
   group_count = directory_size / sizeof(entry_group_t);
   if (group_count >= (APR_UINT32_MAX / GROUP_SIZE))
@@ -1024,6 +1048,7 @@ svn_cache__membuffer_cache_create(svn_me
       c[seg].data = secure_aligned_alloc(pool, (apr_size_t)data_size, FALSE);
       c[seg].current_data = 0;
       c[seg].data_used = 0;
+      c[seg].max_entry_size = max_entry_size;
 
       c[seg].used_entries = 0;
       c[seg].hit_count = 0;
@@ -1055,14 +1080,14 @@ svn_cache__membuffer_cache_create(svn_me
 
 
 /* Try to insert the serialized item given in BUFFER with SIZE into
- * the group GROUP_INDEX of CACHE and uniquely identify it by hash 
- * value TO_FIND. 
- * 
+ * the group GROUP_INDEX of CACHE and uniquely identify it by hash
+ * value TO_FIND.
+ *
  * However, there is no guarantee that it will actually be put into
  * the cache. If there is already some data associated with TO_FIND,
  * it will be removed from the cache even if the new data cannot
  * be inserted.
- * 
+ *
  * Note: This function requires the caller to serialization access.
  * Don't call it directly, call membuffer_cache_get_partial instead.
  */
@@ -1078,7 +1103,7 @@ membuffer_cache_set_internal(svn_membuff
   /* if necessary, enlarge the insertion window.
    */
   if (   buffer != NULL
-      && cache->data_size / 4 > size
+      && cache->max_entry_size >= size
       && ensure_data_insertable(cache, size))
     {
       /* Remove old data for this key, if that exists.
@@ -1165,11 +1190,11 @@ membuffer_cache_set(svn_membuffer_t *cac
 }
 
 /* Look for the cache entry in group GROUP_INDEX of CACHE, identified
- * by the hash value TO_FIND. If no item has been stored for KEY, 
+ * by the hash value TO_FIND. If no item has been stored for KEY,
  * *BUFFER will be NULL. Otherwise, return a copy of the serialized
- * data in *BUFFER and return its size in *ITEM_SIZE. Allocations will 
+ * data in *BUFFER and return its size in *ITEM_SIZE. Allocations will
  * be done in POOL.
- * 
+ *
  * Note: This function requires the caller to serialization access.
  * Don't call it directly, call membuffer_cache_get_partial instead.
  */
@@ -1195,10 +1220,10 @@ membuffer_cache_get_internal(svn_membuff
        */
       *buffer = NULL;
       *item_size = 0;
-  
+
       return SVN_NO_ERROR;
     }
-    
+
   size = ALIGN_VALUE(entry->size);
   *buffer = ALIGN_POINTER(apr_palloc(result_pool, size + ITEM_ALIGNMENT-1));
   memcpy(*buffer, (const char*)cache->data + entry->offset, size);
@@ -1225,7 +1250,7 @@ membuffer_cache_get_internal(svn_membuff
   cache->total_hits++;
 
   *item_size = entry->size;
-  
+
   return SVN_NO_ERROR;
 }
 
@@ -1275,18 +1300,18 @@ membuffer_cache_get(svn_membuffer_t *cac
       *item = NULL;
       return SVN_NO_ERROR;
     }
-    
+
   return deserializer(item, buffer, size, result_pool);
 }
 
 /* Look for the cache entry in group GROUP_INDEX of CACHE, identified
  * by the hash value TO_FIND. FOUND indicates whether that entry exists.
  * If not found, *ITEM will be NULL.
- * 
- * Otherwise, the DESERIALIZER is called with that entry and the BATON 
+ *
+ * Otherwise, the DESERIALIZER is called with that entry and the BATON
  * provided and will extract the desired information. The result is set
  * in *ITEM. Allocations will be done in POOL.
- * 
+ *
  * Note: This function requires the caller to serialization access.
  * Don't call it directly, call membuffer_cache_get_partial instead.
  */
@@ -1307,7 +1332,7 @@ membuffer_cache_get_partial_internal(svn
     {
       *item = NULL;
       *found = FALSE;
-      
+
       return SVN_NO_ERROR;
     }
   else
@@ -1379,10 +1404,10 @@ membuffer_cache_get_partial(svn_membuffe
 /* Look for the cache entry in group GROUP_INDEX of CACHE, identified
  * by the hash value TO_FIND. If no entry has been found, the function
  * returns without modifying the cache.
- * 
+ *
  * Otherwise, FUNC is called with that entry and the BATON provided
  * and may modify the cache entry. Allocations will be done in POOL.
- * 
+ *
  * Note: This function requires the caller to serialization access.
  * Don't call it directly, call membuffer_cache_set_partial instead.
  */
@@ -1452,7 +1477,7 @@ membuffer_cache_set_partial_internal(svn
               /* Remove the old entry and try to make space for the new one.
                */
               drop_entry(cache, entry);
-              if (   (cache->data_size / 4 > size)
+              if (   (cache->max_entry_size >= size)
                   && ensure_data_insertable(cache, size))
                 {
                   /* Write the new entry.
@@ -1823,8 +1848,7 @@ svn_membuffer_cache_is_cachable(void *ca
    * must be small enough to be stored in a 32 bit value.
    */
   svn_membuffer_cache_t *cache = cache_void;
-  return (size < cache->membuffer->data_size / 4)
-      && (size < APR_UINT32_MAX - ITEM_ALIGNMENT);
+  return size <= cache->membuffer->max_entry_size;
 }
 
 /* Add statistics of SEGMENT to INFO.
@@ -1872,7 +1896,7 @@ svn_membuffer_cache_get_info(void *cache
   for (i = 0; i < cache->membuffer->segment_count; ++i)
     {
       svn_membuffer_t *segment = cache->membuffer + i;
-      SVN_MUTEX__WITH_LOCK(segment->mutex, 
+      SVN_MUTEX__WITH_LOCK(segment->mutex,
                            svn_membuffer_get_segment_info(segment, info));
     }
 
@@ -1902,13 +1926,13 @@ svn_membuffer_cache_get_synced(void **va
                                apr_pool_t *result_pool)
 {
   svn_membuffer_cache_t *cache = cache_void;
-  SVN_MUTEX__WITH_LOCK(cache->mutex, 
+  SVN_MUTEX__WITH_LOCK(cache->mutex,
                        svn_membuffer_cache_get(value_p,
                                                found,
                                                cache_void,
                                                key,
                                                result_pool));
-  
+
   return SVN_NO_ERROR;
 }
 
@@ -1921,12 +1945,12 @@ svn_membuffer_cache_set_synced(void *cac
                                apr_pool_t *scratch_pool)
 {
   svn_membuffer_cache_t *cache = cache_void;
-  SVN_MUTEX__WITH_LOCK(cache->mutex, 
+  SVN_MUTEX__WITH_LOCK(cache->mutex,
                        svn_membuffer_cache_set(cache_void,
                                                key,
                                                value,
                                                scratch_pool));
-  
+
   return SVN_NO_ERROR;
 }
 
@@ -1942,7 +1966,7 @@ svn_membuffer_cache_get_partial_synced(v
                                        apr_pool_t *result_pool)
 {
   svn_membuffer_cache_t *cache = cache_void;
-  SVN_MUTEX__WITH_LOCK(cache->mutex, 
+  SVN_MUTEX__WITH_LOCK(cache->mutex,
                        svn_membuffer_cache_get_partial(value_p,
                                                        found,
                                                        cache_void,
@@ -1950,7 +1974,7 @@ svn_membuffer_cache_get_partial_synced(v
                                                        func,
                                                        baton,
                                                        result_pool));
-  
+
   return SVN_NO_ERROR;
 }
 
@@ -1964,13 +1988,13 @@ svn_membuffer_cache_set_partial_synced(v
                                        apr_pool_t *scratch_pool)
 {
   svn_membuffer_cache_t *cache = cache_void;
-  SVN_MUTEX__WITH_LOCK(cache->mutex, 
+  SVN_MUTEX__WITH_LOCK(cache->mutex,
                        svn_membuffer_cache_set_partial(cache_void,
                                                        key,
                                                        func,
                                                        baton,
                                                        scratch_pool));
-  
+
   return SVN_NO_ERROR;
 }
 
@@ -2057,7 +2081,7 @@ svn_cache__create_membuffer_cache(svn_ca
   cache->alloc_counter = 0;
 
   SVN_ERR(svn_mutex__init(&cache->mutex, thread_safe, pool));
-  
+
   /* for performance reasons, we don't actually store the full prefix but a
    * hash value of it
    */
@@ -2078,7 +2102,7 @@ svn_cache__create_membuffer_cache(svn_ca
 
   /* initialize the generic cache wrapper
    */
-  wrapper->vtable = thread_safe ? &membuffer_cache_synced_vtable 
+  wrapper->vtable = thread_safe ? &membuffer_cache_synced_vtable
                                 : &membuffer_cache_vtable;
   wrapper->cache_internal = cache;
   wrapper->error_handler = 0;

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/cache-memcache.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/cache-memcache.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/cache-memcache.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/cache-memcache.c Mon Mar  5 20:34:22 2012
@@ -148,7 +148,7 @@ memcache_internal_get(char **data,
       *found = FALSE;
       return SVN_NO_ERROR;
     }
-  
+
   subpool = svn_pool_create(pool);
   SVN_ERR(build_key(&mc_key, cache, key, subpool));
 
@@ -253,7 +253,7 @@ memcache_set(void *cache_void,
 
   if (key == NULL)
     return SVN_NO_ERROR;
-  
+
   if (cache->serialize_func)
     {
       SVN_ERR((cache->serialize_func)(&data, &data_len, value, subpool));

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/gpg_agent.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/gpg_agent.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/gpg_agent.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/gpg_agent.c Mon Mar  5 20:34:22 2012
@@ -169,7 +169,7 @@ password_get_gpg_agent(svn_boolean_t *do
   const char *p = NULL;
   char *ep = NULL;
   char *buffer;
-  
+
   apr_array_header_t *socket_details;
   const char *request = NULL;
   const char *cache_id = NULL;
@@ -204,7 +204,7 @@ password_get_gpg_agent(svn_boolean_t *do
       sd = socket(AF_UNIX, SOCK_STREAM, 0);
       if (sd == -1)
         return SVN_NO_ERROR;
-    
+
       if (connect(sd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
         {
           close(sd);
@@ -363,7 +363,7 @@ password_get_gpg_agent(svn_boolean_t *do
 
   if (strncmp(buffer, "ERR", 3) == 0)
     return SVN_NO_ERROR;
-  
+
   p = NULL;
   if (strncmp(buffer, "D", 1) == 0)
     p = &buffer[2];

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/mergeinfo.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/mergeinfo.c Mon Mar  5 20:34:22 2012
@@ -1112,12 +1112,12 @@ svn_rangelist_merge2(apr_array_header_t 
                           j++;
                         }
                     }
-                  else 
+                  else
                     {
                       /* CHANGE and RANGE share the same start rev, but
                          CHANGE is considered older because its end rev
                          is older.
-                         
+
                          Insert the intersection of RANGE and CHANGE into
                          RANGELIST and then set RANGE to the non-intersecting
                          portion of RANGE. */

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/skel.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/skel.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/skel.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/skel.c Mon Mar  5 20:34:22 2012
@@ -138,7 +138,7 @@ getsize(const char *data, apr_size_t len
 /* Store the ASCII decimal representation of VALUE at DATA.  Return
    the length of the representation if all goes well; return zero if
    the result doesn't fit in LEN bytes.  */
-static int
+static apr_size_t
 putsize(char *data, apr_size_t len, apr_size_t value)
 {
   apr_size_t i = 0;
@@ -157,7 +157,7 @@ putsize(char *data, apr_size_t len, apr_
 
   /* Put the digits in most-significant-first order.  */
   {
-    int left, right;
+    apr_size_t left, right;
 
     for (left = 0, right = i-1; left < right; left++, right--)
       {
@@ -492,7 +492,7 @@ unparse(const svn_skel_t *skel, svn_stri
         {
           /* Append the length to STR.  */
           char buf[200];
-          int length_len;
+          apr_size_t length_len;
 
           length_len = putsize(buf, sizeof(buf), skel->len);
 

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/sqlite.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/sqlite.c Mon Mar  5 20:34:22 2012
@@ -120,16 +120,17 @@ struct svn_sqlite__value_t
 {                                                                \
   int sqlite_err__temp = (x);                                    \
   if (sqlite_err__temp != SQLITE_OK)                             \
-    return svn_error_create(SQLITE_ERROR_CODE(sqlite_err__temp), \
-                            NULL, sqlite3_errmsg((db)->db3));    \
+    return svn_error_createf(SQLITE_ERROR_CODE(sqlite_err__temp), \
+                             NULL, "sqlite: %s",                 \
+                             sqlite3_errmsg((db)->db3));         \
 } while (0)
 
 #define SQLITE_ERR_MSG(x, msg) do                                \
 {                                                                \
   int sqlite_err__temp = (x);                                    \
   if (sqlite_err__temp != SQLITE_OK)                             \
-    return svn_error_create(SQLITE_ERROR_CODE(sqlite_err__temp), \
-                            NULL, msg);                          \
+    return svn_error_createf(SQLITE_ERROR_CODE(sqlite_err__temp), \
+                             NULL, "sqlite: %s", (msg));         \
 } while (0)
 
 
@@ -245,8 +246,8 @@ svn_sqlite__step(svn_boolean_t *got_row,
     {
       svn_error_t *err1, *err2;
 
-      err1 = svn_error_create(SQLITE_ERROR_CODE(sqlite_result), NULL,
-                              sqlite3_errmsg(stmt->db->db3));
+      err1 = svn_error_createf(SQLITE_ERROR_CODE(sqlite_result), NULL,
+                               "sqlite: %s", sqlite3_errmsg(stmt->db->db3));
       err2 = svn_sqlite__reset(stmt);
       return svn_error_compose_create(err1, err2);
     }
@@ -678,14 +679,15 @@ internal_open(sqlite3 **db3, const char 
       int err_code = sqlite3_open_v2(path, db3, flags, NULL);
       if (err_code != SQLITE_OK)
         {
+          /* Save the error message before closing the SQLite handle. */
           char *msg = apr_pstrdup(scratch_pool, sqlite3_errmsg(*db3));
 
           /* We don't catch the error here, since we care more about the open
              error than the close error at this point. */
           sqlite3_close(*db3);
 
-          msg = apr_pstrcat(scratch_pool, msg, ": '", path, "'", (char *)NULL);
-          return svn_error_create(SQLITE_ERROR_CODE(err_code), NULL, msg);
+          return svn_error_createf(SQLITE_ERROR_CODE(err_code), NULL,
+                                   "sqlite: %s: '%s'", msg, path);
         }
     }
   }

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/stream.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/stream.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/stream.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/stream.c Mon Mar  5 20:34:22 2012
@@ -1008,7 +1008,7 @@ read_handler_gz(void *baton, char *buffe
     }
 
   btn->in->next_out = (Bytef *) buffer;
-  btn->in->avail_out = *len;
+  btn->in->avail_out = (uInt) *len;
 
   while (btn->in->avail_out > 0)
     {
@@ -1067,12 +1067,12 @@ write_handler_gz(void *baton, const char
   write_buf = apr_palloc(subpool, buf_size);
 
   btn->out->next_in = (Bytef *) buffer;  /* Casting away const! */
-  btn->out->avail_in = *len;
+  btn->out->avail_in = (uInt) *len;
 
   while (btn->out->avail_in > 0)
     {
       btn->out->next_out = write_buf;
-      btn->out->avail_out = buf_size;
+      btn->out->avail_out = (uInt) buf_size;
 
       zerr = deflate(btn->out, Z_NO_FLUSH);
       SVN_ERR(svn_error__wrap_zlib(zerr, "deflate", btn->out->msg));

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/svn_mutex.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/svn_mutex.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/svn_mutex.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/svn_mutex.c Mon Mar  5 20:34:22 2012
@@ -25,8 +25,8 @@
 #include "private/svn_mutex.h"
 
 svn_error_t *
-svn_mutex__init(svn_mutex__t **mutex_p, 
-                svn_boolean_t mutex_required, 
+svn_mutex__init(svn_mutex__t **mutex_p,
+                svn_boolean_t mutex_required,
                 apr_pool_t *result_pool)
 {
   /* always initialize the mutex pointer, even though it is not
@@ -47,7 +47,7 @@ svn_mutex__init(svn_mutex__t **mutex_p, 
       *mutex_p = apr_mutex;
     }
 #endif
-    
+
   return SVN_NO_ERROR;
 }
 
@@ -67,7 +67,7 @@ svn_mutex__lock(svn_mutex__t *mutex)
 }
 
 svn_error_t *
-svn_mutex__unlock(svn_mutex__t *mutex, 
+svn_mutex__unlock(svn_mutex__t *mutex,
                   svn_error_t *err)
 {
 #if APR_HAS_THREADS

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/svn_string.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/svn_string.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/svn_string.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/svn_string.c Mon Mar  5 20:34:22 2012
@@ -133,7 +133,7 @@ create_string(const char *data, apr_size
 }
 
 static char empty_buffer[1] = {0};
-  
+
 svn_string_t *
 svn_string_create_empty(apr_pool_t *pool)
 {
@@ -302,7 +302,7 @@ svn_stringbuf_create_empty(apr_pool_t *p
 {
   /* All instances share the same zero-length buffer.
    * Some algorithms, however, assume that they may write
-   * the terminating zero. So, empty_buffer must be writable 
+   * the terminating zero. So, empty_buffer must be writable
    * (a simple (char *)"" will cause SEGFAULTs). */
 
   return create_stringbuf(empty_buffer, 0, 0, pool);
@@ -717,7 +717,7 @@ svn_cstring_match_list(const char *str, 
   return FALSE;
 }
 
-char * 
+char *
 svn_cstring_tokenize(const char *sep, char **str)
 {
     char *token;
@@ -742,7 +742,7 @@ svn_cstring_tokenize(const char *sep, ch
         return NULL;
 
     /* skip valid token characters to terminate token and
-     * prepare for the next call (will terminate at '\0) 
+     * prepare for the next call (will terminate at '\0)
      */
     next = strchr(token, csep);
     if (next == NULL)

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/utf.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/utf.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/utf.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/utf.c Mon Mar  5 20:34:22 2012
@@ -200,8 +200,8 @@ atomic_swap(void * volatile * mem, void 
 #endif
 }
 
-/* Set *RET to a newly created handle node for converting from FROMPAGE 
-   to TOPAGE, If apr_xlate_open() returns APR_EINVAL or APR_ENOTIMPL, set 
+/* Set *RET to a newly created handle node for converting from FROMPAGE
+   to TOPAGE, If apr_xlate_open() returns APR_EINVAL or APR_ENOTIMPL, set
    (*RET)->handle to NULL.  If fail for any other reason, return the error.
    Allocate *RET and its xlate handle in POOL. */
 static svn_error_t *
@@ -274,11 +274,11 @@ xlate_alloc_handle(xlate_handle_node_t *
 
 /* Extend xlate_alloc_handle by using USERDATA_KEY as a key in our
    global hash map, if available.
-   
+
    Allocate *RET and its xlate handle in POOL if svn_utf_initialize()
    hasn't been called or USERDATA_KEY is NULL.  Else, allocate them
    in the pool of xlate_handle_hash.
-   
+
    Note: this function is not thread-safe. Call get_xlate_handle_node
    instead. */
 static svn_error_t *
@@ -292,7 +292,7 @@ get_xlate_handle_node_internal(xlate_han
       xlate_handle_node_t *old_node = NULL;
 
       /* 2nd level: hash lookup */
-      xlate_handle_node_t **old_node_p = apr_hash_get(xlate_handle_hash, 
+      xlate_handle_node_t **old_node_p = apr_hash_get(xlate_handle_hash,
                                                       userdata_key,
                                                       APR_HASH_KEY_STRING);
       if (old_node_p)
@@ -381,7 +381,7 @@ get_xlate_handle_node(xlate_handle_node_
 }
 
 /* Put back NODE into the xlate handle cache for use by other calls.
-   
+
    Note: this function is not thread-safe. Call put_xlate_handle_node
    instead. */
 static svn_error_t *
@@ -403,7 +403,7 @@ put_xlate_handle_node_internal(xlate_han
     }
   node->next = *node_p;
   *node_p = node;
-  
+
   return SVN_NO_ERROR;
 }
 
@@ -431,7 +431,7 @@ put_xlate_handle_node(xlate_handle_node_
         return SVN_NO_ERROR;
 
       SVN_MUTEX__WITH_LOCK(xlate_handle_mutex,
-                           put_xlate_handle_node_internal(node, 
+                           put_xlate_handle_node_internal(node,
                                                           userdata_key));
     }
   else
@@ -439,7 +439,7 @@ put_xlate_handle_node(xlate_handle_node_
       /* Store it in the per-pool cache. */
       apr_pool_userdata_set(node, userdata_key, apr_pool_cleanup_null, pool);
     }
-    
+
   return SVN_NO_ERROR;
 }
 
@@ -748,7 +748,7 @@ svn_utf_stringbuf_to_utf8(svn_stringbuf_
 
   return svn_error_compose_create(err,
                                   put_xlate_handle_node
-                                     (node, 
+                                     (node,
                                       SVN_UTF_NTOU_XLATE_HANDLE,
                                       pool));
 }
@@ -782,7 +782,7 @@ svn_utf_string_to_utf8(const svn_string_
 
   return svn_error_compose_create(err,
                                   put_xlate_handle_node
-                                     (node, 
+                                     (node,
                                       SVN_UTF_NTOU_XLATE_HANDLE,
                                       pool));
 }
@@ -827,7 +827,7 @@ svn_utf_cstring_to_utf8(const char **des
   err = convert_cstring(dest, src, node, pool);
   SVN_ERR(svn_error_compose_create(err,
                                    put_xlate_handle_node
-                                      (node, 
+                                      (node,
                                        SVN_UTF_NTOU_XLATE_HANDLE,
                                        pool)));
   return check_cstring_utf8(*dest, pool);
@@ -850,7 +850,7 @@ svn_utf_cstring_to_utf8_ex2(const char *
   err = convert_cstring(dest, src, node, pool);
   SVN_ERR(svn_error_compose_create(err,
                                    put_xlate_handle_node
-                                      (node, 
+                                      (node,
                                        SVN_UTF_NTOU_XLATE_HANDLE,
                                        pool)));
 

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c Mon Mar  5 20:34:22 2012
@@ -610,8 +610,7 @@ svn_wc__delete_many(svn_wc_context_t *wc
   svn_error_t *err;
   svn_wc__db_status_t status;
   svn_kind_t kind;
-  svn_boolean_t conflicted;
-  const apr_array_header_t *conflicts;
+  const apr_array_header_t *conflicts = NULL;
   apr_array_header_t *versioned_targets;
   const char *local_abspath;
   int i;
@@ -622,6 +621,8 @@ svn_wc__delete_many(svn_wc_context_t *wc
                                      sizeof(const char *));
   for (i = 0; i < targets->nelts; i++)
     {
+      svn_boolean_t conflicted = FALSE;
+
       svn_pool_clear(iterpool);
 
       local_abspath = APR_ARRAY_IDX(targets, i, const char *);
@@ -699,7 +700,7 @@ svn_wc__delete_many(svn_wc_context_t *wc
                                     cancel_func, cancel_baton,
                                     notify_func, notify_baton, scratch_pool));
 
-  if (!keep_local && conflicted && conflicts != NULL)
+  if (!keep_local && conflicts != NULL)
     {
       svn_pool_clear(iterpool);
 
@@ -1711,7 +1712,7 @@ revert_restore(svn_wc__db_t *db,
           svn_boolean_t removed;
 
           SVN_ERR(revert_restore_handle_copied_dirs(&removed, db,
-                                                    local_abspath, TRUE, 
+                                                    local_abspath, TRUE,
                                                     cancel_func, cancel_baton,
                                                     scratch_pool));
           if (removed)
@@ -1736,8 +1737,15 @@ revert_restore(svn_wc__db_t *db,
         }
       else if (on_disk == svn_node_file && kind != svn_kind_file)
         {
-          SVN_ERR(svn_io_remove_file2(local_abspath, FALSE, scratch_pool));
-          on_disk = svn_node_none;
+#ifdef HAVE_SYMLINK
+          /* Preserve symlinks pointing at directories. Changes on the
+           * directory node have been reverted. The symlink should remain. */
+          if (!(special && kind == svn_kind_dir))
+#endif
+            {
+              SVN_ERR(svn_io_remove_file2(local_abspath, FALSE, scratch_pool));
+              on_disk = svn_node_none;
+            }
         }
       else if (on_disk == svn_node_file)
         {

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/entries.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/entries.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/entries.c Mon Mar  5 20:34:22 2012
@@ -1897,7 +1897,7 @@ write_entry(struct write_baton **entry_n
         }
       else if (entry->absent)
         {
-          SVN_ERR_ASSERT(base_node->presence 
+          SVN_ERR_ASSERT(base_node->presence
                                 == svn_wc__db_status_server_excluded);
           /* ### should be svn_node_unknown, but let's store what we have. */
           base_node->kind = entry->kind;

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/externals.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/externals.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/externals.c Mon Mar  5 20:34:22 2012
@@ -1181,7 +1181,7 @@ svn_wc__committable_externals_below(apr_
                                                  local_abspath,
                                                  depth != svn_depth_infinity,
                                                  result_pool, scratch_pool));
-  
+
   if (orig_externals == NULL)
     return SVN_NO_ERROR;
 
@@ -1363,6 +1363,16 @@ svn_wc__externals_gather_definitions(apr
     }
 }
 
+svn_error_t *
+svn_wc__close_db(const char *external_abspath,
+                 svn_wc_context_t *wc_ctx,
+                 apr_pool_t *scratch_pool)
+{
+  SVN_ERR(svn_wc__db_drop_root(wc_ctx->db, external_abspath,
+                               scratch_pool));
+  return SVN_NO_ERROR;
+}
+
 /* Return the scheme of @a uri in @a scheme allocated from @a pool.
    If @a uri does not appear to be a valid URI, then @a scheme will
    not be updated.  */

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/props.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/props.c Mon Mar  5 20:34:22 2012
@@ -2546,7 +2546,8 @@ svn_wc_canonicalize_svn_prop(const svn_s
            || strcmp(propname, SVN_PROP_EXTERNALS) == 0)
     {
       /* Make sure that the last line ends in a newline */
-      if (propval->data[propval->len - 1] != '\n')
+      if (propval->len == 0
+          || propval->data[propval->len - 1] != '\n')
         {
           new_value = svn_stringbuf_create_from_string(propval, pool);
           svn_stringbuf_appendbyte(new_value, '\n');

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/status.c?rev=1297221&r1=1297220&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/status.c Mon Mar  5 20:34:22 2012
@@ -294,7 +294,7 @@ read_info(const struct svn_wc__db_info_t
         {
           const char *moved_to_abspath;
           const char *moved_to_op_root_abspath;
-          
+
           /* NOTE: we can't use op-root-ness as a condition here since a base
            * node can be the root of a move and still not be an explicit
            * op-root (having a working node with op_depth == pathelements).
@@ -303,7 +303,7 @@ read_info(const struct svn_wc__db_info_t
            *   svn mv a/b bb
            *   svn del a
            * and
-           *   svn mv a aa  
+           *   svn mv a aa
            *   svn mv aa/b bb
            * In both, 'bb' is moved from 'a/b', but 'a/b' has no op_depth>0
            * node at all, as its parent 'a' is locally deleted. */
@@ -526,9 +526,17 @@ assemble_status(svn_wc_status3_t **statu
           if (!info->have_base)
             copied = TRUE;
           else
-            SVN_ERR(svn_wc__internal_node_get_schedule(NULL, &copied,
-                                                       db, local_abspath,
-                                                       scratch_pool));
+            {
+              const char *work_del_abspath;
+
+              /* Find out details of our deletion.  */
+              SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL,
+                                               &work_del_abspath, NULL,
+                                               db, local_abspath,
+                                               scratch_pool, scratch_pool));
+              if (work_del_abspath)
+                copied = TRUE; /* Working deletion */
+            }
         }
       else if (!dirent || dirent->kind != svn_node_dir)
         {
@@ -544,11 +552,17 @@ assemble_status(svn_wc_status3_t **statu
     {
       if (info->status == svn_wc__db_status_deleted)
         {
+          const char *work_del_abspath;
+
           node_status = svn_wc_status_deleted;
 
-          SVN_ERR(svn_wc__internal_node_get_schedule(NULL, &copied,
-                                                     db, local_abspath,
-                                                     scratch_pool));
+          /* Find out details of our deletion.  */
+          SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL,
+                                           &work_del_abspath, NULL,
+                                           db, local_abspath,
+                                           scratch_pool, scratch_pool));
+          if (work_del_abspath)
+            copied = TRUE; /* Working deletion */
         }
       else if (!dirent || dirent->kind != svn_node_file)
         {
@@ -1203,7 +1217,7 @@ one_child_status(const struct walk_statu
   /* The node exists on disk but there is no versioned information about it,
    * or it doesn't exist but is a tree conflicted path or should be
    * reported not-present. */
-   
+
   /* Why pass ignore patterns on a tree conflicted node, even if it should
    * always show up in clients' status reports anyway? Because the calling
    * client decides whether to ignore, and thus this flag needs to be
@@ -1318,13 +1332,37 @@ get_dir_status(const struct walk_status_
 
   /* Handle "this-dir" first. */
   if (! skip_this_dir)
-    SVN_ERR(send_status_structure(wb, local_abspath,
-                                  parent_repos_root_url,
-                                  parent_repos_relpath,
-                                  parent_repos_uuid,
-                                  dir_info, dirent, get_all,
-                                  status_func, status_baton,
-                                  iterpool));
+    {
+#ifdef HAVE_SYMLINK
+      if (dirent->special)
+        {
+          svn_io_dirent2_t *this_dirent = svn_io_dirent2_dup(dirent, iterpool);
+
+          /* We're being pointed to "this-dir" via a symlink.
+           * Get the real node kind and pretend the path is not a symlink.
+           * This prevents send_status_structure() from treating this-dir
+           * as a directory obstructed by a file. */
+          SVN_ERR(svn_io_check_resolved_path(local_abspath,
+                                             &this_dirent->kind, iterpool));
+          this_dirent->special = FALSE;
+          SVN_ERR(send_status_structure(wb, local_abspath,
+                                        parent_repos_root_url,
+                                        parent_repos_relpath,
+                                        parent_repos_uuid,
+                                        dir_info, this_dirent, get_all,
+                                        status_func, status_baton,
+                                        iterpool));
+        }
+     else
+#endif
+        SVN_ERR(send_status_structure(wb, local_abspath,
+                                      parent_repos_root_url,
+                                      parent_repos_relpath,
+                                      parent_repos_uuid,
+                                      dir_info, dirent, get_all,
+                                      status_func, status_baton,
+                                      iterpool));
+    }
 
   /* If the requested depth is empty, we only need status on this-dir. */
   if (depth == svn_depth_empty)
@@ -1594,9 +1632,9 @@ tweak_statushash(void *baton,
           else
             statstruct->repos_relpath = apr_pstrdup(pool, b->repos_relpath);
 
-          statstruct->repos_root_url = 
+          statstruct->repos_root_url =
                               b->edit_baton->anchor_status->repos_root_url;
-          statstruct->repos_uuid = 
+          statstruct->repos_uuid =
                               b->edit_baton->anchor_status->repos_uuid;
         }