You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2013/10/15 10:52:18 UTC

svn commit: r1532250 [12/37] - in /subversion/branches/cache-server: ./ build/ build/ac-macros/ build/generator/ build/generator/swig/ build/generator/templates/ contrib/client-side/emacs/ contrib/hook-scripts/ contrib/server-side/fsfsfixer/ contrib/se...

Modified: subversion/branches/cache-server/subversion/libsvn_client/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_client/mergeinfo.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_client/mergeinfo.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_client/mergeinfo.c Tue Oct 15 08:52:06 2013
@@ -24,6 +24,7 @@
 #include <apr_pools.h>
 #include <apr_strings.h>
 
+#include "svn_private_config.h"
 #include "svn_pools.h"
 #include "svn_dirent_uri.h"
 #include "svn_path.h"
@@ -46,7 +47,6 @@
 #include "private/svn_client_private.h"
 #include "client.h"
 #include "mergeinfo.h"
-#include "svn_private_config.h"
 
 
 
@@ -1021,6 +1021,11 @@ svn_client__elide_mergeinfo(const char *
    Set *REPOS_ROOT to the root URL of the repository associated with
    PATH_OR_URL.
 
+   If RA_SESSION is NOT NULL and PATH_OR_URL refers to a URL, RA_SESSION
+   (which must be of the repository containing PATH_OR_URL) will be used
+   instead of a temporary RA session. Caller is responsible for reparenting
+   the session if it wants to use it after the call.
+
    Allocate *MERGEINFO_CATALOG and all its contents in RESULT_POOL.  Use
    SCRATCH_POOL for all temporary allocations.
 
@@ -1034,17 +1039,30 @@ get_mergeinfo(svn_mergeinfo_catalog_t *m
               svn_boolean_t include_descendants,
               svn_boolean_t ignore_invalid_mergeinfo,
               svn_client_ctx_t *ctx,
+              svn_ra_session_t *ra_session,
               apr_pool_t *result_pool,
               apr_pool_t *scratch_pool)
 {
-  svn_ra_session_t *ra_session;
   const char *local_abspath;
   svn_boolean_t use_url = svn_path_is_url(path_or_url);
   svn_client__pathrev_t *peg_loc;
 
-  SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &peg_loc,
-                                            path_or_url, NULL, peg_revision,
-                                            peg_revision, ctx, scratch_pool));
+  if (ra_session && svn_path_is_url(path_or_url))
+    {
+      SVN_ERR(svn_ra_reparent(ra_session, path_or_url, scratch_pool));
+      SVN_ERR(svn_client__resolve_rev_and_url(&peg_loc, ra_session,
+                                              path_or_url,
+                                              peg_revision,
+                                              peg_revision,
+                                              ctx, scratch_pool));
+    }
+  else
+    {
+      SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &peg_loc,
+                                                path_or_url, NULL,
+                                                peg_revision,
+                                                peg_revision, ctx, scratch_pool));
+    }
 
   /* If PATH_OR_URL is as working copy path determine if we will need to
      contact the repository for the requested PEG_REVISION. */
@@ -1064,10 +1082,6 @@ get_mergeinfo(svn_mergeinfo_catalog_t *m
       }
     }
 
-  /* Check server Merge Tracking capability. */
-  SVN_ERR(svn_ra__assert_mergeinfo_capable_server(ra_session, path_or_url,
-                                                  scratch_pool));
-
   SVN_ERR(svn_ra_get_repos_root2(ra_session, repos_root, result_pool));
 
   if (use_url)
