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 2011/12/18 18:36:29 UTC

svn commit: r1220465 [3/13] - in /subversion/branches/file-handle-cache: ./ build/ build/ac-macros/ contrib/client-side/emacs/ contrib/server-side/mod_dontdothat/ notes/ subversion/bindings/javahl/tests/org/apache/subversion/javahl/ subversion/bindings...

Modified: subversion/branches/file-handle-cache/subversion/libsvn_client/diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/file-handle-cache/subversion/libsvn_client/diff.c?rev=1220465&r1=1220464&r2=1220465&view=diff
==============================================================================
--- subversion/branches/file-handle-cache/subversion/libsvn_client/diff.c (original)
+++ subversion/branches/file-handle-cache/subversion/libsvn_client/diff.c Sun Dec 18 17:36:24 2011
@@ -72,7 +72,7 @@ static const char under_string[] =
 
 /* A helper function for display_prop_diffs.  Output the differences between
    the mergeinfo stored in ORIG_MERGEINFO_VAL and NEW_MERGEINFO_VAL in a
-   human-readable form to FILE, using ENCODING.  Use POOL for temporary
+   human-readable form to OUTSTREAM, using ENCODING.  Use POOL for temporary
    allocations. */
 static svn_error_t *
 display_mergeinfo_diff(const char *old_mergeinfo_val,
@@ -147,18 +147,25 @@ display_mergeinfo_diff(const char *old_m
    If TOKEN is empty, or is already terminated by an EOL marker,
    return TOKEN unmodified. Else, return a new string consisting
    of the concatenation of TOKEN and the system's default EOL marker.
-   The new string is allocated from POOL. */
+   The new string is allocated from POOL.
+   If HAD_EOL is not NULL, indicate in *HAD_EOL if the token had a EOL. */
 static const svn_string_t *
-maybe_append_eol(const svn_string_t *token, apr_pool_t *pool)
+maybe_append_eol(const svn_string_t *token, svn_boolean_t *had_eol,
+                 apr_pool_t *pool)
 {
   const char *curp;
 
+  if (had_eol)
+    *had_eol = FALSE;
+
   if (token->len == 0)
     return token;
 
   curp = token->data + token->len - 1;
   if (*curp == '\r')
     {
+      if (had_eol)
+        *had_eol = TRUE;
       return token;
     }
   else if (*curp != '\n')
@@ -167,6 +174,8 @@ maybe_append_eol(const svn_string_t *tok
     }
   else
     {
+      if (had_eol)
+        *had_eol = TRUE;
       return token;
     }
 }
@@ -509,8 +518,8 @@ print_git_diff_header(svn_stream_t *os,
 }
 
 /* A helper func that writes out verbal descriptions of property diffs
-   to FILE.   Of course, OUTSTREAM will probably be whatever was
-   passed to svn_client_diff5, which is probably stdout.
+   to OUTSTREAM.   Of course, OUTSTREAM will probably be whatever was
+   passed to svn_client_diff6(), which is probably stdout.
 
    ### FIXME needs proper docstring
 
@@ -665,18 +674,19 @@ display_prop_diffs(const apr_array_heade
         const svn_string_t *tmp;
         const svn_string_t *orig;
         const svn_string_t *val;
+        svn_boolean_t val_has_eol;
 
         /* The last character in a property is often not a newline.
-           Since the diff is not useful anyway for patching properties an
-           eol character is appended when needed to remove those pescious
-           ' \ No newline at end of file' lines. */
+           An eol character is appended to prevent the diff API to add a
+           ' \ No newline at end of file' line. We add 
+           ' \ No newline at end of property' manually if needed. */
         tmp = original_value ? original_value 
                              : svn_string_create_empty(iterpool);
-        orig = maybe_append_eol(tmp, iterpool);
+        orig = maybe_append_eol(tmp, NULL, iterpool);
 
         tmp = propchange->value ? propchange->value :
                                   svn_string_create_empty(iterpool);
-        val = maybe_append_eol(tmp, iterpool);
+        val = maybe_append_eol(tmp, &val_has_eol, iterpool);
 
         SVN_ERR(svn_diff_mem_string_diff(&diff, orig, val, &options,
                                          iterpool));
@@ -695,7 +705,12 @@ display_prop_diffs(const apr_array_heade
                                            svn_dirent_local_style(path,
                                                                   iterpool),
                                            encoding, orig, val, iterpool));
-
+        if (!val_has_eol)
+          {
+            const char *s = "\\ No newline at end of property" APR_EOL_STR;
+            apr_size_t len = strlen(s);
+            SVN_ERR(svn_stream_write(outstream, s, &len));
+          }
       }
     }
   svn_pool_destroy(iterpool);
@@ -741,7 +756,7 @@ struct diff_cmd_baton {
   const char *orig_path_2;
 
   /* These are the numeric representations of the revisions passed to
-     svn_client_diff5, either may be SVN_INVALID_REVNUM.  We need these
+     svn_client_diff6(), either may be SVN_INVALID_REVNUM.  We need these
      because some of the svn_wc_diff_callbacks4_t don't get revision
      arguments.
 
@@ -1377,16 +1392,17 @@ convert_to_url(const char **url,
   return SVN_NO_ERROR;
 }
 
-/** Check if paths PATH1 and PATH2 are urls and if the revisions REVISION1
- *  and REVISION2 are local. If PEG_REVISION is not unspecified, ensure that
- *  at least one of the two revisions is non-local.
- *  If PATH1 can only be found in the repository, set *IS_REPOS1 to TRUE.
- *  If PATH2 can only be found in the repository, set *IS_REPOS2 to TRUE. */
+/** Check if paths PATH_OR_URL1 and PATH_OR_URL2 are urls and if the
+ * revisions REVISION1 and REVISION2 are local. If PEG_REVISION is not
+ * unspecified, ensure that at least one of the two revisions is non-local.
+ * If PATH_OR_URL1 can only be found in the repository, set *IS_REPOS1
+ * to TRUE. If PATH_OR_URL2 can only be found in the repository, set
+ * *IS_REPOS2 to TRUE. */
 static svn_error_t *
 check_paths(svn_boolean_t *is_repos1,
             svn_boolean_t *is_repos2,
-            const char *path1,
-            const char *path2,
+            const char *path_or_url1,
+            const char *path_or_url2,
             const svn_opt_revision_t *revision1,
             const svn_opt_revision_t *revision2,
             const svn_opt_revision_t *peg_revision)
@@ -1424,15 +1440,55 @@ check_paths(svn_boolean_t *is_repos1,
          URLs.  We don't do that here, though.  We simply record that it
          needs to be done, which is information that helps us choose our
          diff helper function.  */
-      *is_repos1 = ! is_local_rev1 || svn_path_is_url(path1);
-      *is_repos2 = ! is_local_rev2 || svn_path_is_url(path2);
+      *is_repos1 = ! is_local_rev1 || svn_path_is_url(path_or_url1);
+      *is_repos2 = ! is_local_rev2 || svn_path_is_url(path_or_url2);
     }
 
   return SVN_NO_ERROR;
 }
 
