You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2013/05/07 15:26:27 UTC

svn commit: r1479901 [2/7] - in /subversion/branches/wc-collate-path: ./ build/ac-macros/ build/generator/ build/generator/templates/ contrib/server-side/fsfsfixer/ contrib/server-side/fsfsfixer/fixer/ subversion/bindings/ctypes-python/ subversion/bind...

Modified: subversion/branches/wc-collate-path/subversion/libsvn_client/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/libsvn_client/log.c?rev=1479901&r1=1479900&r2=1479901&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/libsvn_client/log.c (original)
+++ subversion/branches/wc-collate-path/subversion/libsvn_client/log.c Tue May  7 13:26:25 2013
@@ -42,6 +42,7 @@
 #include "svn_private_config.h"
 #include "private/svn_wc_private.h"
 
+#include <assert.h>
 
 /*** Getting misc. information ***/
 
@@ -260,59 +261,223 @@ limit_receiver(void *baton, svn_log_entr
   return rb->receiver(rb->baton, log_entry, pool);
 }
 
-
-/*** Public Interface. ***/
+/* Resolve the URLs or WC path in TARGETS as per the svn_client_log5 API.
 
+   The limitations on TARGETS specified by svn_client_log5 are enforced here.
+   So TARGETS can only contain a single WC path or a URL and zero or more
+   relative paths -- anything else will raise an error. 
 
-svn_error_t *
-svn_client_log5(const apr_array_header_t *targets,
-                const svn_opt_revision_t *peg_revision,
-                const apr_array_header_t *revision_ranges,
-                int limit,
-                svn_boolean_t discover_changed_paths,
-                svn_boolean_t strict_node_history,
-                svn_boolean_t include_merged_revisions,
-                const apr_array_header_t *revprops,
-                svn_log_entry_receiver_t real_receiver,
-                void *real_receiver_baton,
-                svn_client_ctx_t *ctx,
-                apr_pool_t *pool)
+   PEG_REVISION, TARGETS, and CTX are as per svn_client_log5.
+
+   If TARGETS contains a single WC path then set *RA_TARGET to the absolute
+   path of that single path if PEG_REVISION is dependent on the working copy
+   (e.g. PREV).  Otherwise set *RA_TARGET to the corresponding URL for the
+   single WC path.  Set *RELATIVE_TARGETS to an array with a single
+   element "".
+
+   If TARGETS contains only a single URL, then set *RA_TARGET to a copy of
+   that URL and *RELATIVE_TARGETS to an array with a single element "".
+
+   If TARGETS contains a single URL and one or more relative paths, then
+   set *RA_TARGET to a copy of that URL and *CONDENSED_PATHS to a copy of
+   each relative path after the URL.
+
+   If *PEG_REVISION is svn_opt_revision_unspecified, then *PEG_REVISION is
+   set to svn_opt_revision_head for URLs or svn_opt_revision_working for a
+   WC path.
+
+   *RA_TARGET and *RELATIVE_TARGETS are allocated in RESULT_POOL. */
+static svn_error_t *
+resolve_log_targets(apr_array_header_t **relative_targets,
+                    const char **ra_target,
+                    svn_opt_revision_t *peg_revision,
+                    const apr_array_header_t *targets,
+                    svn_client_ctx_t *ctx,
+                    apr_pool_t *result_pool,
+                    apr_pool_t *scratch_pool)
 {
-  svn_ra_session_t *ra_session;
-  const char *url_or_path;
-  svn_boolean_t has_log_revprops;
-  apr_array_header_t *condensed_targets;
-  svn_opt_revision_t session_opt_rev;
-  const char *ra_target;
-  pre_15_receiver_baton_t rb = {0};
-  apr_pool_t *iterpool;
   int i;
-  svn_opt_revision_t peg_rev;
-  svn_boolean_t url_targets = FALSE;
-  svn_opt_revision_t resolved_peg_rev;
-  const char *resolved_target;
+  svn_boolean_t url_targets;
+
+  /* Per svn_client_log5, TARGETS contains either a URL followed by zero or
+     more relative paths, or one working copy path. */
+  const char *url_or_path = APR_ARRAY_IDX(targets, 0, const char *);
+
+  /* svn_client_log5 requires at least one target. */
+  if (targets->nelts == 0)
+    return svn_error_create(SVN_ERR_ILLEGAL_TARGET, NULL,
+                            _("No valid target found"));
 
-  if (revision_ranges->nelts == 0)
+  /* Initialize the output array. */
+  *relative_targets = apr_array_make(result_pool, 1, sizeof(const char *));
+
+  if (svn_path_is_url(url_or_path))
     {
-      return svn_error_create
-        (SVN_ERR_CLIENT_BAD_REVISION, NULL,
-         _("Missing required revision specification"));
+      /* An unspecified PEG_REVISION for a URL path defaults
+         to svn_opt_revision_head. */
+      if (peg_revision->kind == svn_opt_revision_unspecified)
+          (*peg_revision).kind = svn_opt_revision_head;
+
+      /* The logic here is this: If we get passed one argument, we assume
+         it is the full URL to a file/dir we want log info for. If we get
+         a URL plus some paths, then we assume that the URL is the base,
+         and that the paths passed are relative to it.  */
+      if (targets->nelts > 1)
+        {
+          /* We have some paths, let's use them. Start after the URL.  */
+          for (i = 1; i < targets->nelts; i++)
+            {
+              const char *target;
+
+              target = APR_ARRAY_IDX(targets, i, const char *);
+
+              if (svn_path_is_url(target) || svn_dirent_is_absolute(target))
+                return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+                                         _("'%s' is not a relative path"),
+                                          target);
+
+              APR_ARRAY_PUSH(*relative_targets, const char *) =
+                apr_pstrdup(result_pool, target);
+            }
+        }
+      else
+        {
+          /* If we have a single URL, then the session will be rooted at
+             it, so just send an empty string for the paths we are
+             interested in. */
+          APR_ARRAY_PUSH(*relative_targets, const char *) = "";
+        }
+
+      /* Remember that our targets are URLs. */
+      url_targets = TRUE;
     }
+  else /* WC path target. */
+    {
+      const char *target;
+      const char *target_abspath;
 
-  /* Make a copy of PEG_REVISION, we may need to change it to a
-     default value. */
-  peg_rev = *peg_revision;
+      url_targets = FALSE;
+      if (targets->nelts > 1)
+        return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+                                _("When specifying working copy paths, only "
+                                  "one target may be given"));
 
-  /* Use the passed URL, if there is one.  */
-  url_or_path = APR_ARRAY_IDX(targets, 0, const char *);
-  session_opt_rev.kind = svn_opt_revision_unspecified;
+      /* An unspecified PEG_REVISION for a working copy path defaults
+         to svn_opt_revision_working. */
+      if (peg_revision->kind == svn_opt_revision_unspecified)
+          (*peg_revision).kind = svn_opt_revision_working;
 