@@ -1391,17 +1405,21 @@ filter_log_entry_with_rangelist(void *ba
              obviously back.  If it was added or replaced it's still around
              possibly it was replaced one or more times, but it's back now.
              Regardless, LOG_ENTRY->REVISION is *not* an eligible revision! */
-          if (ancestor_is_self /* Explicit mergeinfo on TARGET_PATH_AFFECTED */
+          if (nearest_ancestor_mergeinfo &&
+              ancestor_is_self /* Explicit mergeinfo on TARGET_PATH_AFFECTED */
               && (change->action != 'M'))
             {
               svn_rangelist_t *rangelist =
                   svn_hash_gets(nearest_ancestor_mergeinfo, path);
-              svn_merge_range_t *youngest_range = APR_ARRAY_IDX(
-                rangelist, rangelist->nelts - 1, svn_merge_range_t *);
+              if (rangelist)
+                {
+                  svn_merge_range_t *youngest_range = APR_ARRAY_IDX(
+                    rangelist, rangelist->nelts - 1, svn_merge_range_t *);
 
-              if (youngest_range
-                  && (youngest_range->end > log_entry->revision))
-                continue;
+                  if (youngest_range
+                      && (youngest_range->end > log_entry->revision))
+                    continue;
+                }
             }
 
           if (nearest_ancestor_mergeinfo)
@@ -1496,29 +1514,22 @@ logs_for_mergeinfo_rangelist(const char 
                              svn_log_entry_receiver_t log_receiver,
                              void *log_receiver_baton,
                              svn_client_ctx_t *ctx,
+                             svn_ra_session_t *ra_session,
                              apr_pool_t *scratch_pool)
 {
-  apr_array_header_t *target;
   svn_merge_range_t *oldest_range, *youngest_range;
-  apr_array_header_t *revision_ranges;
-  svn_opt_revision_t oldest_rev, youngest_rev;
+  svn_revnum_t oldest_rev, youngest_rev;
   struct filter_log_entry_baton_t fleb;
 
   if (! rangelist->nelts)
     return SVN_NO_ERROR;
 
-  /* Build a single-member log target list using SOURCE_URL. */
-  target = apr_array_make(scratch_pool, 1, sizeof(const char *));
-  APR_ARRAY_PUSH(target, const char *) = source_url;
-
   /* Calculate and construct the bounds of our log request. */
   youngest_range = APR_ARRAY_IDX(rangelist, rangelist->nelts - 1,
                                  svn_merge_range_t *);
-  youngest_rev.kind = svn_opt_revision_number;
-  youngest_rev.value.number = youngest_range->end;
+  youngest_rev = youngest_range->end;
   oldest_range = APR_ARRAY_IDX(rangelist, 0, svn_merge_range_t *);
-  oldest_rev.kind = svn_opt_revision_number;
-  oldest_rev.value.number = oldest_range->start;
+  oldest_rev = oldest_range->start;
 
   if (! target_mergeinfo_catalog)
     target_mergeinfo_catalog = apr_hash_make(scratch_pool);
@@ -1543,19 +1554,29 @@ logs_for_mergeinfo_rangelist(const char 
   fleb.log_receiver_baton = log_receiver_baton;
   fleb.ctx = ctx;
 
-  /* Drive the log. */
-  revision_ranges = apr_array_make(scratch_pool, 1,
-                                   sizeof(svn_opt_revision_range_t *));
-  if (oldest_revs_first)
-    APR_ARRAY_PUSH(revision_ranges, svn_opt_revision_range_t *)
-      = svn_opt__revision_range_create(&oldest_rev, &youngest_rev, scratch_pool);
+  if (!ra_session)
+    SVN_ERR(svn_client__open_ra_session_internal(&ra_session, NULL, source_url,
+                                                 NULL, NULL, FALSE, FALSE, ctx,
+                                                 scratch_pool, scratch_pool));
   else
-    APR_ARRAY_PUSH(revision_ranges, svn_opt_revision_range_t *)
-      = svn_opt__revision_range_create(&youngest_rev, &oldest_rev, scratch_pool);
-  SVN_ERR(svn_client_log5(target, &youngest_rev, revision_ranges,
-                          0, discover_changed_paths, FALSE, FALSE, revprops,
-                          filter_log_entry_with_rangelist, &fleb, ctx,
-                          scratch_pool));
+    SVN_ERR(svn_ra_reparent(ra_session, source_url, scratch_pool));
+
+  {
+    apr_array_header_t *target;
+    target = apr_array_make(scratch_pool, 1, sizeof(const char *));
+    APR_ARRAY_PUSH(target, const char *) = "";
+
+    SVN_ERR(svn_ra_get_log2(ra_session, target,
+                            oldest_revs_first ? oldest_rev : youngest_rev,
+                            oldest_revs_first ? youngest_rev : oldest_rev,
+                            0 /* limit */,
+                            discover_changed_paths,
+                            FALSE /* strict_node_history */,
+                            FALSE /* include_merged_revisions */,
+                            revprops,
+                            filter_log_entry_with_rangelist, &fleb,
+                            scratch_pool));
+  }
 
   /* Check for cancellation. */
   if (ctx->cancel_func)
@@ -1616,7 +1637,7 @@ svn_client_mergeinfo_get_merged(apr_hash
   svn_mergeinfo_t mergeinfo;
 
   SVN_ERR(get_mergeinfo(&mergeinfo_cat, &repos_root, path_or_url,
-                        peg_revision, FALSE, FALSE, ctx, pool, pool));
+                        peg_revision, FALSE, FALSE, ctx, NULL, pool, pool));
   if (mergeinfo_cat)
     {
       const char *repos_relpath;
@@ -1647,11 +1668,11 @@ svn_client_mergeinfo_get_merged(apr_hash
   return SVN_NO_ERROR;
 }
 
-
 svn_error_t *
-svn_client_mergeinfo_log2(svn_boolean_t finding_merged,
+svn_client__mergeinfo_log(svn_boolean_t finding_merged,
                           const char *target_path_or_url,
                           const svn_opt_revision_t *target_peg_revision,
+                          svn_mergeinfo_catalog_t *target_mergeinfo_catalog,
                           const char *source_path_or_url,
                           const svn_opt_revision_t *source_peg_revision,
                           const svn_opt_revision_t *source_start_revision,
@@ -1662,12 +1683,16 @@ svn_client_mergeinfo_log2(svn_boolean_t 
                           svn_depth_t depth,
                           const apr_array_header_t *revprops,
                           svn_client_ctx_t *ctx,
+                          svn_ra_session_t *ra_session,
+                          apr_pool_t *result_pool,
                           apr_pool_t *scratch_pool)
 {
   const char *log_target = NULL;
   const char *repos_root;
   const char *target_repos_relpath;
   svn_mergeinfo_catalog_t target_mergeinfo_cat;
+  svn_ra_session_t *target_session = NULL;
+  svn_client__pathrev_t *pathrev;
 
   /* A hash of paths, at or under TARGET_PATH_OR_URL, mapped to
      rangelists.  Not technically mergeinfo, so not using the
@@ -1684,6 +1709,7 @@ svn_client_mergeinfo_log2(svn_boolean_t 
   apr_hash_index_t *hi;
   apr_pool_t *iterpool;
   svn_boolean_t oldest_revs_first = TRUE;
+  apr_pool_t *subpool;
 
   /* We currently only support depth = empty | infinity. */
   if (depth != svn_depth_infinity && depth != svn_depth_empty)
@@ -1709,6 +1735,11 @@ svn_client_mergeinfo_log2(svn_boolean_t 
       && (source_start_revision->kind != svn_opt_revision_unspecified))
     return svn_error_create(SVN_ERR_CLIENT_BAD_REVISION, NULL, NULL);
 
+  subpool = svn_pool_create(scratch_pool);
+
+  if (ra_session)
+    target_session = ra_session;
+
   /* We need the union of TARGET_PATH_OR_URL@TARGET_PEG_REVISION's mergeinfo
      and MERGE_SOURCE_URL's history.  It's not enough to do path
      matching, because renames in the history of MERGE_SOURCE_URL
@@ -1716,10 +1747,61 @@ svn_client_mergeinfo_log2(svn_boolean_t 
      the target, that vastly simplifies matters (we'll have nothing to
      do). */
   /* This get_mergeinfo() call doubles as a mergeinfo capabilities check. */
-  SVN_ERR(get_mergeinfo(&target_mergeinfo_cat, &repos_root,
-                        target_path_or_url, target_peg_revision,
-                        depth == svn_depth_infinity, TRUE,
-                        ctx, scratch_pool, scratch_pool));
+  if (target_mergeinfo_catalog)
+    {
+      if (*target_mergeinfo_catalog)
+        {
+          /* The caller provided the mergeinfo catalog for
+             TARGET_PATH_OR_URL, so we don't need to accquire
+             it ourselves.  We do need to get the repos_root
+             though, because get_mergeinfo() won't do it for us. */
+          target_mergeinfo_cat = *target_mergeinfo_catalog;
+
+          if (ra_session && svn_path_is_url(target_path_or_url))
+            {
+              SVN_ERR(svn_ra_reparent(ra_session, target_path_or_url, subpool));
+              SVN_ERR(svn_client__resolve_rev_and_url(&pathrev, ra_session,
+                                                      target_path_or_url,
+                                                      target_peg_revision,
+                                                      target_peg_revision,
+                                                      ctx, subpool));
+              target_session = ra_session;
+            }
+          else
+            {
+              SVN_ERR(svn_client__ra_session_from_path2(&target_session,
+                                                        &pathrev,
+                                                        target_path_or_url,
+                                                        NULL,
+                                                        target_peg_revision,
+                                                        target_peg_revision,
+                                                        ctx, subpool));
+            }
+          SVN_ERR(svn_ra_get_repos_root2(target_session, &repos_root,
+                                         scratch_pool));
+        }
+      else
+        {
+          /* The caller didn't provide the mergeinfo catalog for
+             TARGET_PATH_OR_URL, but wants us to pass a copy back
+             when we get it, so use RESULT_POOL. */
+          SVN_ERR(get_mergeinfo(target_mergeinfo_catalog, &repos_root,
+                                target_path_or_url, target_peg_revision,
+                                depth == svn_depth_infinity, TRUE,
+                                ctx, ra_session, result_pool, scratch_pool));
+          target_mergeinfo_cat = *target_mergeinfo_catalog;
+        }
+    }
+  else
+    {
+      /* The caller didn't provide the mergeinfo catalog for
+         TARGET_PATH_OR_URL, nor does it want a copy, so we can use
+         nothing but SCRATCH_POOL. */
+      SVN_ERR(get_mergeinfo(&target_mergeinfo_cat, &repos_root,
+                            target_path_or_url, target_peg_revision,
+                            depth == svn_depth_infinity, TRUE,
+                            ctx, ra_session, scratch_pool, scratch_pool));
+    }
 
   if (!svn_path_is_url(target_path_or_url))
     {
@@ -1751,6 +1833,7 @@ svn_client_mergeinfo_log2(svn_boolean_t 
          history. */
       if (finding_merged)
         {
+          svn_pool_destroy(subpool);
           return SVN_NO_ERROR;
         }
       else
@@ -1768,18 +1851,17 @@ svn_client_mergeinfo_log2(svn_boolean_t 
    * ### TODO: As the source and target must be in the same repository, we
    * should share a single session, tracking the two URLs separately. */
   {
-    apr_pool_t *sesspool = svn_pool_create(scratch_pool);
-    svn_ra_session_t *source_session, *target_session;
-    svn_client__pathrev_t *pathrev;
+    svn_ra_session_t *source_session;
     svn_revnum_t start_rev, end_rev, youngest_rev = SVN_INVALID_REVNUM;
 
     if (! finding_merged)
       {
-        SVN_ERR(svn_client__ra_session_from_path2(&target_session, &pathrev,
-                                                  target_path_or_url, NULL,
-                                                  target_peg_revision,
-                                                  target_peg_revision,
-                                                  ctx, sesspool));
+        if (!target_session)
+          SVN_ERR(svn_client__ra_session_from_path2(&target_session, &pathrev,
+                                                    target_path_or_url, NULL,
+                                                    target_peg_revision,
+                                                    target_peg_revision,
+                                                    ctx, subpool));
         SVN_ERR(svn_client__get_history_as_mergeinfo(&target_history, NULL,
                                                      pathrev,
                                                      SVN_INVALID_REVNUM,
@@ -1788,21 +1870,38 @@ svn_client_mergeinfo_log2(svn_boolean_t 
                                                      scratch_pool));
       }
 
-    SVN_ERR(svn_client__ra_session_from_path2(&source_session, &pathrev,
-                                              source_path_or_url, NULL,
-                                              source_peg_revision,
-                                              source_peg_revision,
-                                              ctx, sesspool));
+    if (target_session
+        && svn_path_is_url(source_path_or_url)
+        && repos_root
+        && svn_uri_skip_ancestor(repos_root, source_path_or_url, subpool))
+      {
+        /* We can re-use the existing session */
+        source_session = target_session;
+        SVN_ERR(svn_ra_reparent(source_session, source_path_or_url, subpool));
+        SVN_ERR(svn_client__resolve_rev_and_url(&pathrev, source_session,
+                                                source_path_or_url,
+                                                source_peg_revision,
+                                                source_peg_revision,
+                                                ctx, subpool));
+      }
+    else
+      {
+        SVN_ERR(svn_client__ra_session_from_path2(&source_session, &pathrev,
+                                                  source_path_or_url, NULL,
+                                                  source_peg_revision,
+                                                  source_peg_revision,
+                                                  ctx, subpool));
+      }
     SVN_ERR(svn_client__get_revision_number(&start_rev, &youngest_rev,
                                             ctx->wc_ctx, source_path_or_url,
                                             source_session,
                                             source_start_revision,
-                                            sesspool));
+                                            subpool));
     SVN_ERR(svn_client__get_revision_number(&end_rev, &youngest_rev,
                                             ctx->wc_ctx, source_path_or_url,
                                             source_session,
                                             source_end_revision,
-                                            sesspool));
+                                            subpool));
     SVN_ERR(svn_client__get_history_as_mergeinfo(&source_history, NULL,
                                                  pathrev,
                                                  MAX(end_rev, start_rev),
@@ -1811,9 +1910,6 @@ svn_client_mergeinfo_log2(svn_boolean_t 
                                                  scratch_pool));
     if (start_rev > end_rev)
       oldest_revs_first = FALSE;
-
-    /* Close the source and target sessions. */
-    svn_pool_destroy(sesspool);
   }
 
   /* Separate the explicit or inherited mergeinfo on TARGET_PATH_OR_URL,
@@ -2070,7 +2166,10 @@ svn_client_mergeinfo_log2(svn_boolean_t 
   log_target = svn_path_url_add_component2(repos_root, log_target + 1,
                                            scratch_pool);
 
-  SVN_ERR(logs_for_mergeinfo_rangelist(log_target, merge_source_fspaths,
+  {
+    svn_error_t *err;
+
+    err = logs_for_mergeinfo_rangelist(log_target, merge_source_fspaths,
                                        finding_merged,
                                        master_inheritable_rangelist,
                                        oldest_revs_first,
@@ -2081,8 +2180,40 @@ svn_client_mergeinfo_log2(svn_boolean_t 
                                        discover_changed_paths,
                                        revprops,
                                        log_receiver, log_receiver_baton,
-                                       ctx, scratch_pool));
-  return SVN_NO_ERROR;
+                                       ctx, target_session, scratch_pool);
+
+    /* Close the source and target sessions. */
+    svn_pool_destroy(subpool); /* For SVN_ERR_CEASE_INVOCATION */
+
+    return svn_error_trace(err);
+  }
+}
+
+svn_error_t *
+svn_client_mergeinfo_log2(svn_boolean_t finding_merged,
+                          const char *target_path_or_url,
+                          const svn_opt_revision_t *target_peg_revision,
+                          const char *source_path_or_url,
+                          const svn_opt_revision_t *source_peg_revision,
+                          const svn_opt_revision_t *source_start_revision,
+                          const svn_opt_revision_t *source_end_revision,
+                          svn_log_entry_receiver_t log_receiver,
+                          void *log_receiver_baton,
+                          svn_boolean_t discover_changed_paths,
+                          svn_depth_t depth,
+                          const apr_array_header_t *revprops,
+                          svn_client_ctx_t *ctx,
+                          apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(
+         svn_client__mergeinfo_log(finding_merged, target_path_or_url,
+                                   target_peg_revision, NULL,
+                                   source_path_or_url, source_peg_revision,
+                                   source_start_revision, source_end_revision,
+                                   log_receiver, log_receiver_baton,
+                                   discover_changed_paths, depth, revprops,
+                                   ctx, NULL,
+                                   scratch_pool, scratch_pool));
 }
 
 svn_error_t *
@@ -2120,7 +2251,7 @@ svn_client_suggest_merge_sources(apr_arr
 
   /* ### TODO: Share ra_session batons to improve efficiency? */
   SVN_ERR(get_mergeinfo(&mergeinfo_cat, &repos_root, path_or_url,
-                        peg_revision, FALSE, FALSE, ctx, pool, pool));
+                        peg_revision, FALSE, FALSE, ctx, NULL, pool, pool));
 
   if (mergeinfo_cat && apr_hash_count(mergeinfo_cat))
     {

Modified: subversion/branches/cache-server/subversion/libsvn_client/patch.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_client/patch.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_client/patch.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_client/patch.c Tue Oct 15 08:52:06 2013
@@ -29,6 +29,8 @@
 
 #include <apr_hash.h>
 #include <apr_fnmatch.h>
+
+#include "svn_private_config.h"
 #include "svn_client.h"
 #include "svn_dirent_uri.h"
 #include "svn_diff.h"
@@ -42,7 +44,6 @@
 #include "svn_wc.h"
 #include "client.h"
 
-#include "svn_private_config.h"
 #include "private/svn_eol_private.h"
 #include "private/svn_wc_private.h"
 #include "private/svn_dep_compat.h"
@@ -2676,8 +2677,8 @@ install_patched_prop_targets(patch_targe
         {
           if (! dry_run)
             {
-              SVN_ERR(svn_io_file_create(target->local_abspath, "",
-                                         scratch_pool));
+              SVN_ERR(svn_io_file_create_empty(target->local_abspath,
+                                               scratch_pool));
               SVN_ERR(svn_wc_add_from_disk2(ctx->wc_ctx, target->local_abspath,
                                             NULL /*props*/,
                                             /* suppress notification */
@@ -2815,10 +2816,13 @@ check_ancestor_delete(const char *delete
 {
   struct can_delete_baton_t cb;
   svn_error_t *err;
+  apr_array_header_t *ignores;
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
 
   const char *dir_abspath = svn_dirent_dirname(deleted_target, scratch_pool);
 
+  SVN_ERR(svn_wc_get_default_ignores(&ignores, ctx->config, scratch_pool));
+
   while (svn_dirent_is_child(apply_root, dir_abspath, iterpool))
     {
       svn_pool_clear(iterpool);
@@ -2828,7 +2832,7 @@ check_ancestor_delete(const char *delete
       cb.targets_info = targets_info;
 
       err = svn_wc_walk_status(ctx->wc_ctx, dir_abspath, svn_depth_infinity,
-                               TRUE, FALSE, FALSE, NULL,
+                               TRUE, FALSE, FALSE, ignores,
                                can_delete_callback, &cb,
                                ctx->cancel_func, ctx->cancel_baton,
                                iterpool);

Modified: subversion/branches/cache-server/subversion/libsvn_client/prop_commands.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_client/prop_commands.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_client/prop_commands.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_client/prop_commands.c Tue Oct 15 08:52:06 2013
@@ -30,6 +30,7 @@
 #define APR_WANT_STRFUNC
 #include <apr_want.h>
 
+#include "svn_private_config.h"
 #include "svn_error.h"
 #include "svn_client.h"
 #include "client.h"
@@ -40,7 +41,6 @@
 #include "svn_hash.h"
 #include "svn_sorts.h"
 
-#include "svn_private_config.h"
 #include "private/svn_wc_private.h"
 #include "private/svn_ra_private.h"
 #include "private/svn_client_private.h"

Modified: subversion/branches/cache-server/subversion/libsvn_client/ra.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_client/ra.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_client/ra.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_client/ra.c Tue Oct 15 08:52:06 2013
@@ -25,6 +25,7 @@
 
 #include <apr_pools.h>
 
+#include "svn_private_config.h"
 #include "svn_error.h"
 #include "svn_hash.h"
 #include "svn_pools.h"
@@ -39,7 +40,6 @@
 #include "client.h"
 #include "mergeinfo.h"
 
-#include "svn_private_config.h"
 #include "private/svn_wc_private.h"
 #include "private/svn_client_private.h"
 
@@ -70,6 +70,8 @@ typedef struct callback_baton_t
   /* A client context. */
   svn_client_ctx_t *ctx;
 
+  /* Last progress reported by progress callback. */
+  apr_off_t last_progress;
 } callback_baton_t;
 
 
@@ -158,7 +160,7 @@ push_wc_prop(void *baton,
   if (! cb->commit_items)
     return svn_error_createf
       (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-       _("Attempt to set wc property '%s' on '%s' in a non-commit operation"),
+       _("Attempt to set wcprop '%s' on '%s' in a non-commit operation"),
        name, svn_dirent_local_style(relpath, pool));
 
   for (i = 0; i < cb->commit_items->nelts; i++)
@@ -287,6 +289,28 @@ get_client_string(void *baton,
   return SVN_NO_ERROR;
 }
 
+/* Implements svn_ra_progress_notify_func_t. Accumulates progress information
+ * for different RA sessions and reports total progress to caller. */
+static void
+progress_func(apr_off_t progress,
+              apr_off_t total,
+              void *baton,
+              apr_pool_t *pool)
+{
+  callback_baton_t *b = baton;
+  svn_client_ctx_t *ctx = b->ctx;
+
+  ctx->progress += (progress - b->last_progress);
+  b->last_progress = progress;
+
+  if (ctx->progress_func)
+    {
+      /* All RA implementations currently provide -1 for total. So it doesn't
+         make sense to develop some complex logic to combine total across all
+         RA sessions. */
+      ctx->progress_func(ctx->progress, -1, ctx->progress_baton, pool);
+    }
+}
 
 #define SVN_CLIENT__MAX_REDIRECT_ATTEMPTS 3 /* ### TODO:  Make configurable. */
 
@@ -320,12 +344,16 @@ svn_client__open_ra_session_internal(svn
   cbtable->invalidate_wc_props = (write_dav_props && read_dav_props)
                                   ? invalidate_wc_props : NULL;
   cbtable->auth_baton = ctx->auth_baton; /* new-style */
-  cbtable->progress_func = ctx->progress_func;
-  cbtable->progress_baton = ctx->progress_baton;
+  cbtable->progress_func = progress_func;
+  cbtable->progress_baton = cb;
   cbtable->cancel_func = ctx->cancel_func ? cancel_callback : NULL;
   cbtable->get_client_string = get_client_string;
   if (base_dir_abspath)
     cbtable->get_wc_contents = get_wc_contents;
+  cbtable->check_tunnel_func = ctx->check_tunnel_func;
+  cbtable->open_tunnel_func = ctx->open_tunnel_func;
+  cbtable->close_tunnel_func = ctx->close_tunnel_func;
+  cbtable->tunnel_baton = ctx->tunnel_baton;
 
   cb->commit_items = commit_items;
   cb->ctx = ctx;
@@ -447,39 +475,14 @@ svn_client_open_ra_session2(svn_ra_sessi
                                                   scratch_pool));
 }
 
-
-
-
-/* Given PATH_OR_URL, which contains either a working copy path or an
-   absolute URL, a peg revision PEG_REVISION, and a desired revision
-   REVISION, find the path at which that object exists in REVISION,
-   following copy history if necessary.  If REVISION is younger than
-   PEG_REVISION, then check that PATH_OR_URL is the same node in both
-   PEG_REVISION and REVISION, and return @c
-   SVN_ERR_CLIENT_UNRELATED_RESOURCES if it is not the same node.
-
-   If PEG_REVISION->kind is 'unspecified', the peg revision is 'head'
-   for a URL or 'working' for a WC path.  If REVISION->kind is
-   'unspecified', the operative revision is the peg revision.
-
-   Store the actual location of the object in *RESOLVED_LOC_P.
-
-   RA_SESSION should be an open RA session pointing at the URL of
-   PATH_OR_URL, or NULL, in which case this function will open its own
-   temporary session.
-
-   Use authentication baton cached in CTX to authenticate against the
-   repository.
-
-   Use POOL for all allocations. */
-static svn_error_t *
-resolve_rev_and_url(svn_client__pathrev_t **resolved_loc_p,
-                    svn_ra_session_t *ra_session,
-                    const char *path_or_url,
-                    const svn_opt_revision_t *peg_revision,
-                    const svn_opt_revision_t *revision,
-                    svn_client_ctx_t *ctx,
-                    apr_pool_t *pool)
+svn_error_t *
+svn_client__resolve_rev_and_url(svn_client__pathrev_t **resolved_loc_p,
+                                svn_ra_session_t *ra_session,
+                                const char *path_or_url,
+                                const svn_opt_revision_t *peg_revision,
+                                const svn_opt_revision_t *revision,
+                                svn_client_ctx_t *ctx,
+                                apr_pool_t *pool)
 {
   svn_opt_revision_t peg_rev = *peg_revision;
   svn_opt_revision_t start_rev = *revision;
@@ -545,9 +548,9 @@ svn_client__ra_session_from_path2(svn_ra
   if (corrected_url && svn_path_is_url(path_or_url))
     path_or_url = corrected_url;
 
-  SVN_ERR(resolve_rev_and_url(&resolved_loc, ra_session,
-                              path_or_url, peg_revision, revision,
-                              ctx, pool));
+  SVN_ERR(svn_client__resolve_rev_and_url(&resolved_loc, ra_session,
+                                          path_or_url, peg_revision, revision,
+                                          ctx, pool));
 
   /* Make the session point to the real URL. */
   SVN_ERR(svn_ra_reparent(ra_session, resolved_loc->url, pool));
@@ -652,6 +655,9 @@ svn_client__repos_location_segments(apr_
  * END_REVNUM must be valid revision numbers except that END_REVNUM may
  * be SVN_INVALID_REVNUM if END_URL is NULL.
  *
+ * YOUNGEST_REV is the already retrieved youngest revision of the ra session,
+ * but can be SVN_INVALID_REVNUM if the value is not already retrieved.
+ *
  * RA_SESSION is an open RA session parented at URL.
  */
 static svn_error_t *
@@ -662,6 +668,7 @@ repos_locations(const char **start_url,
                 svn_revnum_t peg_revnum,
                 svn_revnum_t start_revnum,
                 svn_revnum_t end_revnum,
+                svn_revnum_t youngest_rev,
                 apr_pool_t *result_pool,
                 apr_pool_t *scratch_pool)
 {
@@ -669,9 +676,9 @@ repos_locations(const char **start_url,
   apr_array_header_t *revs;
   apr_hash_t *rev_locs;
 
-  SVN_ERR_ASSERT(peg_revnum != SVN_INVALID_REVNUM);
-  SVN_ERR_ASSERT(start_revnum != SVN_INVALID_REVNUM);
-  SVN_ERR_ASSERT(end_revnum != SVN_INVALID_REVNUM || end_url == NULL);
+  SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(peg_revnum));
+  SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(start_revnum));
+  SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(end_revnum) || end_url == NULL);
 
   /* Avoid a network request in the common easy case. */
   if (start_revnum == peg_revnum
@@ -686,6 +693,27 @@ repos_locations(const char **start_url,
 
   SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_url, scratch_pool));
 
+  /* Handle another common case: The repository root can't move */
+  if (! strcmp(repos_url, url))
+    {
+      if (! SVN_IS_VALID_REVNUM(youngest_rev))
+        SVN_ERR(svn_ra_get_latest_revnum(ra_session, &youngest_rev,
+                                         scratch_pool));
+
+      if (start_revnum > youngest_rev
+          || (SVN_IS_VALID_REVNUM(end_revnum) && (end_revnum > youngest_rev)))
+        return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
+                                 _("No such revision %ld"),
+                                 (start_revnum > youngest_rev) 
+                                        ? start_revnum : end_revnum);
+
+      if (start_url)
+        *start_url = apr_pstrdup(result_pool, repos_url);
+      if (end_url)
+        *end_url = apr_pstrdup(result_pool, repos_url);
+      return SVN_NO_ERROR;
+    }
+
   revs = apr_array_make(scratch_pool, 2, sizeof(svn_revnum_t));
   APR_ARRAY_PUSH(revs, svn_revnum_t) = start_revnum;
   if (end_revnum != start_revnum && end_revnum != SVN_INVALID_REVNUM)
@@ -741,7 +769,7 @@ svn_client__repos_location(svn_client__p
                                             peg_loc->url, scratch_pool));
   err = repos_locations(&op_url, NULL, ra_session,
                         peg_loc->url, peg_loc->rev,
-                        op_revnum, SVN_INVALID_REVNUM,
+                        op_revnum, SVN_INVALID_REVNUM, SVN_INVALID_REVNUM,
                         result_pool, scratch_pool);
   SVN_ERR(svn_error_compose_create(
             err, svn_ra_reparent(ra_session, old_session_url, scratch_pool)));
@@ -881,29 +909,26 @@ svn_client__repos_locations(const char *
 
   SVN_ERR(repos_locations(start_url, end_url,
                           ra_session, url, peg_revnum,
-                          start_revnum, end_revnum,
+                          start_revnum, end_revnum, youngest_rev,
                           pool, subpool));
   svn_pool_destroy(subpool);
   return SVN_NO_ERROR;
 }
 
-
 svn_error_t *
-svn_client__get_youngest_common_ancestor(svn_client__pathrev_t **ancestor_p,
-                                         const svn_client__pathrev_t *loc1,
-                                         const svn_client__pathrev_t *loc2,
-                                         svn_ra_session_t *session,
-                                         svn_client_ctx_t *ctx,
-                                         apr_pool_t *result_pool,
-                                         apr_pool_t *scratch_pool)
+svn_client__calc_youngest_common_ancestor(svn_client__pathrev_t **ancestor_p,
+                                          const svn_client__pathrev_t *loc1,
+                                          apr_hash_t *history1,
+                                          svn_boolean_t has_rev_zero_history1,
+                                          const svn_client__pathrev_t *loc2,
+                                          apr_hash_t *history2,
+                                          svn_boolean_t has_rev_zero_history2,
+                                          apr_pool_t *result_pool,
+                                          apr_pool_t *scratch_pool)
 {
-  apr_pool_t *sesspool = NULL;
-  apr_hash_t *history1, *history2;
   apr_hash_index_t *hi;
   svn_revnum_t yc_revision = SVN_INVALID_REVNUM;
   const char *yc_relpath = NULL;
-  svn_boolean_t has_rev_zero_history1;
-  svn_boolean_t has_rev_zero_history2;
 
   if (strcmp(loc1->repos_root_url, loc2->repos_root_url) != 0)
     {
@@ -911,32 +936,6 @@ svn_client__get_youngest_common_ancestor
       return SVN_NO_ERROR;
     }
 
-  /* Open an RA session for the two locations. */
-  if (session == NULL)
-    {
-      sesspool = svn_pool_create(scratch_pool);
-      SVN_ERR(svn_client_open_ra_session2(&session, loc1->url, NULL, ctx,
-                                          sesspool, sesspool));
-    }
-
-  /* We're going to cheat and use history-as-mergeinfo because it
-     saves us a bunch of annoying custom data comparisons and such. */
-  SVN_ERR(svn_client__get_history_as_mergeinfo(&history1,
-                                               &has_rev_zero_history1,
-                                               loc1,
-                                               SVN_INVALID_REVNUM,
-                                               SVN_INVALID_REVNUM,
-                                               session, ctx, scratch_pool));
-  SVN_ERR(svn_client__get_history_as_mergeinfo(&history2,
-                                               &has_rev_zero_history2,
-                                               loc2,
-                                               SVN_INVALID_REVNUM,
-                                               SVN_INVALID_REVNUM,
-                                               session, ctx, scratch_pool));
-  /* Close the ra session if we opened one. */
-  if (sesspool)
-    svn_pool_destroy(sesspool);
-
   /* Loop through the first location's history, check for overlapping
      paths and ranges in the second location's history, and
      remembering the youngest matching location. */
@@ -990,47 +989,62 @@ svn_client__get_youngest_common_ancestor
 }
 
 svn_error_t *
-svn_client__youngest_common_ancestor(const char **ancestor_url,
-                                     svn_revnum_t *ancestor_rev,
-                                     const char *path_or_url1,
-                                     const svn_opt_revision_t *revision1,
-                                     const char *path_or_url2,
-                                     const svn_opt_revision_t *revision2,
-                                     svn_client_ctx_t *ctx,
-                                     apr_pool_t *result_pool,
-                                     apr_pool_t *scratch_pool)
+svn_client__get_youngest_common_ancestor(svn_client__pathrev_t **ancestor_p,
+                                         const svn_client__pathrev_t *loc1,
+                                         const svn_client__pathrev_t *loc2,
+                                         svn_ra_session_t *session,
+                                         svn_client_ctx_t *ctx,
+                                         apr_pool_t *result_pool,
+                                         apr_pool_t *scratch_pool)
 {
-  apr_pool_t *sesspool = svn_pool_create(scratch_pool);
-  svn_ra_session_t *session;
-  svn_client__pathrev_t *loc1, *loc2, *ancestor;
-
-  /* Resolve the two locations */
-  SVN_ERR(svn_client__ra_session_from_path2(&session, &loc1,
-                                            path_or_url1, NULL,
-                                            revision1, revision1,
-                                            ctx, sesspool));
-  SVN_ERR(resolve_rev_and_url(&loc2, session,
-                              path_or_url2, revision2, revision2,
-                              ctx, scratch_pool));
-
-  SVN_ERR(svn_client__get_youngest_common_ancestor(
-            &ancestor, loc1, loc2, session, ctx, result_pool, scratch_pool));
+  apr_pool_t *sesspool = NULL;
+  apr_hash_t *history1, *history2;
+  svn_boolean_t has_rev_zero_history1;
+  svn_boolean_t has_rev_zero_history2;
 
-  if (ancestor)
+  if (strcmp(loc1->repos_root_url, loc2->repos_root_url) != 0)
     {
-      *ancestor_url = ancestor->url;
-      *ancestor_rev = ancestor->rev;
+      *ancestor_p = NULL;
+      return SVN_NO_ERROR;
     }
-  else
+
+  /* Open an RA session for the two locations. */
+  if (session == NULL)
     {
-      *ancestor_url = NULL;
-      *ancestor_rev = SVN_INVALID_REVNUM;
+      sesspool = svn_pool_create(scratch_pool);
+      SVN_ERR(svn_client_open_ra_session2(&session, loc1->url, NULL, ctx,
+                                          sesspool, sesspool));
     }
-  svn_pool_destroy(sesspool);
+
+  /* We're going to cheat and use history-as-mergeinfo because it
+     saves us a bunch of annoying custom data comparisons and such. */
+  SVN_ERR(svn_client__get_history_as_mergeinfo(&history1,
+                                               &has_rev_zero_history1,
+                                               loc1,
+                                               SVN_INVALID_REVNUM,
+                                               SVN_INVALID_REVNUM,
+                                               session, ctx, scratch_pool));
+  SVN_ERR(svn_client__get_history_as_mergeinfo(&history2,
+                                               &has_rev_zero_history2,
+                                               loc2,
+                                               SVN_INVALID_REVNUM,
+                                               SVN_INVALID_REVNUM,
+                                               session, ctx, scratch_pool));
+  /* Close the ra session if we opened one. */
+  if (sesspool)
+    svn_pool_destroy(sesspool);
+
+  SVN_ERR(svn_client__calc_youngest_common_ancestor(ancestor_p,
+                                                    loc1, history1,
+                                                    has_rev_zero_history1,
+                                                    loc2, history2,
+                                                    has_rev_zero_history2,
+                                                    result_pool,
+                                                    scratch_pool));
+
   return SVN_NO_ERROR;
 }
 
-
 struct ra_ev2_baton {
   /* The working copy context, from the client context.  */
   svn_wc_context_t *wc_ctx;

Modified: subversion/branches/cache-server/subversion/libsvn_client/repos_diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_client/repos_diff.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_client/repos_diff.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_client/repos_diff.c Tue Oct 15 08:52:06 2013
@@ -36,6 +36,7 @@
 #include <apr_md5.h>
 #include <assert.h>
 
+#include "svn_private_config.h"
 #include "svn_checksum.h"
 #include "svn_hash.h"
 #include "svn_wc.h"
@@ -44,7 +45,6 @@
 #include "svn_path.h"
 #include "svn_io.h"
 #include "svn_props.h"
-#include "svn_private_config.h"
 
 #include "client.h"
 
@@ -328,7 +328,7 @@ get_file_from_ra(struct file_baton *fb,
                                      fb->pool, scratch_pool));
 
       fstream = svn_stream_checksummed2(fstream, NULL, &fb->start_md5_checksum,
-                                        svn_checksum_md5, TRUE, scratch_pool);
+                                        svn_checksum_md5, TRUE, fb->pool);
 
       /* Retrieve the file and its properties */
       SVN_ERR(svn_ra_get_file(fb->edit_baton->ra_session,
@@ -933,12 +933,12 @@ apply_textdelta(void *file_baton,
     }
 
   /* Open the file to be used as the base for second revision */
-  src_stream = svn_stream_lazyopen_create(lazy_open_source, fb, FALSE,
+  src_stream = svn_stream_lazyopen_create(lazy_open_source, fb, TRUE,
                                           scratch_pool);
 
   /* Open the file that will become the second revision after applying the
      text delta, it starts empty */
-  result_stream = svn_stream_lazyopen_create(lazy_open_result, fb, FALSE,
+  result_stream = svn_stream_lazyopen_create(lazy_open_result, fb, TRUE,
                                              scratch_pool);
 
   svn_txdelta_apply(src_stream,

Modified: subversion/branches/cache-server/subversion/libsvn_client/resolved.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_client/resolved.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_client/resolved.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_client/resolved.c Tue Oct 15 08:52:06 2013
@@ -29,6 +29,7 @@
 
 #include <stdlib.h>
 
+#include "svn_private_config.h"
 #include "svn_types.h"
 #include "svn_wc.h"
 #include "svn_client.h"
@@ -40,8 +41,6 @@
 #include "svn_sorts.h"
 #include "client.h"
 #include "private/svn_wc_private.h"
-
-#include "svn_private_config.h"
 
 /*** Code. ***/
 

Modified: subversion/branches/cache-server/subversion/libsvn_client/revert.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_client/revert.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_client/revert.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_client/revert.c Tue Oct 15 08:52:06 2013
@@ -27,6 +27,7 @@
 
 /*** Includes. ***/
 
+#include "svn_private_config.h"
 #include "svn_path.h"
 #include "svn_wc.h"
 #include "svn_client.h"
@@ -39,8 +40,6 @@
 #include "client.h"
 #include "private/svn_wc_private.h"
 
-#include "svn_private_config.h"
-
 
 /*** Code. ***/
 

Modified: subversion/branches/cache-server/subversion/libsvn_client/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_client/status.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_client/status.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_client/status.c Tue Oct 15 08:52:06 2013
@@ -29,6 +29,7 @@
 #include <apr_strings.h>
 #include <apr_pools.h>
 
+#include "svn_private_config.h"
 #include "svn_pools.h"
 #include "client.h"
 
@@ -39,7 +40,6 @@
 #include "svn_error.h"
 #include "svn_hash.h"
 
-#include "svn_private_config.h"
 #include "private/svn_wc_private.h"
 #include "private/svn_client_private.h"
 

Modified: subversion/branches/cache-server/subversion/libsvn_client/switch.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_client/switch.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_client/switch.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_client/switch.c Tue Oct 15 08:52:06 2013
@@ -27,6 +27,7 @@
 
 /*** Includes. ***/
 
+#include "svn_private_config.h"
 #include "svn_client.h"
 #include "svn_error.h"
 #include "svn_hash.h"
@@ -37,7 +38,6 @@
 #include "svn_pools.h"
 #include "client.h"
 
-#include "svn_private_config.h"
 #include "private/svn_wc_private.h"
 
 
@@ -231,8 +231,6 @@ switch_internal(svn_revnum_t *result_rev
         yca = NULL; /* Not versioned */
       else
         {
-          /* ### It would be nice if this function could reuse the existing
-             ra session instead of opening two for its own use. */
           SVN_ERR(svn_client__get_youngest_common_ancestor(
                   &yca, switch_loc, target_base_loc, ra_session, ctx,
                   pool, pool));
@@ -241,7 +239,7 @@ switch_internal(svn_revnum_t *result_rev
         return svn_error_createf(SVN_ERR_CLIENT_UNRELATED_RESOURCES, NULL,
                                  _("'%s' shares no common ancestry with '%s'"),
                                  switch_url,
-                                 svn_dirent_dirname(local_abspath, pool));
+                                 svn_dirent_local_style(local_abspath, pool));
     }
 
   wcroot_iprops = apr_hash_make(pool);
@@ -340,8 +338,8 @@ switch_internal(svn_revnum_t *result_rev
   *timestamp_sleep = TRUE;
 
   /* Drive the reporter structure, describing the revisions within
-     PATH.  When we call reporter->finish_report, the update_editor
-     will be driven by svn_repos_dir_delta2. */
+     LOCAL_ABSPATH.  When this calls reporter->finish_report, the
+     reporter will drive the switch_editor. */
   SVN_ERR(svn_wc_crawl_revisions5(ctx->wc_ctx, local_abspath, reporter,
                                   report_baton, TRUE,
                                   depth, (! depth_is_sticky),

Modified: subversion/branches/cache-server/subversion/libsvn_client/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_client/update.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_client/update.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_client/update.c Tue Oct 15 08:52:06 2013
@@ -27,6 +27,7 @@
 
 /*** Includes. ***/
 
+#include "svn_private_config.h"
 #include "svn_hash.h"
 #include "svn_wc.h"
 #include "svn_client.h"
@@ -39,7 +40,6 @@
 #include "svn_io.h"
 #include "client.h"
 
-#include "svn_private_config.h"
 #include "private/svn_wc_private.h"
 
 /* Implements svn_wc_dirents_func_t for update and switch handling. Assumes
@@ -454,8 +454,8 @@ update_internal(svn_revnum_t *result_rev
   *timestamp_sleep = TRUE;
 
   /* Drive the reporter structure, describing the revisions within
-     PATH.  When we call reporter->finish_report, the
-     update_editor will be driven by svn_repos_dir_delta2. */
+     LOCAL_ABSPATH.  When this calls reporter->finish_report, the
+     reporter will drive the update_editor. */
   SVN_ERR(svn_wc_crawl_revisions5(ctx->wc_ctx, local_abspath, reporter,
                                   report_baton, TRUE,
                                   depth, (! depth_is_sticky),
@@ -701,7 +701,23 @@ svn_client_update4(apr_array_header_t **
 
  cleanup:
   if (sleep)
-    svn_io_sleep_for_timestamps((paths->nelts == 1) ? path : NULL, pool);
+    {
+      const char *wcroot_abspath;
+
+      if (paths->nelts == 1)
+        {
+          const char *abspath;
+
+          /* PATH iteslf may have been removed by the update. */
+          SVN_ERR(svn_dirent_get_absolute(&abspath, path, pool));
+          SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath, ctx->wc_ctx, abspath,
+                                     pool, pool));
+        }
+      else
+        wcroot_abspath = NULL;
+
+      svn_io_sleep_for_timestamps(wcroot_abspath, pool);
+    }
 
   return svn_error_trace(err);
 }

Modified: subversion/branches/cache-server/subversion/libsvn_client/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_client/util.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_client/util.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_client/util.c Tue Oct 15 08:52:06 2013
@@ -24,6 +24,7 @@
 #include <apr_pools.h>
 #include <apr_strings.h>
 
+#include "svn_private_config.h"
 #include "svn_hash.h"
 #include "svn_pools.h"
 #include "svn_error.h"
@@ -40,8 +41,6 @@
 
 #include "client.h"
 
-#include "svn_private_config.h"
-
 svn_client__pathrev_t *
 svn_client__pathrev_create(const char *repos_root_url,
                            const char *repos_uuid,

Modified: subversion/branches/cache-server/subversion/libsvn_delta/compat.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_delta/compat.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_delta/compat.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_delta/compat.c Tue Oct 15 08:52:06 2013
@@ -23,6 +23,7 @@
 
 #include <stddef.h>
 
+#include "svn_private_config.h"
 #include "svn_types.h"
 #include "svn_error.h"
 #include "svn_delta.h"
@@ -33,8 +34,6 @@
 #include "svn_props.h"
 #include "svn_pools.h"
 
-#include "svn_private_config.h"
-
 #include "private/svn_delta_private.h"
 
 
@@ -218,6 +217,7 @@ locate_change(struct ev2_edit_baton *eb,
   change = apr_pcalloc(eb->edit_pool, sizeof(*change));
   change->changing = SVN_INVALID_REVNUM;
   change->deleting = SVN_INVALID_REVNUM;
+  change->kind = svn_node_unknown;
 
   svn_hash_sets(eb->changes, relpath, change);
 
@@ -439,8 +439,8 @@ process_actions(struct ev2_edit_baton *e
                                            change->changing, NULL, props));
       else
         SVN_ERR(svn_editor_alter_file(eb->editor, repos_relpath,
-                                      change->changing, props,
-                                      checksum, contents));
+                                      change->changing,
+                                      checksum, contents, props));
     }
 
   return SVN_NO_ERROR;
@@ -1182,9 +1182,9 @@ static svn_error_t *
 alter_file_cb(void *baton,
               const char *relpath,
               svn_revnum_t revision,
-              apr_hash_t *props,
               const svn_checksum_t *checksum,
               svn_stream_t *contents,
+              apr_hash_t *props,
               apr_pool_t *scratch_pool)
 {
   struct editor_baton *eb = baton;
@@ -1234,8 +1234,8 @@ static svn_error_t *
 alter_symlink_cb(void *baton,
                  const char *relpath,
                  svn_revnum_t revision,
-                 apr_hash_t *props,
                  const char *target,
+                 apr_hash_t *props,
                  apr_pool_t *scratch_pool)
 {
   /* ### should we verify the kind is truly a symlink?  */
@@ -1330,17 +1330,6 @@ move_cb(void *baton,
   return SVN_NO_ERROR;
 }
 
-/* This implements svn_editor_cb_rotate_t */
-static svn_error_t *
-rotate_cb(void *baton,
-          const apr_array_header_t *relpaths,
-          const apr_array_header_t *revisions,
-          apr_pool_t *scratch_pool)
-{
-  SVN__NOT_IMPLEMENTED();
-}
-
-
 static int
 count_components(const char *relpath)
 {
@@ -1633,11 +1622,14 @@ apply_change(void **dir_baton,
                                                        change->copyfrom_path,
                                                        scratch_pool);
           else
-            copyfrom_url = change->copyfrom_path;
+            {
+              copyfrom_url = change->copyfrom_path;
 
-          /* Make this an FS path by prepending "/" */
-          if (copyfrom_url[0] != '/')
-            copyfrom_url = apr_pstrcat(scratch_pool, "/", copyfrom_url, NULL);
+              /* Make this an FS path by prepending "/" */
+              if (copyfrom_url[0] != '/')
+                copyfrom_url = apr_pstrcat(scratch_pool, "/",
+                                           copyfrom_url, NULL);
+            }
 
           copyfrom_rev = change->copyfrom_rev;
         }
@@ -1885,7 +1877,6 @@ svn_delta__editor_from_delta(svn_editor_
       delete_cb,
       copy_cb,
       move_cb,
-      rotate_cb,
       complete_cb,
       abort_cb
     };

Modified: subversion/branches/cache-server/subversion/libsvn_delta/compose_delta.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_delta/compose_delta.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_delta/compose_delta.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_delta/compose_delta.c Tue Oct 15 08:52:06 2013
@@ -648,15 +648,17 @@ copy_source_ops(apr_size_t offset, apr_s
     {
       const svn_txdelta_op_t *const op = &window->ops[op_ndx];
       const apr_size_t *const off = &ndx->offs[op_ndx];
-      apr_size_t fix_offset;
-      apr_size_t fix_limit;
+      const apr_size_t fix_offset = (offset > off[0] ? offset - off[0] : 0);
+      const apr_size_t fix_limit = (off[1] > limit ? off[1] - limit : 0);
 
+      /* Ideally, we'd do this check before assigning fix_offset and
+         fix_limit; but then we couldn't make them const whilst still
+         adhering to C90 rules. Instead, we're going to assume that a
+         smart optimizing compiler will reorder this check before the
+         local variable initialization. */
       if (off[0] >= limit)
           break;
 
-      fix_offset = (offset > off[0] ? offset - off[0] : 0);
-      fix_limit = (off[1] > limit ? off[1] - limit : 0);
-
       /* It would be extremely weird if the fixed-up op had zero length. */
       assert(fix_offset + fix_limit < op->length);
 
@@ -701,23 +703,22 @@ copy_source_ops(apr_size_t offset, apr_s
               apr_size_t tgt_off = target_offset;
               assert(ptn_length > ptn_overlap);
 
-              /* ### FIXME: ptn_overlap is unsigned, so the if() condition
-                 below is always true!  Either it should be '> 0', or the
-                 code block should be unconditional.  See also r842362. */
-              if (ptn_overlap >= 0)
-                {
-                  /* Issue second subrange in the pattern. */
-                  const apr_size_t length =
-                    MIN(op->length - fix_off - fix_limit,
-                        ptn_length - ptn_overlap);
-                  copy_source_ops(op->offset + ptn_overlap,
-                                  op->offset + ptn_overlap + length,
-                                  tgt_off,
-                                  op_ndx,
-                                  build_baton, window, ndx, pool);
-                  fix_off += length;
-                  tgt_off += length;
-                }
+              /* Unconditionally issue the second subrange of the
+                 pattern. This is always correct, since the outer
+                 condition already verifies that there is an overlap
+                 in the target copy. */
+              {
+                const apr_size_t length =
+                  MIN(op->length - fix_off - fix_limit,
+                      ptn_length - ptn_overlap);
+                copy_source_ops(op->offset + ptn_overlap,
+                                op->offset + ptn_overlap + length,
+                                tgt_off,
+                                op_ndx,
+                                build_baton, window, ndx, pool);
+                fix_off += length;
+                tgt_off += length;
+              }
 
               assert(fix_off + fix_limit <= op->length);
               if (ptn_overlap > 0

Modified: subversion/branches/cache-server/subversion/libsvn_delta/editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_delta/editor.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_delta/editor.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_delta/editor.c Tue Oct 15 08:52:06 2013
@@ -391,16 +391,6 @@ svn_editor_setcb_move(svn_editor_t *edit
 
 
 svn_error_t *
-svn_editor_setcb_rotate(svn_editor_t *editor,
-                        svn_editor_cb_rotate_t callback,
-                        apr_pool_t *scratch_pool)
-{
-  editor->funcs.cb_rotate = callback;
-  return SVN_NO_ERROR;
-}
-
-
-svn_error_t *
 svn_editor_setcb_complete(svn_editor_t *editor,
                           svn_editor_cb_complete_t callback,
                           apr_pool_t *scratch_pool)
@@ -437,7 +427,6 @@ svn_editor_setcb_many(svn_editor_t *edit
   COPY_CALLBACK(cb_delete);
   COPY_CALLBACK(cb_copy);
   COPY_CALLBACK(cb_move);
-  COPY_CALLBACK(cb_rotate);
   COPY_CALLBACK(cb_complete);
   COPY_CALLBACK(cb_abort);
 
@@ -683,9 +672,9 @@ svn_error_t *
 svn_editor_alter_file(svn_editor_t *editor,
                       const char *relpath,
                       svn_revnum_t revision,
-                      apr_hash_t *props,
                       const svn_checksum_t *checksum,
-                      svn_stream_t *contents)
+                      svn_stream_t *contents,
+                      apr_hash_t *props)
 {
   svn_error_t *err = SVN_NO_ERROR;
 
@@ -705,8 +694,8 @@ svn_editor_alter_file(svn_editor_t *edit
     {
       START_CALLBACK(editor);
       err = editor->funcs.cb_alter_file(editor->baton,
-                                        relpath, revision, props,
-                                        checksum, contents,
+                                        relpath, revision,
+                                        checksum, contents, props,
                                         editor->scratch_pool);
       END_CALLBACK(editor);
     }
@@ -723,8 +712,8 @@ svn_error_t *
 svn_editor_alter_symlink(svn_editor_t *editor,
                          const char *relpath,
                          svn_revnum_t revision,
-                         apr_hash_t *props,
-                         const char *target)
+                         const char *target,
+                         apr_hash_t *props)
 {
   svn_error_t *err = SVN_NO_ERROR;
 
@@ -740,8 +729,8 @@ svn_editor_alter_symlink(svn_editor_t *e
     {
       START_CALLBACK(editor);
       err = editor->funcs.cb_alter_symlink(editor->baton,
-                                           relpath, revision, props,
-                                           target,
+                                           relpath, revision,
+                                           target, props,
                                            editor->scratch_pool);
       END_CALLBACK(editor);
     }
@@ -862,56 +851,6 @@ svn_editor_move(svn_editor_t *editor,
 
 
 svn_error_t *
-svn_editor_rotate(svn_editor_t *editor,
-                  const apr_array_header_t *relpaths,
-                  const apr_array_header_t *revisions)
-{
-  svn_error_t *err = SVN_NO_ERROR;
-
-  SHOULD_NOT_BE_FINISHED(editor);
-#ifdef ENABLE_ORDERING_CHECK
-  {
-    int i;
-    for (i = 0; i < relpaths->nelts; i++)
-      {
-        const char *relpath = APR_ARRAY_IDX(relpaths, i, const char *);
-
-        SVN_ERR_ASSERT(svn_relpath_is_canonical(relpath));
-        SHOULD_NOT_BE_COMPLETED(editor, relpath);
-        VERIFY_PARENT_MAY_EXIST(editor, relpath);
-        CHILD_DELETIONS_ALLOWED(editor, relpath);
-      }
-  }
-#endif
-
-  SVN_ERR(check_cancel(editor));
-
-  if (editor->funcs.cb_rotate)
-    {
-      START_CALLBACK(editor);
-      err = editor->funcs.cb_rotate(editor->baton, relpaths, revisions,
-                                    editor->scratch_pool);
-      END_CALLBACK(editor);
-    }
-
-#ifdef ENABLE_ORDERING_CHECK
-  {
-    int i;
-    for (i = 0; i < relpaths->nelts; i++)
-      {
-        const char *relpath = APR_ARRAY_IDX(relpaths, i, const char *);
-        MARK_ALLOW_ALTER(editor, relpath);
-        MARK_PARENT_STABLE(editor, relpath);
-      }
-  }
-#endif
-
-  svn_pool_clear(editor->scratch_pool);
-  return svn_error_trace(err);
-}
-
-
-svn_error_t *
 svn_editor_complete(svn_editor_t *editor)
 {
   svn_error_t *err = SVN_NO_ERROR;

Modified: subversion/branches/cache-server/subversion/libsvn_delta/svndiff.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_delta/svndiff.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_delta/svndiff.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_delta/svndiff.c Tue Oct 15 08:52:06 2013
@@ -29,21 +29,12 @@
 #include "delta.h"
 #include "svn_pools.h"
 #include "svn_private_config.h"
-#include <zlib.h>
 
 #include "private/svn_error_private.h"
 #include "private/svn_delta_private.h"
-
-/* The zlib compressBound function was not exported until 1.2.0. */
-#if ZLIB_VERNUM >= 0x1200
-#define svnCompressBound(LEN) compressBound(LEN)
-#else
-#define svnCompressBound(LEN) ((LEN) + ((LEN) >> 12) + ((LEN) >> 14) + 11)
-#endif
-
-/* For svndiff1, address/instruction/new data under this size will not
-   be compressed using zlib as a secondary compressor.  */
-#define MIN_COMPRESS_SIZE 512
+#include "private/svn_subr_private.h"
+#include "private/svn_string_private.h"
+#include "private/svn_dep_compat.h"
 
 /* ----- Text delta to svndiff ----- */
 
@@ -58,139 +49,31 @@ struct encoder_baton {
   apr_pool_t *pool;
 };
 
-/* This is at least as big as the largest size of an integer that
-   encode_int can generate; it is sufficient for creating buffers for
-   it to write into.  This assumes that integers are at most 64 bits,
-   and so 10 bytes (with 7 bits of information each) are sufficient to
-   represent them. */
-#define MAX_ENCODED_INT_LEN 10
 /* This is at least as big as the largest size for a single instruction. */
-#define MAX_INSTRUCTION_LEN (2*MAX_ENCODED_INT_LEN+1)
+#define MAX_INSTRUCTION_LEN (2*SVN__MAX_ENCODED_UINT_LEN+1)
 /* This is at least as big as the largest possible instructions
    section: in theory, the instructions could be SVN_DELTA_WINDOW_SIZE
    1-byte copy-from-source instructions (though this is very unlikely). */
 #define MAX_INSTRUCTION_SECTION_LEN (SVN_DELTA_WINDOW_SIZE*MAX_INSTRUCTION_LEN)
 
-/* Encode VAL into the buffer P using the variable-length svndiff
-   integer format.  Return the incremented value of P after the
-   encoded bytes have been written.  P must point to a buffer of size
-   at least MAX_ENCODED_INT_LEN.
-
-   This encoding uses the high bit of each byte as a continuation bit
-   and the other seven bits as data bits.  High-order data bits are
-   encoded first, followed by lower-order bits, so the value can be
-   reconstructed by concatenating the data bits from left to right and
-   interpreting the result as a binary number.  Examples (brackets
-   denote byte boundaries, spaces are for clarity only):
-
-           1 encodes as [0 0000001]
-          33 encodes as [0 0100001]
-         129 encodes as [1 0000001] [0 0000001]
-        2000 encodes as [1 0001111] [0 1010000]
-*/
-static unsigned char *
-encode_int(unsigned char *p, svn_filesize_t val)
-{
-  int n;
-  svn_filesize_t v;
-  unsigned char cont;
-
-  SVN_ERR_ASSERT_NO_RETURN(val >= 0);
-
-  /* Figure out how many bytes we'll need.  */
-  v = val >> 7;
-  n = 1;
-  while (v > 0)
-    {
-      v = v >> 7;
-      n++;
-    }
-
-  SVN_ERR_ASSERT_NO_RETURN(n <= MAX_ENCODED_INT_LEN);
-
-  /* Encode the remaining bytes; n is always the number of bytes
-     coming after the one we're encoding.  */
-  while (--n >= 0)
-    {
-      cont = ((n > 0) ? 0x1 : 0x0) << 7;
-      *p++ = (unsigned char)(((val >> (n * 7)) & 0x7f) | cont);
-    }
-
-  return p;
-}
-
 
 /* Append an encoded integer to a string.  */
 static void
 append_encoded_int(svn_stringbuf_t *header, svn_filesize_t val)
 {
-  unsigned char buf[MAX_ENCODED_INT_LEN], *p;
+  unsigned char buf[SVN__MAX_ENCODED_UINT_LEN], *p;
 
-  p = encode_int(buf, val);
+  SVN_ERR_ASSERT_NO_RETURN(val >= 0);
+  p = svn__encode_uint(buf, (apr_uint64_t)val);
   svn_stringbuf_appendbytes(header, (const char *)buf, p - buf);
 }
 
-/* If IN is a string that is >= MIN_COMPRESS_SIZE and the COMPRESSION_LEVEL
-   is not SVN_DELTA_COMPRESSION_LEVEL_NONE, zlib compress it and places the
-   result in OUT, with an integer prepended specifying the original size.
-   If IN is < MIN_COMPRESS_SIZE, or if the compressed version of IN was no
-   smaller than the original IN, OUT will be a copy of IN with the size
-   prepended as an integer. */
-static svn_error_t *
-zlib_encode(const char *data,
-            apr_size_t len,
-            svn_stringbuf_t *out,
-            int compression_level)
-{
-  unsigned long endlen;
-  apr_size_t intlen;
-
-  svn_stringbuf_setempty(out);
-  append_encoded_int(out, len);
-  intlen = out->len;
-
-  /* Compression initialization overhead is considered to large for
-     short buffers.  Also, if we don't actually want to compress data,
-     ZLIB will produce an output no shorter than the input.  Hence,
-     the DATA would directly appended to OUT, so we can do that directly
-     without calling ZLIB before. */
-  if (   (len < MIN_COMPRESS_SIZE)
-      || (compression_level == SVN_DELTA_COMPRESSION_LEVEL_NONE))
-    {
-      svn_stringbuf_appendbytes(out, data, len);
-    }
-  else
-    {
-      int zerr;
-
-      svn_stringbuf_ensure(out, svnCompressBound(len) + intlen);
-      endlen = out->blocksize;
-
-      zerr = compress2((unsigned char *)out->data + intlen, &endlen,
-                       (const unsigned char *)data, len,
-                       compression_level);
-      if (zerr != Z_OK)
-        return svn_error_trace(svn_error__wrap_zlib(
-                                 zerr, "compress2",
-                                 _("Compression of svndiff data failed")));
-
-      /* Compression didn't help :(, just append the original text */
-      if (endlen >= len)
-        {
-          svn_stringbuf_appendbytes(out, data, len);
-          return SVN_NO_ERROR;
-        }
-      out->len = endlen + intlen;
-      out->data[out->len] = 0;
-    }
-  return SVN_NO_ERROR;
-}
-
 static svn_error_t *
 send_simple_insertion_window(svn_txdelta_window_t *window,
                              struct encoder_baton *eb)
 {
-  unsigned char headers[4 + 5 * MAX_ENCODED_INT_LEN + MAX_INSTRUCTION_LEN];
+  unsigned char headers[4 + 5 * SVN__MAX_ENCODED_UINT_LEN
+                          + MAX_INSTRUCTION_LEN];
   unsigned char ibuf[MAX_INSTRUCTION_LEN];
   unsigned char *header_current;
   apr_size_t header_len;
@@ -226,16 +109,17 @@ send_simple_insertion_window(svn_txdelta
   else
     {
       ibuf[0] = (0x2 << 6);
-      ip_len = encode_int(ibuf + 1, window->tview_len) - ibuf;
+      ip_len = svn__encode_uint(ibuf + 1, window->tview_len) - ibuf;
     }
 
   /* encode the window header.  Please note that the source window may
    * have content despite not being used for deltification. */
-  header_current = encode_int(header_current, window->sview_offset);
-  header_current = encode_int(header_current, window->sview_len);
-  header_current = encode_int(header_current, window->tview_len);
+  header_current = svn__encode_uint(header_current,
+                                    (apr_uint64_t)window->sview_offset);
+  header_current = svn__encode_uint(header_current, window->sview_len);
+  header_current = svn__encode_uint(header_current, window->tview_len);
   header_current[0] = (unsigned char)ip_len;  /* 1 instruction */
-  header_current = encode_int(&header_current[1], len);
+  header_current = svn__encode_uint(&header_current[1], len);
 
   /* append instructions (1 to a handful of bytes) */
   for (i = 0; i < ip_len; ++i)
@@ -319,9 +203,9 @@ window_handler(svn_txdelta_window_t *win
       if (op->length >> 6 == 0)
         *ip++ |= (unsigned char)op->length;
       else
-        ip = encode_int(ip + 1, op->length);
+        ip = svn__encode_uint(ip + 1, op->length);
       if (op->action_code != svn_txdelta_new)
-        ip = encode_int(ip, op->offset);
+        ip = svn__encode_uint(ip, op->offset);
       svn_stringbuf_appendbytes(instructions, (const char *)ibuf, ip - ibuf);
     }
 
@@ -331,20 +215,20 @@ window_handler(svn_txdelta_window_t *win
   append_encoded_int(header, window->tview_len);
   if (eb->version == 1)
     {
-      SVN_ERR(zlib_encode(instructions->data, instructions->len,
-                          i1, eb->compression_level));
+      SVN_ERR(svn__compress(instructions, i1, eb->compression_level));
       instructions = i1;
     }
   append_encoded_int(header, instructions->len);
   if (eb->version == 1)
     {
-      svn_stringbuf_t *temp = svn_stringbuf_create_empty(pool);
-      svn_string_t *tempstr = svn_string_create_empty(pool);
-      SVN_ERR(zlib_encode(window->new_data->data, window->new_data->len,
-                          temp, eb->compression_level));
-      tempstr->data = temp->data;
-      tempstr->len = temp->len;
-      newdata = tempstr;
+      svn_stringbuf_t *compressed = svn_stringbuf_create_empty(pool);
+      svn_stringbuf_t *original = svn_stringbuf_create_empty(pool);
+      original->data = (char *)window->new_data->data; /* won't be modified */
+      original->len = window->new_data->len;
+      original->blocksize = window->new_data->len + 1;
+
+      SVN_ERR(svn__compress(original, compressed, eb->compression_level));
+      newdata = svn_stringbuf__morph_into_string(compressed);
     }
   else
     newdata = window->new_data;
@@ -453,128 +337,32 @@ struct decode_baton
 };
 
 
-/* Decode an svndiff-encoded integer into *VAL and return a pointer to
-   the byte after the integer.  The bytes to be decoded live in the
-   range [P..END-1].  If these bytes do not contain a whole encoded
-   integer, return NULL; in this case *VAL is undefined.
-
-   See the comment for encode_int() earlier in this file for more detail on
-   the encoding format.  */
+/* Wrapper aroung svn__deencode_uint taking a file size as *VAL. */
 static const unsigned char *
 decode_file_offset(svn_filesize_t *val,
                    const unsigned char *p,
                    const unsigned char *end)
 {
-  svn_filesize_t temp = 0;
-
-  if (p + MAX_ENCODED_INT_LEN < end)
-    end = p + MAX_ENCODED_INT_LEN;
-  /* Decode bytes until we're done.  */
-  while (p < end)
-    {
-      /* Don't use svn_filesize_t here, because this might be 64 bits
-       * on 32 bit targets. Optimizing compilers may or may not be
-       * able to reduce that to the effective code below. */
-      unsigned int c = *p++;
-
-      temp = (temp << 7) | (c & 0x7f);
-      if (c < 0x80)
-      {
-        *val = temp;
-        return p;
-      }
-    }
+  apr_uint64_t temp = 0;
+  const unsigned char *result = svn__decode_uint(&temp, p, end);
+  *val = (svn_filesize_t)temp;
 
-  return NULL;
+  return result;
 }
 
-
 /* Same as above, only decode into a size variable. */
 static const unsigned char *
 decode_size(apr_size_t *val,
             const unsigned char *p,
             const unsigned char *end)
 {
-  apr_size_t temp = 0;
-
-  if (p + MAX_ENCODED_INT_LEN < end)
-    end = p + MAX_ENCODED_INT_LEN;
-  /* Decode bytes until we're done.  */
-  while (p < end)
-    {
-      apr_size_t c = *p++;
-
-      temp = (temp << 7) | (c & 0x7f);
-      if (c < 0x80)
-      {
-        *val = temp;
-        return p;
-      }
-    }
-
-  return NULL;
-}
-
-/* Decode the possibly-zlib compressed string of length INLEN that is in
-   IN, into OUT.  We expect an integer is prepended to IN that specifies
-   the original size, and that if encoded size == original size, that the
-   remaining data is not compressed.
-   In that case, we will simply return pointer into IN as data pointer for
-   OUT, COPYLESS_ALLOWED has been set.  The, the caller is expected not to
-   modify the contents of OUT.
-   An error is returned if the decoded length exceeds the given LIMIT.
- */
-static svn_error_t *
-zlib_decode(const unsigned char *in, apr_size_t inLen, svn_stringbuf_t *out,
-            apr_size_t limit)
-{
-  apr_size_t len;
-  const unsigned char *oldplace = in;
-
-  /* First thing in the string is the original length.  */
-  in = decode_size(&len, in, in + inLen);
-  if (in == NULL)
-    return svn_error_create(SVN_ERR_SVNDIFF_INVALID_COMPRESSED_DATA, NULL,
-                            _("Decompression of svndiff data failed: no size"));
-  if (len > limit)
-    return svn_error_create(SVN_ERR_SVNDIFF_INVALID_COMPRESSED_DATA, NULL,
-                            _("Decompression of svndiff data failed: "
-                              "size too large"));
-  /* We need to subtract the size of the encoded original length off the
-   *      still remaining input length.  */
-  inLen -= (in - oldplace);
-  if (inLen == len)
-    {
-      svn_stringbuf_ensure(out, len);
-      memcpy(out->data, in, len);
-      out->data[len] = 0;
-      out->len = len;
-
-      return SVN_NO_ERROR;
-    }
-  else
-    {
-      unsigned long zlen = len;
-      int zerr;
-
-      svn_stringbuf_ensure(out, len);
-      zerr = uncompress((unsigned char *)out->data, &zlen, in, inLen);
-      if (zerr != Z_OK)
-        return svn_error_trace(svn_error__wrap_zlib(
-                                 zerr, "uncompress",
-                                 _("Decompression of svndiff data failed")));
-
-      /* Zlib should not produce something that has a different size than the
-         original length we stored. */
-      if (zlen != len)
-        return svn_error_create(SVN_ERR_SVNDIFF_INVALID_COMPRESSED_DATA,
-                                NULL,
-                                _("Size of uncompressed data "
-                                  "does not match stored original length"));
-      out->data[zlen] = 0;
-      out->len = zlen;
-    }
-  return SVN_NO_ERROR;
+  apr_uint64_t temp = 0;
+  const unsigned char *result = svn__decode_uint(&temp, p, end);
+  if (temp > APR_SIZE_MAX)
+    return NULL;
+  
+  *val = (apr_size_t)temp;
+  return result;
 }
 
 /* Decode an instruction into OP, returning a pointer to the text
@@ -695,6 +483,21 @@ count_and_verify_instructions(int *ninst
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+zlib_decode(const unsigned char *in, apr_size_t inLen, svn_stringbuf_t *out,
+            apr_size_t limit)
+{
+  /* construct a fake string buffer as parameter to svn__decompress.
+     This is fine as that function never writes to it. */
+  svn_stringbuf_t compressed;
+  compressed.pool = NULL;
+  compressed.data = (char *)in;
+  compressed.len = inLen;
+  compressed.blocksize = inLen + 1;
+  
+  return svn__decompress(&compressed, out, limit);
+}
+
 /* Given the five integer fields of a window header and a pointer to
    the remainder of the window contents, fill in a delta window
    structure *WINDOW.  New allocations will be performed in POOL;
@@ -847,7 +650,7 @@ write_handler(void *baton,
       if (tview_len > SVN_DELTA_WINDOW_SIZE ||
           sview_len > SVN_DELTA_WINDOW_SIZE ||
           /* for svndiff1, newlen includes the original length */
-          newlen > SVN_DELTA_WINDOW_SIZE + MAX_ENCODED_INT_LEN ||
+          newlen > SVN_DELTA_WINDOW_SIZE + SVN__MAX_ENCODED_UINT_LEN ||
           inslen > MAX_INSTRUCTION_SECTION_LEN)
         return svn_error_create(SVN_ERR_SVNDIFF_CORRUPT_WINDOW, NULL,
                                 _("Svndiff contains a too-large window"));
@@ -1029,7 +832,7 @@ read_window_header(svn_stream_t *stream,
   if (*tview_len > SVN_DELTA_WINDOW_SIZE ||
       *sview_len > SVN_DELTA_WINDOW_SIZE ||
       /* for svndiff1, newlen includes the original length */
-      *newlen > SVN_DELTA_WINDOW_SIZE + MAX_ENCODED_INT_LEN ||
+      *newlen > SVN_DELTA_WINDOW_SIZE + SVN__MAX_ENCODED_UINT_LEN ||
       *inslen > MAX_INSTRUCTION_SECTION_LEN)
     return svn_error_create(SVN_ERR_SVNDIFF_CORRUPT_WINDOW, NULL,
                             _("Svndiff contains a too-large window"));
@@ -1086,18 +889,3 @@ svn_txdelta_skip_svndiff_window(apr_file
 }
 
 
-svn_error_t *
-svn__compress(svn_string_t *in,
-              svn_stringbuf_t *out,
-              int compression_level)
-{
-  return zlib_encode(in->data, in->len, out, compression_level);
-}
-
-svn_error_t *
-svn__decompress(svn_string_t *in,
-                svn_stringbuf_t *out,
-                apr_size_t limit)
-{
-  return zlib_decode((const unsigned char*)in->data, in->len, out, limit);
-}

Modified: subversion/branches/cache-server/subversion/libsvn_delta/text_delta.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_delta/text_delta.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_delta/text_delta.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_delta/text_delta.c Tue Oct 15 08:52:06 2013
@@ -669,7 +669,7 @@ patterning_copy(char *target, const char
 
 #if SVN_UNALIGNED_ACCESS_IS_OK
 
-  if (end + sizeof(apr_uint32_t) <= target)
+  if (source + sizeof(apr_uint32_t) <= target)
     {
       /* Source and target are at least 4 bytes apart, so we can copy in
        * 4-byte chunks.  */

Modified: subversion/branches/cache-server/subversion/libsvn_delta/xdelta.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_delta/xdelta.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_delta/xdelta.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_delta/xdelta.c Tue Oct 15 08:52:06 2013
@@ -27,8 +27,10 @@
 #include <apr_general.h>        /* for APR_INLINE */
 #include <apr_hash.h>
 
+#include "svn_private_config.h"
 #include "svn_hash.h"
 #include "svn_delta.h"
+#include "private/svn_string_private.h"
 #include "delta.h"
 
 /* This is pseudo-adler32. It is adler32 without the prime modulus.
@@ -223,73 +225,6 @@ init_blocks_table(const char *data,
     add_block(blocks, init_adler32(data + i), i);
 }
 
-/* Return the lowest position at which A and B differ. If no difference
- * can be found in the first MAX_LEN characters, MAX_LEN will be returned.
- */
-static apr_size_t
-match_length(const char *a, const char *b, apr_size_t max_len)
-{
-  apr_size_t pos = 0;
-
-#if SVN_UNALIGNED_ACCESS_IS_OK
-
-  /* Chunky processing is so much faster ...
-   *
-   * We can't make this work on architectures that require aligned access
-   * because A and B will probably have different alignment. So, skipping
-   * the first few chars until alignment is reached is not an option.
-   */
-  for (; pos + sizeof(apr_size_t) <= max_len; pos += sizeof(apr_size_t))
-    if (*(const apr_size_t*)(a + pos) != *(const apr_size_t*)(b + pos))
-      break;
-
-#endif
-
-  for (; pos < max_len; ++pos)
-    if (a[pos] != b[pos])
-      break;
-
-  return pos;
-}
-
-/* Return the number of bytes before A and B that don't differ.  If no
- * difference can be found in the first MAX_LEN characters,  MAX_LEN will
- * be returned.  Please note that A-MAX_LEN and B-MAX_LEN must both be
- * valid addresses.
- */
-static apr_size_t
-reverse_match_length(const char *a, const char *b, apr_size_t max_len)
-{
-  apr_size_t pos = 0;
-
-#if SVN_UNALIGNED_ACCESS_IS_OK
-
-  /* Chunky processing is so much faster ...
-   *
-   * We can't make this work on architectures that require aligned access
-   * because A and B will probably have different alignment. So, skipping
-   * the first few chars until alignment is reached is not an option.
-   */
-  for (pos = sizeof(apr_size_t); pos <= max_len; pos += sizeof(apr_size_t))
-    if (*(const apr_size_t*)(a - pos) != *(const apr_size_t*)(b - pos))
-      break;
-
-  pos -= sizeof(apr_size_t);
-
-#endif
-
-  /* If we find a mismatch at -pos, pos-1 characters matched.
-   */
-  while (++pos <= max_len)
-    if (a[0-pos] != b[0-pos])
-      return pos - 1;
-
-  /* No mismatch found -> at least MAX_LEN matching chars.
-   */
-  return max_len;
-}
-
-
 /* Try to find a match for the target data B in BLOCKS, and then
    extend the match as long as data in A and B at the match position
    continues to match.  We set the position in A we ended up in (in
@@ -323,9 +258,9 @@ find_match(const struct blocks *blocks,
   max_delta = asize - apos - MATCH_BLOCKSIZE < bsize - bpos - MATCH_BLOCKSIZE
             ? asize - apos - MATCH_BLOCKSIZE
             : bsize - bpos - MATCH_BLOCKSIZE;
-  delta = match_length(a + apos + MATCH_BLOCKSIZE,
-                       b + bpos + MATCH_BLOCKSIZE,
-                       max_delta);
+  delta = svn_cstring__match_length(a + apos + MATCH_BLOCKSIZE,
+                                    b + bpos + MATCH_BLOCKSIZE,
+                                    max_delta);
 
   /* See if we can extend backwards (max MATCH_BLOCKSIZE-1 steps because A's
      content has been sampled only every MATCH_BLOCKSIZE positions).  */
@@ -362,7 +297,8 @@ store_delta_trailer(svn_txdelta__ops_bat
   if (max_len == 0)
     return;
 
-  end_match = reverse_match_length(a + asize, b + bsize, max_len);
+  end_match = svn_cstring__reverse_match_length(a + asize, b + bsize,
+                                                max_len);
   if (end_match <= 4)
     end_match = 0;
 
@@ -414,7 +350,7 @@ compute_delta(svn_txdelta__ops_baton_t *
   /* Optimization: directly compare window starts. If more than 4
    * bytes match, we can immediately create a matching windows.
    * Shorter sequences result in a net data increase. */
-  lo = match_length(a, b, asize > bsize ? bsize : asize);
+  lo = svn_cstring__match_length(a, b, asize > bsize ? bsize : asize);
   if ((lo > 4) || (lo == bsize))
     {
       svn_txdelta__insert_op(build_baton, svn_txdelta_source,
@@ -468,7 +404,8 @@ compute_delta(svn_txdelta__ops_baton_t *
             {
               /* the match borders on the previous op. Maybe, we found a
                * match that is better than / overlapping the previous one. */
-              apr_size_t len = reverse_match_length(a + apos, b + lo, apos < lo ? apos : lo);
+              apr_size_t len = svn_cstring__reverse_match_length
+                                 (a + apos, b + lo, apos < lo ? apos : lo);
               if (len > 0)
                 {
                   len = svn_txdelta__remove_copy(build_baton, len);

Modified: subversion/branches/cache-server/subversion/libsvn_diff/diff_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_diff/diff_file.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_diff/diff_file.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_diff/diff_file.c Tue Oct 15 08:52:06 2013
@@ -166,26 +166,39 @@ read_chunk(apr_file_t *file, const char 
 static svn_error_t *
 map_or_read_file(apr_file_t **file,
                  MMAP_T_PARAM(mm)
-                 char **buffer, apr_off_t *size,
+                 char **buffer, apr_size_t *size_p,
                  const char *path, apr_pool_t *pool)
 {
   apr_finfo_t finfo;
   apr_status_t rv;
+  apr_size_t size;
 
   *buffer = NULL;
 
   SVN_ERR(svn_io_file_open(file, path, APR_READ, APR_OS_DEFAULT, pool));
   SVN_ERR(svn_io_file_info_get(&finfo, APR_FINFO_SIZE, *file, pool));
 
+  if (finfo.size > APR_SIZE_MAX)
+    {
+      return svn_error_createf(APR_ENOMEM, NULL,
+                               _("File '%s' is too large to be read in "
+                                 "to memory"), path);
+    }
+
+  size = (apr_size_t) finfo.size;
 #if APR_HAS_MMAP
-  if (finfo.size > APR_MMAP_THRESHOLD)
+  if (size > APR_MMAP_THRESHOLD)
     {
-      rv = apr_mmap_create(mm, *file, 0, (apr_size_t) finfo.size,
-                           APR_MMAP_READ, pool);
+      rv = apr_mmap_create(mm, *file, 0, size, APR_MMAP_READ, pool);
       if (rv == APR_SUCCESS)
         {
           *buffer = (*mm)->mm;
         }
+      else
+        {
+          /* Clear *MM because output parameters are undefined on error. */
+          *mm = NULL;
+        }
 
       /* On failure we just fall through and try reading the file into
        * memory instead.
@@ -193,12 +206,11 @@ map_or_read_file(apr_file_t **file,
     }
 #endif /* APR_HAS_MMAP */
 
-   if (*buffer == NULL && finfo.size > 0)
+   if (*buffer == NULL && size > 0)
     {
-      *buffer = apr_palloc(pool, (apr_size_t) finfo.size);
+      *buffer = apr_palloc(pool, size);
 
-      SVN_ERR(svn_io_file_read_full2(*file, *buffer, (apr_size_t) finfo.size,
-                                     NULL, NULL, pool));
+      SVN_ERR(svn_io_file_read_full2(*file, *buffer, size, NULL, NULL, pool));
 
       /* Since we have the entire contents of the file we can
        * close it now.
@@ -208,7 +220,7 @@ map_or_read_file(apr_file_t **file,
       *file = NULL;
     }
 
-  *size = finfo.size;
+  *size_p = size;
 
   return SVN_NO_ERROR;
 }
@@ -634,7 +646,7 @@ find_identical_suffix(apr_off_t *suffix_
         min_curp[0] += suffix_min_offset0;
 
       /* Scan quickly by reading with machine-word granularity. */
-      for (i = 0, can_read_word = TRUE; i < file_len; i++)
+      for (i = 0, can_read_word = TRUE; can_read_word && i < file_len; i++)
         can_read_word = can_read_word
                         && (  (file_for_suffix[i].curp + 1
                                  - sizeof(apr_uintptr_t))
@@ -652,7 +664,7 @@ find_identical_suffix(apr_off_t *suffix_
           if (contains_eol(chunk))
             break;
 
-          for (i = 1, is_match = TRUE; i < file_len; i++)
+          for (i = 1, is_match = TRUE; is_match && i < file_len; i++)
             is_match = is_match
                        && (   chunk
                            == *(const apr_uintptr_t *)
@@ -957,7 +969,7 @@ datasource_get_next_token(apr_uint32_t *
          function.
 
          When changing things here, make sure the whitespace settings are
-         applied, or we mught not reach the exact suffix boundary as token
+         applied, or we might not reach the exact suffix boundary as token
          boundary. */
       SVN_ERR(read_chunk(file->file, file->path,
                          curp, length,
@@ -2360,7 +2372,7 @@ svn_diff_file_output_merge2(svn_stream_t
 
   for (idx = 0; idx < 3; idx++)
     {
-      apr_off_t size;
+      apr_size_t size;
 
       SVN_ERR(map_or_read_file(&file[idx],
                                MMAP_T_ARG(mm[idx])