-/** Prepare a repos repos diff between PATH1 and PATH2@PEG_REVISION,
- * in the revision range REVISION1:REVISION2.
+/* Raise an error if the diff target URL does not exist at REVISION.
+ * If REVISION does not equal OTHER_REVISION, mention both revisions in
+ * the error message. Use RA_SESSION to contact the repository.
+ * Use POOL for temporary allocations. */
+static svn_error_t *
+check_diff_target_exists(const char *url,
+                         svn_revnum_t revision,
+                         svn_revnum_t other_revision,
+                         svn_ra_session_t *ra_session,
+                         apr_pool_t *pool)
+{
+  svn_node_kind_t kind;
+  const char *session_url;
+
+  SVN_ERR(svn_ra_get_session_url(ra_session, &session_url, pool));
+
+  if (strcmp(url, session_url) != 0)
+    SVN_ERR(svn_ra_reparent(ra_session, url, pool));
+
+  SVN_ERR(svn_ra_check_path(ra_session, "", revision, &kind, pool));
+  if (kind == svn_node_none)
+    {
+      if (revision == other_revision)
+        return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,
+                                 _("Diff target '%s' was not found in the "
+                                   "repository at revision '%ld'"),
+                                 url, revision);
+      else
+        return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,
+                                 _("Diff target '%s' was not found in the "
+                                   "repository at revision '%ld' or '%ld'"),
+                                 url, revision, other_revision);
+     }
+
+  if (strcmp(url, session_url) != 0)
+    SVN_ERR(svn_ra_reparent(ra_session, session_url, pool));
+
+  return SVN_NO_ERROR;
+}
+
+/** Prepare a repos repos diff between PATH_OR_URL1 and
+ * PATH_OR_URL2@PEG_REVISION, in the revision range REVISION1:REVISION2.
  * Return URLs and peg revisions in *URL1, *REV1 and in *URL2, *REV2.
  * Return suitable anchors in *ANCHOR1 and *ANCHOR2, and targets in
  * *TARGET1 and *TARGET2, based on *URL1 and *URL2.
@@ -1451,43 +1507,43 @@ diff_prepare_repos_repos(const char **ur
                          const char **target2,
                          svn_ra_session_t **ra_session,
                          svn_client_ctx_t *ctx,
-                         const char *path1,
-                         const char *path2,
+                         const char *path_or_url1,
+                         const char *path_or_url2,
                          const svn_opt_revision_t *revision1,
                          const svn_opt_revision_t *revision2,
                          const svn_opt_revision_t *peg_revision,
                          apr_pool_t *pool)
 {
   svn_node_kind_t kind1, kind2;
-  const char *path2_abspath;
-  const char *path1_abspath;
+  const char *abspath_or_url2;
+  const char *abspath_or_url1;
 
-  if (!svn_path_is_url(path2))
-    SVN_ERR(svn_dirent_get_absolute(&path2_abspath, path2,
+  if (!svn_path_is_url(path_or_url2))
+    SVN_ERR(svn_dirent_get_absolute(&abspath_or_url2, path_or_url2,
                                     pool));
   else
-    path2_abspath = path2;
+    abspath_or_url2 = path_or_url2;
 
-  if (!svn_path_is_url(path1))
-    SVN_ERR(svn_dirent_get_absolute(&path1_abspath, path1,
+  if (!svn_path_is_url(path_or_url1))
+    SVN_ERR(svn_dirent_get_absolute(&abspath_or_url1, path_or_url1,
                                     pool));
   else
-    path1_abspath = path1;
+    abspath_or_url1 = path_or_url1;
 
   /* Figure out URL1 and URL2. */