-  for (i = 0; i < revision_ranges->nelts; i++)
+      /* Get URLs for each target */
+      target = APR_ARRAY_IDX(targets, 0, const char *);
+
+      SVN_ERR(svn_dirent_get_absolute(&target_abspath, target, scratch_pool));
+      SVN_ERR(svn_wc__node_get_url(&url_or_path, ctx->wc_ctx, target_abspath,
+                                   scratch_pool, scratch_pool));
+      APR_ARRAY_PUSH(*relative_targets, const char *) = "";
+    }
+
+  /* If this is a revision type that requires access to the working copy,
+   * we use our initial target path to figure out where to root the RA
+   * session, otherwise we use our URL. */
+  if (SVN_CLIENT__REVKIND_NEEDS_WC(peg_revision->kind))
+    {
+      if (url_targets)
+        return svn_error_create(SVN_ERR_CLIENT_BAD_REVISION, NULL,
+                                _("PREV, BASE, or COMMITTED revision "
+                                  "keywords are invalid for URL"));
+
+      else
+        SVN_ERR(svn_dirent_get_absolute(
+          ra_target, APR_ARRAY_IDX(targets, 0, const char *), result_pool));
+    }
+  else
+    {
+      *ra_target = apr_pstrdup(result_pool, url_or_path);
+    }
+
+  return SVN_NO_ERROR;
+}
+
+/* Keep track of oldest and youngest opt revs found.
+
+   If REV is younger than *YOUNGEST_REV, or *YOUNGEST_REV is
+   svn_opt_revision_unspecified, then set *YOUNGEST_REV equal to REV.
+
+   If REV is older than *OLDEST_REV, or *OLDEST_REV is
+   svn_opt_revision_unspecified, then set *OLDEST_REV equal to REV. */
+static void
+find_youngest_and_oldest_revs(svn_revnum_t *youngest_rev,
+                              svn_revnum_t *oldest_rev,
+                              svn_revnum_t rev)
+{
+  /* Is REV younger than YOUNGEST_REV? */
+  if (! SVN_IS_VALID_REVNUM(*youngest_rev)
+      || rev > *youngest_rev)
+    *youngest_rev = rev;
+
+  if (! SVN_IS_VALID_REVNUM(*oldest_rev)
+      || rev < *oldest_rev)
+    *oldest_rev = rev;
+
+  return;
+}
+
+typedef struct rev_range_t
+{
+  svn_revnum_t range_start;
+  svn_revnum_t range_end;
+} rev_range_t;
+
+/* Convert array of svn_opt_revision_t ranges to an array of svn_revnum_t
+   ranges.
+
+   Given a log target URL_OR_ABSPATH@PEG_REV and an array of
+   svn_opt_revision_range_t's OPT_REV_RANGES, resolve the opt revs in
+   OPT_REV_RANGES to svn_revnum_t's and return these in *REVISION_RANGES, an
+   array of rev_range_t *.
+
+   Set *YOUNGEST_REV and *OLDEST_REV to the youngest and oldest revisions
+   found in *REVISION_RANGES.
+
+   If the repository needs to be contacted to resolve svn_opt_revision_date or
+   svn_opt_revision_head revisions, then the session used to do this is
+   RA_SESSION; it must be an open session to any URL in the right repository.
+*/
+static svn_error_t*
+convert_opt_rev_array_to_rev_range_array(
+  apr_array_header_t **revision_ranges,
+  svn_revnum_t *youngest_rev,
+  svn_revnum_t *oldest_rev,
+  svn_ra_session_t *ra_session,
+  const char *url_or_abspath,
+  const apr_array_header_t *opt_rev_ranges,
+  const svn_opt_revision_t *peg_rev,
+  svn_client_ctx_t *ctx,
+  apr_pool_t *result_pool,
+  apr_pool_t *scratch_pool)
+{
+  int i;
+  svn_revnum_t head_rev = SVN_INVALID_REVNUM;
+
+  /* Initialize the input/output parameters. */
+  *youngest_rev = *oldest_rev = SVN_INVALID_REVNUM;
+
+  /* Convert OPT_REV_RANGES to an array of rev_range_t and find the youngest
+     and oldest revision range that spans all of OPT_REV_RANGES. */
+  *revision_ranges = apr_array_make(result_pool, opt_rev_ranges->nelts,
+                                    sizeof(rev_range_t *));
+
+  for (i = 0; i < opt_rev_ranges->nelts; i++)
     {
       svn_opt_revision_range_t *range;
+      rev_range_t *rev_range;
+      svn_boolean_t start_same_as_end = FALSE;
 
-      range = APR_ARRAY_IDX(revision_ranges, i, svn_opt_revision_range_t *);
+      range = APR_ARRAY_IDX(opt_rev_ranges, i, svn_opt_revision_range_t *);
 
+      /* Right now RANGE can be any valid pair of svn_opt_revision_t's.  We
+         will now convert all RANGEs in place to the corresponding
+         svn_opt_revision_number kind. */
       if ((range->start.kind != svn_opt_revision_unspecified)
           && (range->end.kind == svn_opt_revision_unspecified))
         {
@@ -331,15 +496,15 @@ svn_client_log5(const apr_array_header_t
           /* Default to any specified peg revision.  Otherwise, if the
            * first target is a URL, then we default to HEAD:0.  Lastly,
            * the default is BASE:0 since WC@HEAD may not exist. */
-          if (peg_rev.kind == svn_opt_revision_unspecified)
+          if (peg_rev->kind == svn_opt_revision_unspecified)
             {
-              if (svn_path_is_url(url_or_path))
+              if (svn_path_is_url(url_or_abspath))
                 range->start.kind = svn_opt_revision_head;
               else
                 range->start.kind = svn_opt_revision_base;
             }
           else
-            range->start = peg_rev;
+            range->start = *peg_rev;
 
           if (range->end.kind == svn_opt_revision_unspecified)
             {
@@ -356,179 +521,102 @@ svn_client_log5(const apr_array_header_t
              _("Missing required revision specification"));
         }
 
-      /* Determine the revision to open the RA session to. */
-      if (session_opt_rev.kind == svn_opt_revision_unspecified)
-        {
-          if (range->start.kind == svn_opt_revision_number &&
-              range->end.kind == svn_opt_revision_number)
-            {
-              session_opt_rev =
-                  (range->start.value.number > range->end.value.number ?
-                   range->start : range->end);
-            }
-          else if (range->start.kind == svn_opt_revision_head ||
-                   range->end.kind == svn_opt_revision_head)
-            {
-              session_opt_rev.kind = svn_opt_revision_head;
-            }
-          else if (range->start.kind == svn_opt_revision_date &&
-                   range->end.kind == svn_opt_revision_date)
-            {
-              session_opt_rev =
-                  (range->start.value.date > range->end.value.date ?
-                   range->start : range->end);
-            }
-        }
-    }
-
-  /* Use the passed URL, if there is one.  */
-  if (svn_path_is_url(url_or_path))
-    {
-      /* Initialize this array, since we'll be building it below */
-      condensed_targets = apr_array_make(pool, 1, sizeof(const char *));
-
-      /* The logic here is this: If we get passed one argument, we assume
-         it is the full URL to a file/dir we want log info for. If we get
-         a URL plus some paths, then we assume that the URL is the base,
-         and that the paths passed are relative to it.  */
-      if (targets->nelts > 1)
-        {
-          /* We have some paths, let's use them. Start after the URL.  */
-          for (i = 1; i < targets->nelts; i++)
-            {
-              const char *target;
-
-              target = APR_ARRAY_IDX(targets, i, const char *);
-
-              if (svn_path_is_url(target) || svn_dirent_is_absolute(target))
-                return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
-                                         _("'%s' is not a relative path"),
-                                          target);
-
-              APR_ARRAY_PUSH(condensed_targets, const char *) = target;
-            }
-        }
+      if (memcmp(&(range->start), &(range->end),
+                 sizeof(svn_opt_revision_t)) == 0)
+        start_same_as_end = TRUE;
+
+      rev_range = apr_palloc(result_pool, sizeof(*rev_range));
+      SVN_ERR(svn_client__get_revision_number(
+                &rev_range->range_start, &head_rev,
+                ctx->wc_ctx, url_or_abspath, ra_session,
+                &range->start, scratch_pool));
+      if (start_same_as_end)
+        rev_range->range_end = rev_range->range_start;
       else
-        {
-          /* If we have a single URL, then the session will be rooted at
-             it, so just send an empty string for the paths we are
-             interested in. */
-          APR_ARRAY_PUSH(condensed_targets, const char *) = "";
-        }
-
-      /* Remember that our targets are URLs. */
-      url_targets = TRUE;
+        SVN_ERR(svn_client__get_revision_number(
+                  &rev_range->range_end, &head_rev,
+                  ctx->wc_ctx, url_or_abspath, ra_session,
+                  &range->end, scratch_pool));
+
+      /* Possibly update the oldest and youngest revisions requested. */
+      find_youngest_and_oldest_revs(youngest_rev,
+                                    oldest_rev,
+                                    rev_range->range_start);
+      find_youngest_and_oldest_revs(youngest_rev,
+                                    oldest_rev,
+                                    rev_range->range_end);
+      APR_ARRAY_PUSH(*revision_ranges, rev_range_t *) = rev_range;
     }
-  else
-    {
-      apr_array_header_t *target_urls;
-      apr_array_header_t *real_targets;
 
-      /* See FIXME about multiple wc targets, below. */
-      if (targets->nelts > 1)
-        return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-                                _("When specifying working copy paths, only "
-                                  "one target may be given"));
+  return SVN_NO_ERROR;
+}
 
-      /* An unspecified PEG_REVISION for a working copy path defaults
-         to svn_opt_revision_working. */
-      if (peg_rev.kind == svn_opt_revision_unspecified)
-          peg_rev.kind = svn_opt_revision_working;
+static int
+compare_rev_to_segment(const void *key_p,
+                       const void *element_p)
+{
+  svn_revnum_t rev =
+    * (svn_revnum_t *)key_p;
+  const svn_location_segment_t *segment =
+    *((const svn_location_segment_t * const *) element_p);
+
+  if (rev < segment->range_start)
+    return -1;
+  else if (rev > segment->range_end)
+    return 1;
+  else
+    return 0;
+}
 
-      /* Get URLs for each target */
-      target_urls = apr_array_make(pool, 1, sizeof(const char *));
-      real_targets = apr_array_make(pool, 1, sizeof(const char *));
-      iterpool = svn_pool_create(pool);
-      for (i = 0; i < targets->nelts; i++)
-        {
-          const char *url;
-          const char *target = APR_ARRAY_IDX(targets, i, const char *);
-          const char *target_abspath;
-
-          svn_pool_clear(iterpool);
-          SVN_ERR(svn_dirent_get_absolute(&target_abspath, target, iterpool));
-          SVN_ERR(svn_wc__node_get_url(&url, ctx->wc_ctx, target_abspath,
-                                       pool, iterpool));
-
-          if (! url)
-            return svn_error_createf
-              (SVN_ERR_ENTRY_MISSING_URL, NULL,
-               _("Entry '%s' has no URL"),
-               svn_dirent_local_style(target, pool));
-
-          APR_ARRAY_PUSH(target_urls, const char *) = url;
-          APR_ARRAY_PUSH(real_targets, const char *) = target;
-        }
-
-      /* if we have no valid target_urls, just exit. */
-      if (target_urls->nelts == 0)
-        return SVN_NO_ERROR;
-
-      /* Find the base URL and condensed targets relative to it. */
-      SVN_ERR(svn_uri_condense_targets(&url_or_path, &condensed_targets,
-                                       target_urls, TRUE, pool, iterpool));
-
-      if (condensed_targets->nelts == 0)
-        APR_ARRAY_PUSH(condensed_targets, const char *) = "";
-
-      /* 'targets' now becomes 'real_targets', which has bogus,
-         unversioned things removed from it. */
-      targets = real_targets;
-      svn_pool_destroy(iterpool);
-    }
-
-
-  {
-    svn_client__pathrev_t *actual_loc;
-
-    /* If this is a revision type that requires access to the working copy,
-     * we use our initial target path to figure out where to root the RA
-     * session, otherwise we use our URL. */
-    if (SVN_CLIENT__REVKIND_NEEDS_WC(peg_rev.kind))
-      {
-        if (url_targets)
-          SVN_ERR(svn_uri_condense_targets(&ra_target, NULL, targets,
-                                           TRUE, pool, pool));
-        else
-          SVN_ERR(svn_dirent_condense_targets(&ra_target, NULL, targets,
-                                              TRUE, pool, pool));
-      }
-    else
-      ra_target = url_or_path;
-
-    SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &actual_loc,
-                                             ra_target, NULL,
-                                             &peg_rev, &session_opt_rev,
-                                             ctx, pool));
-
-    if (svn_path_is_url(ra_target))
-      {
-        resolved_target = ra_target;
-        resolved_peg_rev = peg_rev;
-      }
-    else
-      {
-        svn_client__pathrev_t *resolved_target_pathrev;
-
-        SVN_ERR(svn_client__wc_node_get_origin(&resolved_target_pathrev,
-                                               ra_target, ctx, pool, pool));
-        resolved_target = resolved_target_pathrev->url;
-        resolved_peg_rev.kind = svn_opt_revision_number;
-        resolved_peg_rev.value.number = resolved_target_pathrev->rev;
-      }
+/* Run svn_ra_get_log2 for PATHS, one or more paths relative to RA_SESSION's
+   common parent, for each revision in REVISION_RANGES, an array of
+   rev_range_t.
+
+   RA_SESSION is an open session pointing to ACTUAL_LOC.
+
+   LOG_SEGMENTS is an array of svn_location_segment_t * items representing the
+   history of PATHS from the oldest to youngest revisions found in
+   REVISION_RANGES.
+
+   The TARGETS, LIMIT, DISCOVER_CHANGED_PATHS, STRICT_NODE_HISTORY,
+   INCLUDE_MERGED_REVISIONS, REVPROPS, REAL_RECEIVER, and REAL_RECEIVER_BATON
+   parameters are all as per the svn_client_log5 API. */
+static svn_error_t *
+run_ra_get_log(apr_array_header_t *revision_ranges,
+               apr_array_header_t *paths,
+               apr_array_header_t *log_segments,
+               svn_client__pathrev_t *actual_loc,
+               svn_ra_session_t *ra_session,
+               /* The following are as per svn_client_log5. */ 
+               const apr_array_header_t *targets,
+               int limit,
+               svn_boolean_t discover_changed_paths,
+               svn_boolean_t strict_node_history,
+               svn_boolean_t include_merged_revisions,
+               const apr_array_header_t *revprops,
+               svn_log_entry_receiver_t real_receiver,
+               void *real_receiver_baton,
+               svn_client_ctx_t *ctx,
+               apr_pool_t *scratch_pool)
+{
+  int i;
+  pre_15_receiver_baton_t rb = {0};
+  apr_pool_t *iterpool;
+  svn_boolean_t has_log_revprops;
 
-    SVN_ERR(svn_ra_has_capability(ra_session, &has_log_revprops,
-                                  SVN_RA_CAPABILITY_LOG_REVPROPS, pool));
+  SVN_ERR(svn_ra_has_capability(ra_session, &has_log_revprops,
+                                SVN_RA_CAPABILITY_LOG_REVPROPS,
+                                scratch_pool));
 
-    if (!has_log_revprops) {
+  if (!has_log_revprops)
+    {
       /* See above pre-1.5 notes. */
       rb.ctx = ctx;
 
       /* Create ra session on first use */
-      rb.ra_session_pool = pool;
+      rb.ra_session_pool = scratch_pool;
       rb.ra_session_url = actual_loc->url;
     }
-  }
 
   /* It's a bit complex to correctly handle the special revision words
    * such as "BASE", "COMMITTED", and "PREV".  For example, if the
@@ -577,35 +665,54 @@ svn_client_log5(const apr_array_header_t
    * epg wonders if the repository could send a unified stream of log
    * entries if the paths and revisions were passed down.
    */
-  iterpool = svn_pool_create(pool);
+  iterpool = svn_pool_create(scratch_pool);
   for (i = 0; i < revision_ranges->nelts; i++)
     {
-      svn_revnum_t start_revnum, end_revnum, youngest_rev = SVN_INVALID_REVNUM;
+      const char *old_session_url;
       const char *path = APR_ARRAY_IDX(targets, 0, const char *);
       const char *local_abspath_or_url;
-      svn_opt_revision_range_t *range;
+      rev_range_t *range;
       limit_receiver_baton_t lb;
       svn_log_entry_receiver_t passed_receiver;
       void *passed_receiver_baton;
       const apr_array_header_t *passed_receiver_revprops;
+      svn_location_segment_t **matching_segment;
+      svn_revnum_t younger_rev;
 
       svn_pool_clear(iterpool);
 
       if (!svn_path_is_url(path))
-        SVN_ERR(svn_dirent_get_absolute(&local_abspath_or_url, path, iterpool));
+        SVN_ERR(svn_dirent_get_absolute(&local_abspath_or_url, path,
+                                        iterpool));
       else
         local_abspath_or_url = path;
 
-      range = APR_ARRAY_IDX(revision_ranges, i, svn_opt_revision_range_t *);
+      range = APR_ARRAY_IDX(revision_ranges, i, rev_range_t *);
 
-      SVN_ERR(svn_client__get_revision_number(&start_revnum, &youngest_rev,
-                                              ctx->wc_ctx, local_abspath_or_url,
-                                              ra_session, &range->start,
-                                              iterpool));
-      SVN_ERR(svn_client__get_revision_number(&end_revnum, &youngest_rev,
-                                              ctx->wc_ctx, local_abspath_or_url,
-                                              ra_session, &range->end,
-                                              iterpool));
+      /* Issue #4355: Account for renames spanning requested
+         revision ranges. */
+      younger_rev = MAX(range->range_start, range->range_end);
+      matching_segment = bsearch(&younger_rev, log_segments->elts,
+                                 log_segments->nelts, log_segments->elt_size,
+                                 compare_rev_to_segment);
+      SVN_ERR_ASSERT(*matching_segment);
+      
+      /* A segment with a NULL path means there is gap in the history.
+         We'll just proceed and let svn_ra_get_log2 fail with a useful
+         error...*/
+      if ((*matching_segment)->path != NULL)
+        {
+          /* ...but if there is history, then we must account for issue
+             #4355 and make sure our RA session is pointing at the correct
+             location. */
+          const char *segment_url = svn_path_url_add_component2(
+            actual_loc->repos_root_url, (*matching_segment)->path,
+            scratch_pool);
+          SVN_ERR(svn_client__ensure_ra_session_url(&old_session_url,
+                                                    ra_session,
+                                                    segment_url,
+                                                    scratch_pool));
+        }
 
       if (has_log_revprops)
         {
@@ -634,40 +741,10 @@ svn_client_log5(const apr_array_header_t
           passed_receiver_baton = &lb;
         }
 
-      /* Issue #4355: If multiple REVISION_RANGES were requested we might
-         need to reparent the session to account for renames. */
-      if (i > 0)
-        {
-          const char *old_session_url;
-          svn_client__pathrev_t *resolved_loc;
-
-          /* Ensure session is pointing to our starting target. */
-          SVN_ERR(svn_client__ensure_ra_session_url(&old_session_url,
-                                                    ra_session,
-                                                    resolved_target,
-                                                    pool));
-          /* Find the target's (possibly different) url at the start of
-             RANGE and then reparent the session to that if necessary. */
-          SVN_ERR(svn_client__resolve_rev_and_url(&resolved_loc, ra_session,
-                                                  resolved_target,
-                                                  &resolved_peg_rev,
-                                                  &(range->start),
-                                                  ctx, iterpool));
-          SVN_ERR(svn_client__ensure_ra_session_url(&old_session_url,
-                                                    ra_session,
-                                                    resolved_loc->url,
-                                                    pool));
-          if (!has_log_revprops)
-            {
-              /* See above pre-1.5 notes. */
-              rb.ra_session_url = resolved_loc->url;
-            }
-        }
-
       SVN_ERR(svn_ra_get_log2(ra_session,
-                              condensed_targets,
-                              start_revnum,
-                              end_revnum,
+                              paths,
+                              range->range_start,
+                              range->range_end,
                               limit,
                               discover_changed_paths,
                               strict_node_history,
@@ -690,3 +767,85 @@ svn_client_log5(const apr_array_header_t
 
   return SVN_NO_ERROR;
 }
+
+/*** Public Interface. ***/
+
+svn_error_t *
+svn_client_log5(const apr_array_header_t *targets,
+                const svn_opt_revision_t *peg_revision,
+                const apr_array_header_t *opt_rev_ranges,
+                int limit,
+                svn_boolean_t discover_changed_paths,
+                svn_boolean_t strict_node_history,
+                svn_boolean_t include_merged_revisions,
+                const apr_array_header_t *revprops,
+                svn_log_entry_receiver_t real_receiver,
+                void *real_receiver_baton,
+                svn_client_ctx_t *ctx,
+                apr_pool_t *pool)
+{
+  svn_ra_session_t *ra_session;
+  const char *old_session_url;
+  const char *ra_target;
+  svn_opt_revision_t youngest_opt_rev;
+  svn_revnum_t youngest_rev;
+  svn_revnum_t oldest_rev;
+  svn_opt_revision_t peg_rev;
+  svn_client__pathrev_t *actual_loc;
+  apr_array_header_t *log_segments;
+  apr_array_header_t *revision_ranges;
+  apr_array_header_t *relative_targets;
+
+  if (opt_rev_ranges->nelts == 0)
+    {
+      return svn_error_create
+        (SVN_ERR_CLIENT_BAD_REVISION, NULL,
+         _("Missing required revision specification"));
+    }
+
+  /* Make a copy of PEG_REVISION, we may need to change it to a
+     default value. */
+  peg_rev = *peg_revision;
+
+  SVN_ERR(resolve_log_targets(&relative_targets, &ra_target, &peg_rev,
+                              targets, ctx, pool, pool));
+
+  SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &actual_loc,
+                                            ra_target, NULL, &peg_rev, &peg_rev,
+                                            ctx, pool));
+
+  /* Convert OPT_REV_RANGES to an array of rev_range_t and find the youngest
+     and oldest revision range that spans all of OPT_REV_RANGES. */
+  SVN_ERR(convert_opt_rev_array_to_rev_range_array(&revision_ranges,
+                                                   &youngest_rev,
+                                                   &oldest_rev,
+                                                   ra_session,
+                                                   ra_target,
+                                                   opt_rev_ranges, &peg_rev,
+                                                   ctx, pool,  pool));
+
+  /* Make ACTUAL_LOC and RA_SESSION point to the youngest operative rev. */
+  youngest_opt_rev.kind = svn_opt_revision_number;
+  youngest_opt_rev.value.number = youngest_rev;
+  SVN_ERR(svn_client__resolve_rev_and_url(&actual_loc, ra_session,
+                                          ra_target, &peg_rev,
+                                          &youngest_opt_rev, ctx, pool));
+  SVN_ERR(svn_client__ensure_ra_session_url(&old_session_url, ra_session,
+                                            actual_loc->url, pool));
+
+  /* Get the svn_location_segment_t's representing the requested log ranges. */
+  SVN_ERR(svn_client__repos_location_segments(&log_segments, ra_session,
+                                              actual_loc->url,
+                                              actual_loc->rev, /* peg */
+                                              actual_loc->rev, /* start */
+                                              oldest_rev,      /* end */
+                                              ctx, pool));
+
+  SVN_ERR(run_ra_get_log(revision_ranges, relative_targets, log_segments,
+                         actual_loc, ra_session, targets, limit,
+                         discover_changed_paths, strict_node_history,
+                         include_merged_revisions, revprops, real_receiver,
+                         real_receiver_baton, ctx, pool));
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/wc-collate-path/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/libsvn_client/merge.c?rev=1479901&r1=1479900&r2=1479901&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/wc-collate-path/subversion/libsvn_client/merge.c Tue May  7 13:26:25 2013
@@ -12028,16 +12028,17 @@ operative_rev_receiver(void *baton,
   return svn_error_create(SVN_ERR_CEASE_INVOCATION, NULL, NULL);
 }
 
-/* Wrapper around svn_client_mergeinfo_log2. All arguments are as per
-   that API.  The discover_changed_paths, depth, and revprops args to
-   svn_client_mergeinfo_log2 are always TRUE, svn_depth_infinity_t,
+/* Wrapper around svn_client__mergeinfo_log. All arguments are as per
+   that private API.  The discover_changed_paths, depth, and revprops args to
+   svn_client__mergeinfo_log are always TRUE, svn_depth_infinity_t,
    and NULL respectively.
 
    If RECEIVER raises a SVN_ERR_CEASE_INVOCATION error, but still sets
    *REVISION to a valid revnum, then clear the error.  Otherwise return
    any error. */
 static svn_error_t*
-short_circuit_mergeinfo_log(svn_boolean_t finding_merged,
+short_circuit_mergeinfo_log(svn_mergeinfo_catalog_t *target_mergeinfo_cat,
+                            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,
@@ -12047,18 +12048,21 @@ short_circuit_mergeinfo_log(svn_boolean_
                             svn_log_entry_receiver_t receiver,
                             svn_revnum_t *revision,
                             svn_client_ctx_t *ctx,
+                            apr_pool_t *result_pool,
                             apr_pool_t *scratch_pool)
 {
-  svn_error_t *err = svn_client_mergeinfo_log2(finding_merged,
+  svn_error_t *err = svn_client__mergeinfo_log(finding_merged,
                                                target_path_or_url,
                                                target_peg_revision,
+                                               target_mergeinfo_cat,
                                                source_path_or_url,
                                                source_peg_revision,
                                                source_start_revision,
                                                source_end_revision,
                                                receiver, revision,
                                                TRUE, svn_depth_infinity,
-                                               NULL, ctx, scratch_pool);
+                                               NULL, ctx, result_pool,
+                                               scratch_pool);
 
   if (err)
     {
@@ -12128,6 +12132,7 @@ find_last_merged_location(svn_client__pa
   svn_opt_revision_t source_peg_rev, source_start_rev, source_end_rev,
     target_opt_rev;
   svn_revnum_t youngest_merged_rev = SVN_INVALID_REVNUM;
+  svn_mergeinfo_catalog_t target_mergeinfo_cat = NULL;
 
   source_peg_rev.kind = svn_opt_revision_number;
   source_peg_rev.value.number = source_branch->tip->rev;
@@ -12140,14 +12145,15 @@ find_last_merged_location(svn_client__pa
 
   /* Find the youngest revision fully merged from SOURCE_BRANCH to TARGET,
      if such a revision exists. */
-  SVN_ERR(short_circuit_mergeinfo_log(TRUE, /* Find merged */
+  SVN_ERR(short_circuit_mergeinfo_log(&target_mergeinfo_cat,
+                                      TRUE, /* Find merged */
                                       target->url, &target_opt_rev,
                                       source_branch->tip->url,
                                       &source_peg_rev,
                                       &source_end_rev, &source_start_rev,
                                       operative_rev_receiver,
                                       &youngest_merged_rev,
-                                      ctx, scratch_pool));
+                                      ctx, result_pool, scratch_pool));
 
   if (!SVN_IS_VALID_REVNUM(youngest_merged_rev))
     {
@@ -12174,14 +12180,15 @@ find_last_merged_location(svn_client__pa
          (i.e. finding the youngest revision after the YCA where all revs have
          been merged) that doesn't matter. */
       source_end_rev.value.number = youngest_merged_rev;
-      SVN_ERR(short_circuit_mergeinfo_log(FALSE, /* Find eligible */
+      SVN_ERR(short_circuit_mergeinfo_log(&target_mergeinfo_cat,
+                                          FALSE, /* Find eligible */
                                           target->url, &target_opt_rev,
                                           source_branch->tip->url,
                                           &source_peg_rev,
                                           &source_start_rev, &source_end_rev,
                                           operative_rev_receiver,
                                           &oldest_eligible_rev,
-                                          ctx, scratch_pool));
+                                          ctx, scratch_pool, scratch_pool));
 
       /* If there are revisions eligible for merging, use the oldest one
          to calculate the base.  Otherwise there are no operative revisions

Modified: subversion/branches/wc-collate-path/subversion/libsvn_client/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/libsvn_client/mergeinfo.c?rev=1479901&r1=1479900&r2=1479901&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/libsvn_client/mergeinfo.c (original)
+++ subversion/branches/wc-collate-path/subversion/libsvn_client/mergeinfo.c Tue May  7 13:26:25 2013
@@ -1647,11 +1647,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 +1662,15 @@ svn_client_mergeinfo_log2(svn_boolean_t 
                           svn_depth_t depth,
                           const apr_array_header_t *revprops,
                           svn_client_ctx_t *ctx,
+                          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 +1687,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 +1713,8 @@ 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);
+
   /* 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 +1722,45 @@ 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;
+          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, 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, scratch_pool, scratch_pool));
+    }
 
   if (!svn_path_is_url(target_path_or_url))
     {
@@ -1751,6 +1792,7 @@ svn_client_mergeinfo_log2(svn_boolean_t 
          history. */
       if (finding_merged)
         {
+          svn_pool_destroy(subpool);
           return SVN_NO_ERROR;
         }
       else
@@ -1768,18 +1810,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,
@@ -1792,17 +1833,17 @@ svn_client_mergeinfo_log2(svn_boolean_t 
                                               source_path_or_url, NULL,
                                               source_peg_revision,
                                               source_peg_revision,
-                                              ctx, sesspool));
+                                              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),
@@ -1813,7 +1854,7 @@ svn_client_mergeinfo_log2(svn_boolean_t 
       oldest_revs_first = FALSE;
 
     /* Close the source and target sessions. */
-    svn_pool_destroy(sesspool);
+    svn_pool_destroy(subpool);
   }
 
   /* Separate the explicit or inherited mergeinfo on TARGET_PATH_OR_URL,
@@ -2086,6 +2127,31 @@ svn_client_mergeinfo_log2(svn_boolean_t 
 }
 
 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_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, scratch_pool, scratch_pool);
+}
+
+svn_error_t *
 svn_client_suggest_merge_sources(apr_array_header_t **suggestions,
                                  const char *path_or_url,
                                  const svn_opt_revision_t *peg_revision,

Modified: subversion/branches/wc-collate-path/subversion/libsvn_client/ra.c
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/libsvn_client/ra.c?rev=1479901&r1=1479900&r2=1479901&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/libsvn_client/ra.c (original)
+++ subversion/branches/wc-collate-path/subversion/libsvn_client/ra.c Tue May  7 13:26:25 2013
@@ -447,9 +447,6 @@ svn_client_open_ra_session2(svn_ra_sessi
                                                   scratch_pool));
 }
 
-
-
-
 svn_error_t *
 svn_client__resolve_rev_and_url(svn_client__pathrev_t **resolved_loc_p,
                                 svn_ra_session_t *ra_session,

Modified: subversion/branches/wc-collate-path/subversion/libsvn_client/repos_diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/libsvn_client/repos_diff.c?rev=1479901&r1=1479900&r2=1479901&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/libsvn_client/repos_diff.c (original)
+++ subversion/branches/wc-collate-path/subversion/libsvn_client/repos_diff.c Tue May  7 13:26:25 2013
@@ -843,6 +843,37 @@ window_handler(svn_txdelta_window_t *win
   return SVN_NO_ERROR;
 }
 
+/* Implements svn_stream_lazyopen_func_t. */
+static svn_error_t *
+lazy_open_source(svn_stream_t **stream,
+                 void *baton,
+                 apr_pool_t *result_pool,
+                 apr_pool_t *scratch_pool)
+{
+  struct file_baton *fb = baton;
+
+  SVN_ERR(svn_stream_open_readonly(stream, fb->path_start_revision,
+                                   result_pool, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+/* Implements svn_stream_lazyopen_func_t. */
+static svn_error_t *
+lazy_open_result(svn_stream_t **stream,
+                 void *baton,
+                 apr_pool_t *result_pool,
+                 apr_pool_t *scratch_pool)
+{
+  struct file_baton *fb = baton;
+
+  SVN_ERR(svn_stream_open_unique(stream, &fb->path_end_revision, NULL,
+                                 svn_io_file_del_on_pool_cleanup,
+                                 result_pool, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
 /* An svn_delta_editor_t function.  */
 static svn_error_t *
 apply_textdelta(void *file_baton,
@@ -902,14 +933,13 @@ apply_textdelta(void *file_baton,
     }
 
   /* Open the file to be used as the base for second revision */
-  SVN_ERR(svn_stream_open_readonly(&src_stream, fb->path_start_revision,
-                                   scratch_pool, scratch_pool));
+  src_stream = svn_stream_lazyopen_create(lazy_open_source, fb, FALSE,
+                                          scratch_pool);
 
   /* Open the file that will become the second revision after applying the
      text delta, it starts empty */
-  SVN_ERR(svn_stream_open_unique(&result_stream, &fb->path_end_revision, NULL,
-                                 svn_io_file_del_on_pool_cleanup,
-                                 scratch_pool, scratch_pool));
+  result_stream = svn_stream_lazyopen_create(lazy_open_result, fb, FALSE,
+                                             scratch_pool);
 
   svn_txdelta_apply(src_stream,
                     result_stream,

Modified: subversion/branches/wc-collate-path/subversion/libsvn_delta/compose_delta.c
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/libsvn_delta/compose_delta.c?rev=1479901&r1=1479900&r2=1479901&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/libsvn_delta/compose_delta.c (original)
+++ subversion/branches/wc-collate-path/subversion/libsvn_delta/compose_delta.c Tue May  7 13:26:25 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/wc-collate-path/subversion/libsvn_fs/fs-loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/libsvn_fs/fs-loader.c?rev=1479901&r1=1479900&r2=1479901&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/libsvn_fs/fs-loader.c (original)
+++ subversion/branches/wc-collate-path/subversion/libsvn_fs/fs-loader.c Tue May  7 13:26:25 2013
@@ -487,6 +487,7 @@ svn_fs_upgrade(const char *path, apr_poo
 
 svn_error_t *
 svn_fs_verify(const char *path,
+              apr_hash_t *fs_config,
               svn_revnum_t start,
               svn_revnum_t end,
               svn_fs_progress_notify_func_t notify_func,
@@ -499,7 +500,7 @@ svn_fs_verify(const char *path,
   svn_fs_t *fs;
 
   SVN_ERR(fs_library_vtable(&vtable, path, pool));
-  fs = fs_new(NULL, pool);
+  fs = fs_new(fs_config, pool);
 
   SVN_MUTEX__WITH_LOCK(common_pool_lock,
                        vtable->verify_fs(fs, path, start, end,
@@ -515,6 +516,15 @@ svn_fs_path(svn_fs_t *fs, apr_pool_t *po
   return apr_pstrdup(pool, fs->path);
 }
 
+apr_hash_t *
+svn_fs_config(svn_fs_t *fs, apr_pool_t *pool)
+{
+  if (fs->config)
+    return apr_hash_copy(pool, fs->config);
+
+  return NULL;
+}
+
 svn_error_t *
 svn_fs_delete_fs(const char *path, apr_pool_t *pool)
 {
@@ -1306,7 +1316,6 @@ svn_fs_youngest_rev(svn_revnum_t *younge
   return svn_error_trace(fs->vtable->youngest_rev(youngest_p, fs, pool));
 }
 
-#ifdef SVN_FS_INFO
 svn_error_t *
 svn_fs_info_format(int *fs_format,
                    svn_version_t **supports_version,
@@ -1329,7 +1338,6 @@ svn_fs_info_config_files(apr_array_heade
                                                        result_pool,
                                                        scratch_pool));
 }
-#endif
 
 svn_error_t *
 svn_fs_deltify_revision(svn_fs_t *fs, svn_revnum_t revision, apr_pool_t *pool)
@@ -1617,24 +1625,41 @@ svn_fs_version(void)
 }
 
 
-#ifdef SVN_FS_INFO
 /** info **/
 svn_error_t *
-svn_fs_info(const svn_fs_info_t **info,
+svn_fs_info(const svn_fs_info_placeholder_t **info_p,
             svn_fs_t *fs,
             apr_pool_t *result_pool,
             apr_pool_t *scratch_pool)
 {
-  SVN__NOT_IMPLEMENTED();
+  if (fs->vtable->info_fsap)
+    {
+      SVN_ERR(fs->vtable->info_fsap((const void **)info_p, fs,
+                                    result_pool, scratch_pool));
+    }
+  else
+    {
+      svn_fs_info_placeholder_t *info = apr_palloc(result_pool, sizeof(*info));
+      /* ### Ask the disk(!), since svn_fs_t doesn't cache the answer. */
+      SVN_ERR(svn_fs_type(&info->fs_type, fs->path, result_pool));
+      *info_p = info;
+    }
+  return SVN_NO_ERROR;
 }
 
-svn_fs_info_t *
-svn_fs_info_dup(const svn_fs_info_t *info,
-                apr_pool_t *result_pool)
+void *
+svn_fs_info_dup(const void *info_void,
+                apr_pool_t *result_pool,
+                apr_pool_t *scratch_pool)
 {
-  /* Not implemented. */
-  SVN_ERR_MALFUNCTION_NO_RETURN();
-  return NULL;
+  const svn_fs_info_placeholder_t *info = info_void;
+  fs_library_vtable_t *vtable;
+
+  SVN_ERR(get_library_vtable(&vtable, info->fs_type, scratch_pool));
+  
+  if (vtable->info_fsap_dup)
+    return vtable->info_fsap_dup(info_void, result_pool);
+  else
+    return apr_pmemdup(result_pool, info, sizeof(*info));
 }
-#endif
 

Modified: subversion/branches/wc-collate-path/subversion/libsvn_fs/fs-loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/libsvn_fs/fs-loader.h?rev=1479901&r1=1479900&r2=1479901&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/libsvn_fs/fs-loader.h (original)
+++ subversion/branches/wc-collate-path/subversion/libsvn_fs/fs-loader.h Tue May  7 13:26:25 2013
@@ -131,7 +131,9 @@ typedef struct fs_library_vtable_t
                                                                const char *,
                                                                apr_hash_t *,
                                                                apr_pool_t *));
-
+  /* For svn_fs_info_fsfs_dup(). */
+  void *(*info_fsap_dup)(const void *fsap_info,
+                         apr_pool_t *result_pool);
 } fs_library_vtable_t;
 
 /* This is the type of symbol an FS module defines to fetch the
@@ -221,6 +223,11 @@ typedef struct fs_vtable_t
                                     svn_fs_t *fs,
                                     apr_pool_t *result_pool,
                                     apr_pool_t *scratch_pool);
+  svn_error_t *(*info_fsap)(const void **fsap_info,
+                            svn_fs_t *fs,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool);
+  /* info_fsap_dup is in the library vtable. */
   svn_error_t *(*verify_root)(svn_fs_root_t *root,
                               apr_pool_t *pool);
   svn_error_t *(*freeze)(svn_fs_t *fs,

Modified: subversion/branches/wc-collate-path/subversion/libsvn_fs_base/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/libsvn_fs_base/fs.c?rev=1479901&r1=1479900&r2=1479901&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/libsvn_fs_base/fs.c (original)
+++ subversion/branches/wc-collate-path/subversion/libsvn_fs_base/fs.c Tue May  7 13:26:25 2013
@@ -562,6 +562,7 @@ static fs_vtable_t fs_vtable = {
   svn_fs_base__get_locks,
   base_bdb_info_format,
   base_bdb_info_config_files,
+  NULL /* info_fsap */,
   base_bdb_verify_root,
   base_bdb_freeze,
   base_bdb_set_errcall,
@@ -1462,7 +1463,8 @@ static fs_library_vtable_t library_vtabl
   base_bdb_pack,
   base_bdb_logfiles,
   svn_fs_base__id_parse,
-  base_set_svn_fs_open
+  base_set_svn_fs_open,
+  NULL /* info_fsap_dup */
 };
 
 svn_error_t *

Modified: subversion/branches/wc-collate-path/subversion/libsvn_fs_fs/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/libsvn_fs_fs/fs.c?rev=1479901&r1=1479900&r2=1479901&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/libsvn_fs_fs/fs.c (original)
+++ subversion/branches/wc-collate-path/subversion/libsvn_fs_fs/fs.c Tue May  7 13:26:25 2013
@@ -164,6 +164,21 @@ fs_freeze(svn_fs_t *fs,
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+fs_info(const void **fsfs_info,
+        svn_fs_t *fs,
+        apr_pool_t *result_pool,
+        apr_pool_t *scratch_pool)
+{
+  fs_fs_data_t *ffd = fs->fsap_data;
+  svn_fs_fsfs_info_t *info = apr_palloc(result_pool, sizeof(*info));
+  info->fs_type = SVN_FS_TYPE_FSFS;
+  info->shard_size = ffd->max_files_per_dir;
+  info->min_unpacked_rev = ffd->min_unpacked_rev;
+  *fsfs_info = info;
+  return SVN_NO_ERROR;
+}
+
 
 
 /* The vtable associated with a specific open filesystem. */
@@ -186,6 +201,7 @@ static fs_vtable_t fs_vtable = {
   svn_fs_fs__get_locks,
   svn_fs_fs__info_format,
   svn_fs_fs__info_config_files,
+  fs_info,
   svn_fs_fs__verify_root,
   fs_freeze,
   fs_set_errcall
@@ -414,6 +430,15 @@ fs_set_svn_fs_open(svn_fs_t *fs,
   return SVN_NO_ERROR;
 }
 
+static void *
+fs_info_dup(const void *fsfs_info_void,
+            apr_pool_t *result_pool)
+{
+  /* All fields are either ints or static strings. */
+  const svn_fs_fsfs_info_t *fsfs_info = fsfs_info_void;
+  return apr_pmemdup(result_pool, fsfs_info, sizeof(*fsfs_info));
+}
+
 
 /* Base FS library vtable, used by the FS loader library. */
 
@@ -431,7 +456,8 @@ static fs_library_vtable_t library_vtabl
   fs_pack,
   fs_logfiles,
   NULL /* parse_id */,
-  fs_set_svn_fs_open
+  fs_set_svn_fs_open,
+  fs_info_dup
 };
 
 svn_error_t *

Modified: subversion/branches/wc-collate-path/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/libsvn_fs_fs/fs_fs.c?rev=1479901&r1=1479900&r2=1479901&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/wc-collate-path/subversion/libsvn_fs_fs/fs_fs.c Tue May  7 13:26:25 2013
@@ -1157,9 +1157,9 @@ read_config(fs_fs_data_t *ffd,
             const char *fs_path,
             apr_pool_t *pool)
 {
-  SVN_ERR(svn_config_read2(&ffd->config,
+  SVN_ERR(svn_config_read3(&ffd->config,
                            svn_dirent_join(fs_path, PATH_CONFIG, pool),
-                           FALSE, FALSE, pool));
+                           FALSE, FALSE, FALSE, pool));
 
   /* Initialize ffd->rep_sharing_allowed. */
   if (ffd->format >= SVN_FS_FS__MIN_REP_SHARING_FORMAT)

Modified: subversion/branches/wc-collate-path/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/libsvn_ra_serf/commit.c?rev=1479901&r1=1479900&r2=1479901&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/wc-collate-path/subversion/libsvn_ra_serf/commit.c Tue May  7 13:26:25 2013
@@ -989,7 +989,7 @@ create_put_body(serf_bucket_t **body_bkt
   apr_file_buffer_set(ctx->svndiff, NULL, 0);
 #endif
   offset = 0;
-  apr_file_seek(ctx->svndiff, APR_SET, &offset);
+  SVN_ERR(svn_io_file_seek(ctx->svndiff, APR_SET, &offset, pool));
 
   *body_bkt = serf_bucket_file_create(ctx->svndiff, alloc);
   return SVN_NO_ERROR;

Modified: subversion/branches/wc-collate-path/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/libsvn_ra_serf/update.c?rev=1479901&r1=1479900&r2=1479901&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/wc-collate-path/subversion/libsvn_ra_serf/update.c Tue May  7 13:26:25 2013
@@ -94,8 +94,8 @@ typedef enum report_state_e {
 
    We measure outstanding requests as the sum of NUM_ACTIVE_FETCHES and
    NUM_ACTIVE_PROPFINDS in the report_context_t structure.  */
-#define REQUEST_COUNT_TO_PAUSE 1000
-#define REQUEST_COUNT_TO_RESUME 100
+#define REQUEST_COUNT_TO_PAUSE 50
+#define REQUEST_COUNT_TO_RESUME 40
 
 
 /* Forward-declare our report context. */
@@ -2721,7 +2721,7 @@ create_update_report_body(serf_bucket_t 
   apr_off_t offset;
 
   offset = 0;
-  apr_file_seek(report->body_file, APR_SET, &offset);
+  SVN_ERR(svn_io_file_seek(report->body_file, APR_SET, &offset, pool));
 
   *body_bkt = serf_bucket_file_create(report->body_file, alloc);
 

Modified: subversion/branches/wc-collate-path/subversion/libsvn_ra_svn/marshal.c
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/libsvn_ra_svn/marshal.c?rev=1479901&r1=1479900&r2=1479901&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/libsvn_ra_svn/marshal.c (original)
+++ subversion/branches/wc-collate-path/subversion/libsvn_ra_svn/marshal.c Tue May  7 13:26:25 2013
@@ -1230,6 +1230,15 @@ static svn_error_t *vparse_tuple(const a
           else
             break;
         }
+      else if (**fmt == '3' && elt->kind == SVN_RA_SVN_WORD)
+        {
+          if (strcmp(elt->u.word, "true") == 0)
+            *va_arg(*ap, svn_tristate_t *) = svn_tristate_true;
+          else if (strcmp(elt->u.word, "false") == 0)
+            *va_arg(*ap, svn_tristate_t *) = svn_tristate_false;
+          else
+            break;
+        }
       else if (**fmt == 'l' && elt->kind == SVN_RA_SVN_LIST)
         *va_arg(*ap, apr_array_header_t **) = elt->u.list;
       else if (**fmt == '(' && elt->kind == SVN_RA_SVN_LIST)
@@ -1268,6 +1277,9 @@ static svn_error_t *vparse_tuple(const a
             case 'n':
               *va_arg(*ap, apr_uint64_t *) = SVN_RA_SVN_UNSPECIFIED_NUMBER;
               break;
+            case '3':
+              *va_arg(*ap, svn_tristate_t *) = svn_tristate_unknown;
+              break;
             case '(':
               nesting_level++;
               break;

Modified: subversion/branches/wc-collate-path/subversion/libsvn_repos/authz.c
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/libsvn_repos/authz.c?rev=1479901&r1=1479900&r2=1479901&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/libsvn_repos/authz.c (original)
+++ subversion/branches/wc-collate-path/subversion/libsvn_repos/authz.c Tue May  7 13:26:25 2013
@@ -824,7 +824,7 @@ authz_retrieve_config_repo(svn_config_t 
     {
       if (!must_exist)
         {
-          SVN_ERR(svn_config_create(cfg_p, TRUE, result_pool));
+          SVN_ERR(svn_config_create2(cfg_p, TRUE, TRUE, result_pool));
           return SVN_NO_ERROR;
         }
       else
@@ -842,7 +842,7 @@ authz_retrieve_config_repo(svn_config_t 
     }
 
   SVN_ERR(svn_fs_file_contents(&contents, root, fs_path, scratch_pool));
-  err = svn_config_parse(cfg_p, contents, TRUE, result_pool);
+  err = svn_config_parse(cfg_p, contents, TRUE, TRUE, result_pool);
 
   /* Add the URL to the error stack since the parser doesn't have it. */
   if (err != SVN_NO_ERROR)
@@ -891,7 +891,7 @@ authz_retrieve_config(svn_config_t **cfg
   else
     {
       /* Outside of repo file or Windows registry*/
-      SVN_ERR(svn_config_read2(cfg_p, path, must_exist, TRUE, pool));
+      SVN_ERR(svn_config_read3(cfg_p, path, must_exist, TRUE, TRUE, pool));
     }
 
   return SVN_NO_ERROR;
@@ -944,7 +944,7 @@ svn_repos__authz_read(svn_authz_t **auth
   if (accept_urls)
     SVN_ERR(authz_retrieve_config(&authz->cfg, path, must_exist, pool));
   else
-    SVN_ERR(svn_config_read2(&authz->cfg, path, must_exist, TRUE, pool));
+    SVN_ERR(svn_config_read3(&authz->cfg, path, must_exist, TRUE, TRUE, pool));
 
   if (groups_path)
     {
@@ -956,8 +956,8 @@ svn_repos__authz_read(svn_authz_t **auth
         SVN_ERR(authz_retrieve_config(&groups_cfg, groups_path, must_exist,
                                       pool));
       else
-        SVN_ERR(svn_config_read2(&groups_cfg, groups_path, must_exist,
-                                 TRUE, pool));
+        SVN_ERR(svn_config_read3(&groups_cfg, groups_path, must_exist,
+                                 TRUE, TRUE, pool));
 
       /* Copy the groups from groups_cfg into authz. */
       err = authz_copy_groups(authz, groups_cfg, pool);
@@ -998,14 +998,14 @@ svn_repos_authz_parse(svn_authz_t **auth
   svn_authz_t *authz = apr_palloc(pool, sizeof(*authz));
 
   /* Parse the authz stream */
-  SVN_ERR(svn_config_parse(&authz->cfg, stream, TRUE, pool));
+  SVN_ERR(svn_config_parse(&authz->cfg, stream, TRUE, TRUE, pool));
 
   if (groups_stream)
     {
       svn_config_t *groups_cfg;
 
       /* Parse the groups stream */
-      SVN_ERR(svn_config_parse(&groups_cfg, groups_stream, TRUE, pool));
+      SVN_ERR(svn_config_parse(&groups_cfg, groups_stream, TRUE, TRUE, pool));
 
       SVN_ERR(authz_copy_groups(authz, groups_cfg, pool));
     }

Modified: subversion/branches/wc-collate-path/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/libsvn_repos/dump.c?rev=1479901&r1=1479900&r2=1479901&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/wc-collate-path/subversion/libsvn_repos/dump.c Tue May  7 13:26:25 2013
@@ -1438,7 +1438,8 @@ svn_repos_verify_fs2(svn_repos_t *repos,
     }
 
   /* Verify global metadata and backend-specific data first. */
-  SVN_ERR(svn_fs_verify(svn_fs_path(fs, pool), start_rev, end_rev,
+  SVN_ERR(svn_fs_verify(svn_fs_path(fs, pool), svn_fs_config(fs, pool),
+                        start_rev, end_rev,
                         verify_notify, verify_notify_baton,
                         cancel_func, cancel_baton, pool));
 

Modified: subversion/branches/wc-collate-path/subversion/libsvn_repos/fs-wrap.c
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/libsvn_repos/fs-wrap.c?rev=1479901&r1=1479900&r2=1479901&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/libsvn_repos/fs-wrap.c (original)
+++ subversion/branches/wc-collate-path/subversion/libsvn_repos/fs-wrap.c Tue May  7 13:26:25 2013
@@ -740,7 +740,14 @@ pack_notify_func(void *baton,
   struct pack_notify_baton *pnb = baton;
   svn_repos_notify_t *notify;
 
-  notify = svn_repos_notify_create(pack_action + 3, pool);
+  /* Simple conversion works for these values. */
+  SVN_ERR_ASSERT(pack_action >= svn_fs_pack_notify_start
+                 && pack_action <= svn_fs_pack_notify_end_revprop);
+
+  notify = svn_repos_notify_create(pack_action
+                                   + svn_repos_notify_pack_shard_start
+                                   - svn_fs_pack_notify_start,
+                                   pool);
   notify->shard = shard;
   pnb->notify_func(pnb->notify_baton, notify, pool);
 

Modified: subversion/branches/wc-collate-path/subversion/libsvn_repos/hooks.c
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/libsvn_repos/hooks.c?rev=1479901&r1=1479900&r2=1479901&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/libsvn_repos/hooks.c (original)
+++ subversion/branches/wc-collate-path/subversion/libsvn_repos/hooks.c Tue May  7 13:26:25 2013
@@ -421,7 +421,8 @@ svn_repos__parse_hooks_env(apr_hash_t **
 
   if (local_abspath)
     {
-      SVN_ERR(svn_config_read2(&cfg, local_abspath, FALSE, TRUE, scratch_pool));
+      SVN_ERR(svn_config_read3(&cfg, local_abspath, FALSE,
+                               TRUE, TRUE, scratch_pool));
       b.cfg = cfg;
       b.hooks_env = apr_hash_make(result_pool);
       (void)svn_config_enumerate_sections2(cfg, parse_hooks_env_section, &b,

Modified: subversion/branches/wc-collate-path/subversion/libsvn_repos/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/libsvn_repos/repos.c?rev=1479901&r1=1479900&r2=1479901&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/libsvn_repos/repos.c (original)
+++ subversion/branches/wc-collate-path/subversion/libsvn_repos/repos.c Tue May  7 13:26:25 2013
@@ -1677,7 +1677,6 @@ svn_repos_has_capability(svn_repos_t *re
   return SVN_NO_ERROR;
 }
 
-#ifdef SVN_FS_INFO
 svn_error_t *
 svn_repos_capabilities(apr_hash_t **capabilities,
                        svn_repos_t *repos,
@@ -1734,7 +1733,6 @@ svn_repos_info_format(int *repos_format,
 
   return SVN_NO_ERROR;
 }
-#endif
 
 svn_fs_t *
 svn_repos_fs(svn_repos_t *repos)

Modified: subversion/branches/wc-collate-path/subversion/libsvn_subr/cache-inprocess.c
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/libsvn_subr/cache-inprocess.c?rev=1479901&r1=1479900&r2=1479901&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/libsvn_subr/cache-inprocess.c (original)
+++ subversion/branches/wc-collate-path/subversion/libsvn_subr/cache-inprocess.c Tue May  7 13:26:25 2013
@@ -642,6 +642,7 @@ svn_cache__create_inprocess(svn_cache__t
 
   wrapper->vtable = &inprocess_cache_vtable;
   wrapper->cache_internal = cache;
+  wrapper->pretend_empty = !!getenv("SVN_X_DOES_NOT_MARK_THE_SPOT");
 
   *cache_p = wrapper;
   return SVN_NO_ERROR;