-  SVN_ERR(convert_to_url(url1, ctx->wc_ctx, path1_abspath,
+  SVN_ERR(convert_to_url(url1, ctx->wc_ctx, abspath_or_url1,
                          pool, pool));
-  SVN_ERR(convert_to_url(url2, ctx->wc_ctx, path2_abspath,
+  SVN_ERR(convert_to_url(url2, ctx->wc_ctx, abspath_or_url2,
                          pool, pool));
 
   /* We need exactly one BASE_PATH, so we'll let the BASE_PATH
-     calculated for PATH2 override the one for PATH1 (since the diff
-     will be "applied" to URL2 anyway). */
+     calculated for PATH_OR_URL2 override the one for PATH_OR_URL1
+     (since the diff will be "applied" to URL2 anyway). */
   *base_path = NULL;
-  if (strcmp(*url1, path1) != 0)
-    *base_path = path1;
-  if (strcmp(*url2, path2) != 0)
-    *base_path = path2;
+  if (strcmp(*url1, path_or_url1) != 0)
+    *base_path = path_or_url1;
+  if (strcmp(*url2, path_or_url2) != 0)
+    *base_path = path_or_url2;
 
   SVN_ERR(svn_client__open_ra_session_internal(ra_session, NULL, *url2,
                                                NULL, NULL, FALSE,
@@ -1497,50 +1553,126 @@ diff_prepare_repos_repos(const char **ur
      actual URLs will be. */
   if (peg_revision->kind != svn_opt_revision_unspecified)
     {
-      svn_opt_revision_t *start_ignore, *end_ignore;
+      svn_error_t *err;
 
-      SVN_ERR(svn_client__repos_locations(url1, &start_ignore,
-                                          url2, &end_ignore,
-                                          *ra_session,
-                                          path2,
-                                          peg_revision,
-                                          revision1,
-                                          revision2,
-                                          ctx, pool));
-      /* Reparent the session, since *URL2 might have changed as a result
-         the above call. */
-      SVN_ERR(svn_ra_reparent(*ra_session, *url2, pool));
+      err = svn_client__repos_locations(url1, NULL,
+                                        url2, NULL,
+                                        *ra_session,
+                                        path_or_url2,
+                                        peg_revision,
+                                        revision1,
+                                        revision2,
+                                        ctx, pool);
+      if (err)
+        {
+          if (err->apr_err == SVN_ERR_CLIENT_UNRELATED_RESOURCES)
+            {
+              /* Don't give up just yet. A missing path might translate
+               * into an addition in the diff. Below, we verify that each
+               * URL exists on at least one side of the diff. */
+              svn_error_clear(err);
+            }
+          else
+            return svn_error_trace(err);
+        }
+      else
+        {
+          /* Reparent the session, since *URL2 might have changed as a result
+             the above call. */
+          SVN_ERR(svn_ra_reparent(*ra_session, *url2, pool));
+        }
     }
 
   /* Resolve revision and get path kind for the second target. */
   SVN_ERR(svn_client__get_revision_number(rev2, NULL, ctx->wc_ctx,
-           (path2 == *url2) ? NULL : path2_abspath,
+           (path_or_url2 == *url2) ? NULL : abspath_or_url2,
            *ra_session, revision2, pool));
   SVN_ERR(svn_ra_check_path(*ra_session, "", *rev2, &kind2, pool));
-  if (kind2 == svn_node_none)
-    return svn_error_createf
-      (SVN_ERR_FS_NOT_FOUND, NULL,
-       _("'%s' was not found in the repository at revision %ld"),
-       *url2, *rev2);
 
   /* Do the same for the first target. */
   SVN_ERR(svn_ra_reparent(*ra_session, *url1, pool));
   SVN_ERR(svn_client__get_revision_number(rev1, NULL, ctx->wc_ctx,
-           (strcmp(path1, *url1) == 0) ? NULL : path1_abspath,
+           (strcmp(path_or_url1, *url1) == 0) ? NULL : abspath_or_url1,
            *ra_session, revision1, pool));
   SVN_ERR(svn_ra_check_path(*ra_session, "", *rev1, &kind1, pool));
-  if (kind1 == svn_node_none)
-    return svn_error_createf
-      (SVN_ERR_FS_NOT_FOUND, NULL,
-       _("'%s' was not found in the repository at revision %ld"),
-       *url1, *rev1);
+
+  /* Either both URLs must exist at their respective revisions,
+   * or one of them may be missing from one side of the diff. */
+  if (kind1 == svn_node_none && kind2 == svn_node_none)
+    {
+      if (strcmp(*url1, *url2) == 0)
+        return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,
+                                 _("Diff target '%s' was not found in the "
+                                   "repository at revisions '%ld' and '%ld'"),
+                                 *url1, *rev1, *rev2);
+      else
+        return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,
+                                 _("Diff targets '%s and '%s' were not found "
+                                   "in the repository at revisions '%ld' and "
+                                   "'%ld'"),
+                                 *url1, *url2, *rev1, *rev2);
+    }
+  else if (kind1 == svn_node_none)
+    SVN_ERR(check_diff_target_exists(*url1, *rev2, *rev1, *ra_session, pool));
+  else if (kind2 == svn_node_none)
+    SVN_ERR(check_diff_target_exists(*url2, *rev1, *rev2, *ra_session, pool));
 
   /* Choose useful anchors and targets for our two URLs. */
   *anchor1 = *url1;
   *anchor2 = *url2;
   *target1 = "";
   *target2 = "";
-  if ((kind1 == svn_node_file) || (kind2 == svn_node_file))
+  if ((kind1 == svn_node_none) || (kind2 == svn_node_none))
+    {
+      svn_node_kind_t kind;
+      const char *repos_root;
+      const char *new_anchor;
+      svn_revnum_t rev;
+
+      /* The diff target does not exist on one side of the diff.
+       * This can happen if the target was added or deleted within the
+       * revision range being diffed.
+       * However, we don't know how deep within a added/deleted subtree the
+       * diff target is. Find a common parent that exists on both sides of
+       * the diff and use it as anchor for the diff operation.
+       *
+       * ### This can fail due to authz restrictions (like in issue #3242).
+       * ### But it is the only option we have right now to try to get
+       * ### a usable diff in this situation. */
+
+      SVN_ERR(svn_ra_get_repos_root2(*ra_session, &repos_root, pool));
+
+      /* Since we already know that one of the URLs does exist,
+       * look for an existing parent of the URL which doesn't exist. */
+      new_anchor = (kind1 == svn_node_none ? *anchor1 : *anchor2);
+      rev = (kind1 == svn_node_none ? *rev1 : *rev2);
+      do
+        {
+          if (strcmp(new_anchor, repos_root) != 0)
+            {
+              new_anchor = svn_path_uri_decode(svn_uri_dirname(new_anchor,
+                                                               pool),
+                                               pool);
+              if (*base_path)
+                *base_path = svn_dirent_dirname(*base_path, pool);
+            }
+
+          SVN_ERR(svn_ra_reparent(*ra_session, new_anchor, pool));
+          SVN_ERR(svn_ra_check_path(*ra_session, "", rev, &kind, pool));
+
+        }
+      while (kind != svn_node_dir);
+      *anchor1 = *anchor2 = new_anchor;
+      /* Diff targets must be relative to the new anchor. */
+      *target1 = svn_uri_skip_ancestor(new_anchor, *url1, pool);
+      *target2 = svn_uri_skip_ancestor(new_anchor, *url2, pool);
+      SVN_ERR_ASSERT(*target1 && *target2);
+      if (kind1 == svn_node_none)
+        kind1 = svn_node_dir;
+      else
+        kind2 = svn_node_dir;
+    }
+  else if ((kind1 == svn_node_file) || (kind2 == svn_node_file))
     {
       svn_uri_split(anchor1, target1, *url1, pool);
       svn_uri_split(anchor2, target2, *url2, pool);
@@ -1554,8 +1686,8 @@ diff_prepare_repos_repos(const char **ur
 
 /* A Theoretical Note From Ben, regarding do_diff().
 
-   This function is really svn_client_diff5().  If you read the public
-   API description for svn_client_diff5(), it sounds quite Grand.  It
+   This function is really svn_client_diff6().  If you read the public
+   API description for svn_client_diff6(), it sounds quite Grand.  It
    sounds really generalized and abstract and beautiful: that it will
    diff any two paths, be they working-copy paths or URLs, at any two
    revisions.
@@ -1575,7 +1707,7 @@ diff_prepare_repos_repos(const char **ur
    pigeonholed into one of these three use-cases, we currently bail
    with a friendly apology.
 
-   Perhaps someday a brave soul will truly make svn_client_diff5
+   Perhaps someday a brave soul will truly make svn_client_diff6()
    perfectly general.  For now, we live with the 90% case.  Certainly,
    the commandline client only calls this function in legal ways.
    When there are other users of svn_client.h, maybe this will become
@@ -1588,7 +1720,7 @@ static svn_error_t *
 unsupported_diff_error(svn_error_t *child_err)
 {
   return svn_error_create(SVN_ERR_INCORRECT_PARAMS, child_err,
-                          _("Sorry, svn_client_diff5 was called in a way "
+                          _("Sorry, svn_client_diff6 was called in a way "
                             "that is not yet supported"));
 }
 
@@ -1598,7 +1730,7 @@ unsupported_diff_error(svn_error_t *chil
    PATH1 and PATH2 are both working copy paths.  REVISION1 and
    REVISION2 are their respective revisions.
 
-   All other options are the same as those passed to svn_client_diff5(). */
+   All other options are the same as those passed to svn_client_diff6(). */
 static svn_error_t *
 diff_wc_wc(const char *path1,
            const svn_opt_revision_t *revision1,
@@ -1674,19 +1806,19 @@ diff_wc_wc(const char *path1,
 
 /* Perform a diff between two repository paths.
 
-   PATH1 and PATH2 may be either URLs or the working copy paths.
+   PATH_OR_URL1 and PATH_OR_URL2 may be either URLs or the working copy paths.
    REVISION1 and REVISION2 are their respective revisions.
-   If PEG_REVISION is specified, PATH2 is the path at the peg revision,
+   If PEG_REVISION is specified, PATH_OR_URL2 is the path at the peg revision,
    and the actual two paths compared are determined by following copy
-   history from PATH2.
+   history from PATH_OR_URL2.
 
-   All other options are the same as those passed to svn_client_diff5(). */
+   All other options are the same as those passed to svn_client_diff6(). */
 static svn_error_t *
 diff_repos_repos(const svn_wc_diff_callbacks4_t *callbacks,
                  struct diff_cmd_baton *callback_baton,
                  svn_client_ctx_t *ctx,
-                 const char *path1,
-                 const char *path2,
+                 const char *path_or_url1,
+                 const char *path_or_url2,
                  const svn_opt_revision_t *revision1,
                  const svn_opt_revision_t *revision2,
                  const svn_opt_revision_t *peg_revision,
@@ -1716,7 +1848,7 @@ diff_repos_repos(const svn_wc_diff_callb
   /* Prepare info for the repos repos diff. */
   SVN_ERR(diff_prepare_repos_repos(&url1, &url2, &base_path, &rev1, &rev2,
                                    &anchor1, &anchor2, &target1, &target2,
-                                   &ra_session, ctx, path1, path2,
+                                   &ra_session, ctx, path_or_url1, path_or_url2,
                                    revision1, revision2, peg_revision,
                                    pool));
 
@@ -1767,16 +1899,16 @@ diff_repos_repos(const svn_wc_diff_callb
 
 /* Perform a diff between a repository path and a working-copy path.
 
-   PATH1 may be either a URL or a working copy path.  PATH2 is a
+   PATH_OR_URL1 may be either a URL or a working copy path.  PATH2 is a
    working copy path.  REVISION1 and REVISION2 are their respective
    revisions.  If REVERSE is TRUE, the diff will be done in reverse.
-   If PEG_REVISION is specified, then PATH1 is the path in the peg
+   If PEG_REVISION is specified, then PATH_OR_URL1 is the path in the peg
    revision, and the actual repository path to be compared is
    determined by following copy history.
 
-   All other options are the same as those passed to svn_client_diff5(). */
+   All other options are the same as those passed to svn_client_diff6(). */
 static svn_error_t *
-diff_repos_wc(const char *path1,
+diff_repos_wc(const char *path_or_url1,
               const svn_opt_revision_t *revision1,
               const svn_opt_revision_t *peg_revision,
               const char *path2,
@@ -1802,21 +1934,21 @@ diff_repos_wc(const char *path1,
   void *diff_edit_baton;
   svn_boolean_t rev2_is_base = (revision2->kind == svn_opt_revision_base);
   svn_boolean_t server_supports_depth;
-  const char *abspath1;
+  const char *abspath_or_url1;
   const char *abspath2;
   const char *anchor_abspath;
 
   SVN_ERR_ASSERT(! svn_path_is_url(path2));
 
-  if (!svn_path_is_url(path1))
-    SVN_ERR(svn_dirent_get_absolute(&abspath1, path1, pool));
+  if (!svn_path_is_url(path_or_url1))
+    SVN_ERR(svn_dirent_get_absolute(&abspath_or_url1, path_or_url1, pool));
   else
-    abspath1 = path1;
+    abspath_or_url1 = path_or_url1;
 
   SVN_ERR(svn_dirent_get_absolute(&abspath2, path2, pool));
 
-  /* Convert path1 to a URL to feed to do_diff. */
-  SVN_ERR(convert_to_url(&url1, ctx->wc_ctx, abspath1, pool, pool));
+  /* Convert path_or_url1 to a URL to feed to do_diff. */
+  SVN_ERR(convert_to_url(&url1, ctx->wc_ctx, abspath_or_url1, pool, pool));
 
   SVN_ERR(svn_wc_get_actual_target2(&anchor, &target,
                                     ctx->wc_ctx, path2,
@@ -1835,11 +1967,9 @@ diff_repos_wc(const char *path1,
      actual URLs will be. */
   if (peg_revision->kind != svn_opt_revision_unspecified)
     {
-      svn_opt_revision_t *start_ignore;
-
-      SVN_ERR(svn_client__repos_locations(&url1, &start_ignore, NULL, NULL,
+      SVN_ERR(svn_client__repos_locations(&url1, NULL, NULL, NULL,
                                           NULL,
-                                          path1,
+                                          path_or_url1,
                                           peg_revision,
                                           revision1, NULL,
                                           ctx, pool));
@@ -1891,8 +2021,8 @@ diff_repos_wc(const char *path1,
 
   /* Tell the RA layer we want a delta to change our txn to URL1 */
   SVN_ERR(svn_client__get_revision_number(&rev, NULL, ctx->wc_ctx,
-                                          (strcmp(path1, url1) == 0)
-                                                    ? NULL : abspath1,
+                                          (strcmp(path_or_url1, url1) == 0)
+                                                    ? NULL : abspath_or_url1,
                                           ra_session, revision1, pool));
 
   if (!reverse)
@@ -1929,13 +2059,13 @@ diff_repos_wc(const char *path1,
 }
 
 
-/* This is basically just the guts of svn_client_diff[_peg]5(). */
+/* This is basically just the guts of svn_client_diff[_peg]6(). */
 static svn_error_t *
 do_diff(const svn_wc_diff_callbacks4_t *callbacks,
         struct diff_cmd_baton *callback_baton,
         svn_client_ctx_t *ctx,
-        const char *path1,
-        const char *path2,
+        const char *path_or_url1,
+        const char *path_or_url2,
         const svn_opt_revision_t *revision1,
         const svn_opt_revision_t *revision2,
         const svn_opt_revision_t *peg_revision,
@@ -1950,7 +2080,7 @@ do_diff(const svn_wc_diff_callbacks4_t *
   svn_boolean_t is_repos2;
 
   /* Check if paths/revisions are urls/local. */
-  SVN_ERR(check_paths(&is_repos1, &is_repos2, path1, path2,
+  SVN_ERR(check_paths(&is_repos1, &is_repos2, path_or_url1, path_or_url2,
                       revision1, revision2, peg_revision));
 
   if (is_repos1)
@@ -1959,32 +2089,33 @@ do_diff(const svn_wc_diff_callbacks4_t *
         {
           /* ### Ignores 'show_copies_as_adds'. */
           SVN_ERR(diff_repos_repos(callbacks, callback_baton, ctx,
-                                   path1, path2, revision1, revision2,
+                                   path_or_url1, path_or_url2,
+                                   revision1, revision2,
                                    peg_revision, depth, ignore_ancestry,
                                    pool));
         }
-      else /* path2 is a working copy path */
+      else /* path_or_url2 is a working copy path */
         {
-          SVN_ERR(diff_repos_wc(path1, revision1, peg_revision,
-                                path2, revision2, FALSE, depth,
+          SVN_ERR(diff_repos_wc(path_or_url1, revision1, peg_revision,
+                                path_or_url2, revision2, FALSE, depth,
                                 ignore_ancestry, show_copies_as_adds,
                                 use_git_diff_format, changelists,
                                 callbacks, callback_baton, ctx, pool));
         }
     }
-  else /* path1 is a working copy path */
+  else /* path_or_url1 is a working copy path */
     {
       if (is_repos2)
         {
-          SVN_ERR(diff_repos_wc(path2, revision2, peg_revision,
-                                path1, revision1, TRUE, depth,
+          SVN_ERR(diff_repos_wc(path_or_url2, revision2, peg_revision,
+                                path_or_url1, revision1, TRUE, depth,
                                 ignore_ancestry, show_copies_as_adds,
                                 use_git_diff_format, changelists,
                                 callbacks, callback_baton, ctx, pool));
         }
-      else /* path2 is a working copy path */
+      else /* path_or_url2 is a working copy path */
         {
-          SVN_ERR(diff_wc_wc(path1, revision1, path2, revision2,
+          SVN_ERR(diff_wc_wc(path_or_url1, revision1, path_or_url2, revision2,
                              depth, ignore_ancestry, show_copies_as_adds,
                              use_git_diff_format, changelists,
                              callbacks, callback_baton, ctx, pool));
@@ -1999,7 +2130,7 @@ do_diff(const svn_wc_diff_callbacks4_t *
    PATH1 and PATH2 are both working copy paths.  REVISION1 and
    REVISION2 are their respective revisions.
 
-   All other options are the same as those passed to svn_client_diff5(). */
+   All other options are the same as those passed to svn_client_diff6(). */
 static svn_error_t *
 diff_summarize_wc_wc(svn_client_diff_summarize_func_t summarize_func,
                      void *summarize_baton,
@@ -2057,8 +2188,8 @@ static svn_error_t *
 diff_summarize_repos_repos(svn_client_diff_summarize_func_t summarize_func,
                            void *summarize_baton,
                            svn_client_ctx_t *ctx,
-                           const char *path1,
-                           const char *path2,
+                           const char *path_or_url1,
+                           const char *path_or_url2,
                            const svn_opt_revision_t *revision1,
                            const svn_opt_revision_t *revision2,
                            const svn_opt_revision_t *peg_revision,
@@ -2091,7 +2222,7 @@ diff_summarize_repos_repos(svn_client_di
   SVN_ERR(diff_prepare_repos_repos(&url1, &url2, &base_path, &rev1, &rev2,
                                    &anchor1, &anchor2, &target1, &target2,
                                    &ra_session, ctx,
-                                   path1, path2, revision1, revision2,
+                                   path_or_url1, path_or_url2, revision1, revision2,
                                    peg_revision, pool));
 
   SVN_ERR(svn_client__get_diff_summarize_callbacks(
@@ -2132,8 +2263,8 @@ static svn_error_t *
 do_diff_summarize(svn_client_diff_summarize_func_t summarize_func,
                   void *summarize_baton,
                   svn_client_ctx_t *ctx,
-                  const char *path1,
-                  const char *path2,
+                  const char *path_or_url1,
+                  const char *path_or_url2,
                   const svn_opt_revision_t *revision1,
                   const svn_opt_revision_t *revision2,
                   const svn_opt_revision_t *peg_revision,
@@ -2146,17 +2277,19 @@ do_diff_summarize(svn_client_diff_summar
   svn_boolean_t is_repos2;
 
   /* Check if paths/revisions are urls/local. */
-  SVN_ERR(check_paths(&is_repos1, &is_repos2, path1, path2,
+  SVN_ERR(check_paths(&is_repos1, &is_repos2, path_or_url1, path_or_url2,
                       revision1, revision2, peg_revision));
 
   if (is_repos1 && is_repos2)
     return diff_summarize_repos_repos(summarize_func, summarize_baton, ctx,
-                                      path1, path2, revision1, revision2,
+                                      path_or_url1, path_or_url2,
+                                      revision1, revision2,
                                       peg_revision, depth, ignore_ancestry,
                                       pool);
   else if (! is_repos1 && ! is_repos2)
     return diff_summarize_wc_wc(summarize_func, summarize_baton,
-                                path1, revision1, path2, revision2,
+                                path_or_url1, revision1,
+                                path_or_url2, revision2,
                                 depth, ignore_ancestry,
                                 changelists, ctx, pool);
   else
@@ -2270,9 +2403,9 @@ set_up_diff_cmd_and_options(struct diff_
 */
 svn_error_t *
 svn_client_diff6(const apr_array_header_t *options,
-                 const char *path1,
+                 const char *path_or_url1,
                  const svn_opt_revision_t *revision1,
-                 const char *path2,
+                 const char *path_or_url2,
                  const svn_opt_revision_t *revision2,
                  const char *relative_to_dir,
                  svn_depth_t depth,
@@ -2295,8 +2428,8 @@ svn_client_diff6(const apr_array_header_
   peg_revision.kind = svn_opt_revision_unspecified;
 
   /* setup callback and baton */
-  diff_cmd_baton.orig_path_1 = path1;
-  diff_cmd_baton.orig_path_2 = path2;
+  diff_cmd_baton.orig_path_1 = path_or_url1;
+  diff_cmd_baton.orig_path_2 = path_or_url2;
 
   SVN_ERR(set_up_diff_cmd_and_options(&diff_cmd_baton, options,
                                       ctx->config, pool));
@@ -2319,14 +2452,15 @@ svn_client_diff6(const apr_array_header_
   diff_cmd_baton.anchor = NULL;
 
   return do_diff(&diff_callbacks, &diff_cmd_baton, ctx,
-                 path1, path2, revision1, revision2, &peg_revision,
+                 path_or_url1, path_or_url2, revision1, revision2,
+                 &peg_revision,
                  depth, ignore_ancestry, show_copies_as_adds,
                  use_git_diff_format, changelists, pool);
 }
 
 svn_error_t *
 svn_client_diff_peg6(const apr_array_header_t *options,
-                     const char *path,
+                     const char *path_or_url,
                      const svn_opt_revision_t *peg_revision,
                      const svn_opt_revision_t *start_revision,
                      const svn_opt_revision_t *end_revision,
@@ -2347,8 +2481,8 @@ svn_client_diff_peg6(const apr_array_hea
   struct diff_cmd_baton diff_cmd_baton = { 0 };
 
   /* setup callback and baton */
-  diff_cmd_baton.orig_path_1 = path;
-  diff_cmd_baton.orig_path_2 = path;
+  diff_cmd_baton.orig_path_1 = path_or_url;
+  diff_cmd_baton.orig_path_2 = path_or_url;
 
   SVN_ERR(set_up_diff_cmd_and_options(&diff_cmd_baton, options,
                                       ctx->config, pool));
@@ -2371,15 +2505,16 @@ svn_client_diff_peg6(const apr_array_hea
   diff_cmd_baton.anchor = NULL;
 
   return do_diff(&diff_callbacks, &diff_cmd_baton, ctx,
-                 path, path, start_revision, end_revision, peg_revision,
+                 path_or_url, path_or_url, start_revision, end_revision,
+                 peg_revision,
                  depth, ignore_ancestry, show_copies_as_adds,
                  use_git_diff_format, changelists, pool);
 }
 
 svn_error_t *
-svn_client_diff_summarize2(const char *path1,
+svn_client_diff_summarize2(const char *path_or_url1,
                            const svn_opt_revision_t *revision1,
-                           const char *path2,
+                           const char *path_or_url2,
                            const svn_opt_revision_t *revision2,
                            svn_depth_t depth,
                            svn_boolean_t ignore_ancestry,
@@ -2394,12 +2529,13 @@ svn_client_diff_summarize2(const char *p
   peg_revision.kind = svn_opt_revision_unspecified;
 
   return do_diff_summarize(summarize_func, summarize_baton, ctx,
-                           path1, path2, revision1, revision2, &peg_revision,
+                           path_or_url1, path_or_url2, revision1, revision2,
+                           &peg_revision,
                            depth, ignore_ancestry, changelists, pool);
 }
 
 svn_error_t *
-svn_client_diff_summarize_peg2(const char *path,
+svn_client_diff_summarize_peg2(const char *path_or_url,
                                const svn_opt_revision_t *peg_revision,
                                const svn_opt_revision_t *start_revision,
                                const svn_opt_revision_t *end_revision,
@@ -2412,8 +2548,8 @@ svn_client_diff_summarize_peg2(const cha
                                apr_pool_t *pool)
 {
   return do_diff_summarize(summarize_func, summarize_baton, ctx,
-                           path, path, start_revision, end_revision,
-                           peg_revision,
+                           path_or_url, path_or_url,
+                           start_revision, end_revision, peg_revision,
                            depth, ignore_ancestry, changelists, pool);
 }
 

Modified: subversion/branches/file-handle-cache/subversion/libsvn_client/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/file-handle-cache/subversion/libsvn_client/externals.c?rev=1220465&r1=1220464&r2=1220465&view=diff
==============================================================================
--- subversion/branches/file-handle-cache/subversion/libsvn_client/externals.c (original)
+++ subversion/branches/file-handle-cache/subversion/libsvn_client/externals.c Sun Dec 18 17:36:24 2011
@@ -606,6 +606,7 @@ handle_external_item_change(const struct
   svn_ra_session_t *ra_session;
   svn_client__ra_session_from_path_results ra_cache = { 0 };
   const char *new_url;
+  svn_node_kind_t kind;
 
   ra_cache.kind = svn_node_unknown;
 
@@ -624,43 +625,38 @@ handle_external_item_change(const struct
                                                 parent_dir_url,
                                                 scratch_pool, scratch_pool));
 
-  /* If the external is being checked out, exported or updated,
-     determine if the external is a file or directory. */
-  if (new_item)
-    {
-      svn_node_kind_t kind;
+  /* Determine if the external is a file or directory. */
+  /* Get the RA connection. */
+  SVN_ERR(svn_client__ra_session_from_path(&ra_session,
+                                           &ra_cache.ra_revnum,
+                                           &ra_cache.ra_session_url,
+                                           new_url, NULL,
+                                           &(new_item->peg_revision),
+                                           &(new_item->revision), eb->ctx,
+                                           scratch_pool));
+
+  SVN_ERR(svn_ra_get_uuid2(ra_session, &ra_cache.repos_uuid,
+                           scratch_pool));
+  SVN_ERR(svn_ra_get_repos_root2(ra_session, &ra_cache.repos_root_url,
+                                 scratch_pool));
+  SVN_ERR(svn_ra_check_path(ra_session, "", ra_cache.ra_revnum, &kind,
+                            scratch_pool));
+
+  if (svn_node_none == kind)
+    return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
+                             _("URL '%s' at revision %ld doesn't exist"),
+                             ra_cache.ra_session_url,
+                             ra_cache.ra_revnum);
+
+  if (svn_node_dir != kind && svn_node_file != kind)
+    return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
+                             _("URL '%s' at revision %ld is not a file "
+                               "or a directory"),
+                             ra_cache.ra_session_url,
+                             ra_cache.ra_revnum);
 
-      /* Get the RA connection. */
-      SVN_ERR(svn_client__ra_session_from_path(&ra_session,
-                                               &ra_cache.ra_revnum,
-                                               &ra_cache.ra_session_url,
-                                               new_url, NULL,
-                                               &(new_item->peg_revision),
-                                               &(new_item->revision), eb->ctx,
-                                               scratch_pool));
-
-      SVN_ERR(svn_ra_get_uuid2(ra_session, &ra_cache.repos_uuid,
-                               scratch_pool));
-      SVN_ERR(svn_ra_get_repos_root2(ra_session, &ra_cache.repos_root_url,
-                                     scratch_pool));
-      SVN_ERR(svn_ra_check_path(ra_session, "", ra_cache.ra_revnum, &kind,
-                                scratch_pool));
+  ra_cache.kind = kind;
 
-      if (svn_node_none == kind)
-        return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
-                                 _("URL '%s' at revision %ld doesn't exist"),
-                                 ra_cache.ra_session_url,
-                                 ra_cache.ra_revnum);
-
-      if (svn_node_dir != kind && svn_node_file != kind)
-        return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
-                                 _("URL '%s' at revision %ld is not a file "
-                                   "or a directory"),
-                                 ra_cache.ra_session_url,
-                                 ra_cache.ra_revnum);
-
-      ra_cache.kind = kind;
-    }
 
   /* Not protecting against recursive externals.  Detecting them in
      the global case is hard, and it should be pretty obvious to a
@@ -679,87 +675,44 @@ handle_external_item_change(const struct
 
   if (! old_defining_abspath)
     {
-      /* This branch is only used during a checkout or an export. */
-
-      switch (ra_cache.kind)
-        {
-        case svn_node_dir:
-          /* The target dir might have multiple components.  Guarantee
-             the path leading down to the last component. */
-          SVN_ERR(svn_io_make_dir_recursively(svn_dirent_dirname(local_abspath,
-                                                                 scratch_pool),
-                                              scratch_pool));
-
-          SVN_ERR(switch_dir_external(
-                   local_abspath, new_url,
-                   &(new_item->peg_revision), &(new_item->revision),
-                   parent_dir_abspath, eb->timestamp_sleep, eb->ctx,
-                   scratch_pool));
-          break;
-        case svn_node_file:
-          if (strcmp(eb->repos_root_url, ra_cache.repos_root_url))
-            return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-                      _("Unsupported external: "
-                        "url of file external '%s' is not in repository '%s'"),
-                      new_url, eb->repos_root_url);
-          SVN_ERR(switch_file_external(local_abspath,
-                                       new_url,
-                                       &new_item->peg_revision,
-                                       &new_item->revision,
-                                       parent_dir_abspath,
-                                       ra_session,
-                                       ra_cache.ra_session_url,
-                                       ra_cache.ra_revnum,
-                                       ra_cache.repos_root_url,
-                                       eb->timestamp_sleep, eb->ctx,
-                                       scratch_pool));
-          break;
-        default:
-          SVN_ERR_MALFUNCTION();
-          break;
-        }
+      /* The target dir might have multiple components.  Guarantee the path
+         leading down to the last component. */
+      SVN_ERR(svn_io_make_dir_recursively(svn_dirent_dirname(local_abspath,
+                                                             scratch_pool),
+                                          scratch_pool));
     }
-  else
-    {
-      /* This branch handles a definition change or simple update. */
 
-      /* Either the URL changed, or the exact same item is present in
-         both hashes, and caller wants to update such unchanged items.
-         In the latter case, the call below will try to make sure that
-         the external really is a WC pointing to the correct
-         URL/revision. */
-      switch (ra_cache.kind)
-        {
-        case svn_node_dir:
-          SVN_ERR(switch_dir_external(local_abspath, new_url,
-                                      &(new_item->peg_revision),
-                                      &(new_item->revision),
-                                      parent_dir_abspath,
-                                      eb->timestamp_sleep, eb->ctx,
-                                      scratch_pool));
-          break;
-        case svn_node_file:
-          if (strcmp(eb->repos_root_url, ra_cache.repos_root_url))
-            return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-                      _("Unsupported external: "
-                        "url of file external '%s' is not in repository '%s'"),
-                      new_url, eb->repos_root_url);
-          SVN_ERR(switch_file_external(local_abspath,
-                                       new_url,
-                                       &new_item->peg_revision,
-                                       &new_item->revision,
-                                       parent_dir_abspath,
-                                       ra_session,
-                                       ra_cache.ra_session_url,
-                                       ra_cache.ra_revnum,
-                                       ra_cache.repos_root_url,
-                                       eb->timestamp_sleep, eb->ctx,
-                                       scratch_pool));
-          break;
-        default:
-          SVN_ERR_MALFUNCTION();
-          break;
-        }
+  switch (ra_cache.kind)
+    {
+      case svn_node_dir:
+        SVN_ERR(switch_dir_external(local_abspath, new_url,
+                                    &(new_item->peg_revision),
+                                    &(new_item->revision),
+                                    parent_dir_abspath,
+                                    eb->timestamp_sleep, eb->ctx,
+                                    scratch_pool));
+        break;
+      case svn_node_file:
+        if (strcmp(eb->repos_root_url, ra_cache.repos_root_url))
+          return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+                    _("Unsupported external: "
+                      "url of file external '%s' is not in repository '%s'"),
+                    new_url, eb->repos_root_url);
+        SVN_ERR(switch_file_external(local_abspath,
+                                     new_url,
+                                     &new_item->peg_revision,
+                                     &new_item->revision,
+                                     parent_dir_abspath,
+                                     ra_session,
+                                     ra_cache.ra_session_url,
+                                     ra_cache.ra_revnum,
+                                     ra_cache.repos_root_url,
+                                     eb->timestamp_sleep, eb->ctx,
+                                     scratch_pool));
+        break;
+      default:
+        SVN_ERR_MALFUNCTION();
+        break;
     }
 
   return SVN_NO_ERROR;
@@ -943,7 +896,7 @@ svn_client__handle_externals(apr_hash_t 
     {
       const char *item_abspath = svn__apr_hash_index_key(hi);
       const char *defining_abspath = svn__apr_hash_index_val(hi);
-      svn_wc_status3_t *defining_status;
+      const char *parent_abspath;
 
       svn_pool_clear(iterpool);
 
@@ -953,19 +906,29 @@ svn_client__handle_externals(apr_hash_t 
                                                        item_abspath, iterpool),
                           iterpool));
 
-      /* Is DEFINING_ABSPATH now an unversioned directory we can remove? */
-      SVN_ERR(svn_wc_status3(&defining_status, ctx->wc_ctx, defining_abspath,
-                             iterpool, iterpool));
-      if (defining_status->node_status == svn_wc_status_unversioned)
-        {
-          svn_error_t *err;
-
-          err = svn_io_dir_remove_nonrecursive(defining_abspath, iterpool);
-          if (err && APR_STATUS_IS_ENOTEMPTY(err->apr_err))
-            svn_error_clear(err);
-          else
-            SVN_ERR(err);
-        }
+      /* Are there any unversioned directories between the removed
+       * external and the DEFINING_ABSPATH which we can remove? */
+      parent_abspath = item_abspath;
+      do {
+        svn_wc_status3_t *parent_status;
+
+        parent_abspath = svn_dirent_dirname(parent_abspath, iterpool);
+        SVN_ERR(svn_wc_status3(&parent_status, ctx->wc_ctx, parent_abspath,
+                               iterpool, iterpool));
+        if (parent_status->node_status == svn_wc_status_unversioned)
+          {
+            svn_error_t *err;
+
+            err = svn_io_dir_remove_nonrecursive(parent_abspath, iterpool);
+            if (err && APR_STATUS_IS_ENOTEMPTY(err->apr_err))
+              {
+                svn_error_clear(err);
+                break;
+              }
+            else
+              SVN_ERR(err);
+          }
+      } while (strcmp(parent_abspath, defining_abspath) != 0);
     }
 
 

Modified: subversion/branches/file-handle-cache/subversion/libsvn_client/info.c
URL: http://svn.apache.org/viewvc/subversion/branches/file-handle-cache/subversion/libsvn_client/info.c?rev=1220465&r1=1220464&r2=1220465&view=diff
==============================================================================
--- subversion/branches/file-handle-cache/subversion/libsvn_client/info.c (original)
+++ subversion/branches/file-handle-cache/subversion/libsvn_client/info.c Sun Dec 18 17:36:24 2011
@@ -145,8 +145,8 @@ push_dir_info(svn_ra_session_t *ra_sessi
 
       path = svn_relpath_join(dir, name, subpool);
       URL = svn_path_url_add_component2(session_URL, name, subpool);
-      fs_path = svn_fspath__canonicalize(svn_uri__is_child(repos_root, URL,
-                                                           subpool), subpool);
+      fs_path = svn_fspath__canonicalize(
+                  svn_uri_skip_ancestor(repos_root, URL, subpool), subpool);
 
       lock = apr_hash_get(locks, fs_path, APR_HASH_KEY_STRING);
 
@@ -187,14 +187,13 @@ same_resource_in_head(svn_boolean_t *sam
 {
   svn_error_t *err;
   svn_opt_revision_t start_rev, peg_rev;
-  svn_opt_revision_t *ignored_rev;
   const char *head_url;
 
   start_rev.kind = svn_opt_revision_head;
   peg_rev.kind = svn_opt_revision_number;
   peg_rev.value.number = rev;
 
-  err = svn_client__repos_locations(&head_url, &ignored_rev, NULL, NULL,
+  err = svn_client__repos_locations(&head_url, NULL, NULL, NULL,
                                     ra_session,
                                     url, &peg_rev,
                                     &start_rev, NULL,

Modified: subversion/branches/file-handle-cache/subversion/libsvn_client/list.c
URL: http://svn.apache.org/viewvc/subversion/branches/file-handle-cache/subversion/libsvn_client/list.c?rev=1220465&r1=1220464&r2=1220465&view=diff
==============================================================================
--- subversion/branches/file-handle-cache/subversion/libsvn_client/list.c (original)
+++ subversion/branches/file-handle-cache/subversion/libsvn_client/list.c Sun Dec 18 17:36:24 2011
@@ -32,6 +32,7 @@
 #include "client.h"
 
 #include "private/svn_fspath.h"
+#include "private/svn_ra_private.h"
 #include "svn_private_config.h"
 
 /* Get the directory entries of DIR at REV (relative to the root of
@@ -239,7 +240,6 @@ svn_client_list2(const char *path_or_url
   svn_revnum_t rev;
   svn_dirent_t *dirent;
   const char *url;
-  const char *repos_root;
   const char *fs_path;
   svn_error_t *err;
   apr_hash_t *locks;
@@ -254,11 +254,8 @@ svn_client_list2(const char *path_or_url
                                            peg_revision,
                                            revision, ctx, pool));
 
-  SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root, pool));
-
-  SVN_ERR(svn_client__path_relative_to_root(&fs_path, ctx->wc_ctx, url,
-                                            repos_root, TRUE, ra_session,
-                                            pool, pool));
+  SVN_ERR(svn_ra__get_fspath_relative_to_root(ra_session, &fs_path, url,
+                                              pool));
 
   SVN_ERR(ra_stat_compatible(ra_session, rev, &dirent, dirent_fields,
                              ctx, pool));

Modified: subversion/branches/file-handle-cache/subversion/libsvn_client/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/file-handle-cache/subversion/libsvn_client/log.c?rev=1220465&r1=1220464&r2=1220465&view=diff
==============================================================================
--- subversion/branches/file-handle-cache/subversion/libsvn_client/log.c (original)
+++ subversion/branches/file-handle-cache/subversion/libsvn_client/log.c Sun Dec 18 17:36:24 2011
@@ -299,8 +299,7 @@ svn_client_log5(const apr_array_header_t
 
   /* Make a copy of PEG_REVISION, we may need to change it to a
      default value. */
-  peg_rev.kind = peg_revision->kind;
-  peg_rev.value = peg_revision->value;
+  peg_rev = *peg_revision;
 
   /* Use the passed URL, if there is one.  */
   url_or_path = APR_ARRAY_IDX(targets, 0, const char *);
@@ -426,7 +425,7 @@ svn_client_log5(const apr_array_header_t
                                 _("When specifying working copy paths, only "
                                   "one target may be given"));
 
-      /* An unspecified PEG_REVISION for a working copy path defautls
+      /* 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;