You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2012/04/04 17:57:39 UTC

svn commit: r1309471 [1/2] - in /subversion/branches/ev2-export: ./ subversion/include/ subversion/include/private/ subversion/libsvn_client/ subversion/libsvn_delta/ subversion/libsvn_fs_base/bdb/ subversion/libsvn_subr/ subversion/svnrdump/ subversio...

Author: hwright
Date: Wed Apr  4 15:57:38 2012
New Revision: 1309471

URL: http://svn.apache.org/viewvc?rev=1309471&view=rev
Log:
On the ev2-export branch:
Bring up-to-date with trunk.

Modified:
    subversion/branches/ev2-export/   (props changed)
    subversion/branches/ev2-export/subversion/include/private/svn_client_private.h
    subversion/branches/ev2-export/subversion/include/svn_string.h
    subversion/branches/ev2-export/subversion/libsvn_client/checkout.c
    subversion/branches/ev2-export/subversion/libsvn_client/client.h
    subversion/branches/ev2-export/subversion/libsvn_client/commit_util.c
    subversion/branches/ev2-export/subversion/libsvn_client/copy.c
    subversion/branches/ev2-export/subversion/libsvn_client/info.c
    subversion/branches/ev2-export/subversion/libsvn_client/merge.c
    subversion/branches/ev2-export/subversion/libsvn_client/mergeinfo.c
    subversion/branches/ev2-export/subversion/libsvn_client/mergeinfo.h
    subversion/branches/ev2-export/subversion/libsvn_client/ra.c
    subversion/branches/ev2-export/subversion/libsvn_client/repos_diff.c
    subversion/branches/ev2-export/subversion/libsvn_client/switch.c
    subversion/branches/ev2-export/subversion/libsvn_client/util.c
    subversion/branches/ev2-export/subversion/libsvn_delta/compat.c
    subversion/branches/ev2-export/subversion/libsvn_delta/xdelta.c
    subversion/branches/ev2-export/subversion/libsvn_fs_base/bdb/env.c
    subversion/branches/ev2-export/subversion/libsvn_subr/crypto.c
    subversion/branches/ev2-export/subversion/libsvn_subr/svn_string.c
    subversion/branches/ev2-export/subversion/libsvn_subr/time.c
    subversion/branches/ev2-export/subversion/svnrdump/load_editor.c
    subversion/branches/ev2-export/subversion/tests/cmdline/copy_tests.py
    subversion/branches/ev2-export/subversion/tests/libsvn_client/client-test.c

Propchange: subversion/branches/ev2-export/
------------------------------------------------------------------------------
  Merged /subversion/trunk:r1308887-1309469

Modified: subversion/branches/ev2-export/subversion/include/private/svn_client_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/include/private/svn_client_private.h?rev=1309471&r1=1309470&r2=1309471&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/include/private/svn_client_private.h (original)
+++ subversion/branches/ev2-export/subversion/include/private/svn_client_private.h Wed Apr  4 15:57:38 2012
@@ -29,6 +29,7 @@
 
 #include <apr_pools.h>
 
+#include "svn_ra.h"
 #include "svn_client.h"
 #include "svn_types.h"
 
@@ -55,11 +56,48 @@ svn_client__pathrev_create(const char *r
                            const char *url,
                            apr_pool_t *result_pool);
 
-/* Return a deep copy of the path-rev LOC, allocated in RESULT_POOL. */
+/* Return a new path-rev structure, allocated in RESULT_POOL,
+ * initialized with deep copies of REPOS_ROOT_URL, REPOS_UUID, and REV,
+ * and using the repository-relative RELPATH to construct the URL. */
+svn_client__pathrev_t *
+svn_client__pathrev_create_with_relpath(const char *repos_root_url,
+                                        const char *repos_uuid,
+                                        svn_revnum_t rev,
+                                        const char *relpath,
+                                        apr_pool_t *result_pool);
+
+/* Set *PATHREV_P to a new path-rev structure, allocated in RESULT_POOL,
+ * initialized with deep copies of the repository root URL and UUID from
+ * RA_SESSION, and of REV and URL. */
+svn_error_t *
+svn_client__pathrev_create_with_session(svn_client__pathrev_t **pathrev_p,
+                                        svn_ra_session_t *ra_session,
+                                        svn_revnum_t rev,
+                                        const char *url,
+                                        apr_pool_t *result_pool);
+
+/* Return a deep copy of PATHREV, allocated in RESULT_POOL. */
 svn_client__pathrev_t *
-svn_client__pathrev_dup(const svn_client__pathrev_t *loc,
+svn_client__pathrev_dup(const svn_client__pathrev_t *pathrev,
                         apr_pool_t *result_pool);
 
+/* Return a deep copy of PATHREV, with a URI-encoded representation of
+ * RELPATH joined on to the URL.  Allocate the result in RESULT_POOL. */
+svn_client__pathrev_t *
+svn_client__pathrev_join_relpath(const svn_client__pathrev_t *pathrev,
+                                 const char *relpath,
+                                 apr_pool_t *result_pool);
+
+/* Return the repository-relative relpath of PATHREV. */
+const char *
+svn_client__pathrev_relpath(const svn_client__pathrev_t *pathrev,
+                            apr_pool_t *result_pool);
+
+/* Return the repository-relative fspath of PATHREV. */
+const char *
+svn_client__pathrev_fspath(const svn_client__pathrev_t *pathrev,
+                           apr_pool_t *result_pool);
+
 
 /** Return @c SVN_ERR_ILLEGAL_TARGET if TARGETS contains a mixture of
  * URLs and paths; otherwise return SVN_NO_ERROR.
@@ -106,19 +144,14 @@ svn_client__youngest_common_ancestor(con
                                      apr_pool_t *result_pool,
                                      apr_pool_t *scratch_pool);
 
-/* Set *REPOS_ROOT_URL_P, *REPOS_UUID_P, *REV and *URL to the origin of the
- * WC node at WC_ABSPATH.  If the node is a local copy, give the copy-from
- * location.  If the node is locally added or deleted, set *REV and *URL
- * to SVN_INVALID_REVNUM and NULL respectively, but still give the correct
- * repository root URL and UUID.
- *
- * Any outputs may be NULL if not wanted.
+/* Set *ORIGIN_P to the origin of the WC node at WC_ABSPATH.  If the node
+ * is a local copy, give the copy-from location.  If the node is locally
+ * added or deleted, set the REV and URL fields to SVN_INVALID_REVNUM and
+ * NULL respectively, but still give the correct repository root URL and
+ * UUID.
  */
 svn_error_t *
-svn_client__wc_node_get_origin(const char **repos_root_url_p,
-                               const char **repos_uuid_p,
-                               svn_revnum_t *rev_p,
-                               const char **url_p,
+svn_client__wc_node_get_origin(svn_client__pathrev_t **origin_p,
                                const char *wc_abspath,
                                svn_client_ctx_t *ctx,
                                apr_pool_t *result_pool,

Modified: subversion/branches/ev2-export/subversion/include/svn_string.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/include/svn_string.h?rev=1309471&r1=1309470&r2=1309471&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/include/svn_string.h (original)
+++ subversion/branches/ev2-export/subversion/include/svn_string.h Wed Apr  4 15:57:38 2012
@@ -209,8 +209,8 @@ svn_stringbuf_create_empty(apr_pool_t *p
 /** Create a new empty bytestring with at least @a minimum_size bytes of
  * space available in the memory block.
  *
- * The allocated string buffer will be one byte larger than @a minimum_size
- * to account for a final '\\0'.
+ * The allocated string buffer will be at least one byte larger than
+ * @a minimum_size to account for a final '\\0'.
  *
  * @since New in 1.6.
  */
@@ -235,10 +235,16 @@ svn_stringbuf_t *
 svn_stringbuf_createv(apr_pool_t *pool, const char *fmt, va_list ap)
   __attribute__((format(printf, 2, 0)));
 
-/** Make sure that the string @a str has at least @a minimum_size bytes of
- * space available in the memory block.
+/** Make sure that the stringbuf @a str has at least @a minimum_size
+ * bytes of space available in the memory block.
+ *
+ * The allocated string buffer will be at least one byte larger than
+ * @a minimum_size to account for a final '\\0'.
  *
- * (@a minimum_size should include space for the terminating NULL character.)
+ * @note: Before Subversion 1.8 this function did not ensure space for
+ * one byte more than @a minimum_size.  If compatibility with pre-1.8
+ * behaviour is required callers must assume space for only
+ * @a minimum_size-1 data bytes plus a final '\\0'.
  */
 void
 svn_stringbuf_ensure(svn_stringbuf_t *str, apr_size_t minimum_size);

Modified: subversion/branches/ev2-export/subversion/libsvn_client/checkout.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/checkout.c?rev=1309471&r1=1309470&r2=1309471&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/checkout.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/checkout.c Wed Apr  4 15:57:38 2012
@@ -49,10 +49,7 @@
 
 static svn_error_t *
 initialize_area(const char *local_abspath,
-                const char *session_url,
-                const char *repos_root,
-                const char *uuid,
-                svn_revnum_t revnum,
+                const svn_client__pathrev_t *pathrev,
                 svn_depth_t depth,
                 svn_client_ctx_t *ctx,
                 apr_pool_t *pool)
@@ -61,8 +58,9 @@ initialize_area(const char *local_abspat
     depth = svn_depth_infinity;
 
   /* Make the unversioned directory into a versioned one.  */
-  SVN_ERR(svn_wc_ensure_adm4(ctx->wc_ctx, local_abspath, session_url,
-                             repos_root, uuid, revnum, depth, pool));
+  SVN_ERR(svn_wc_ensure_adm4(ctx->wc_ctx, local_abspath, pathrev->url,
+                             pathrev->repos_root_url, pathrev->repos_uuid,
+                             pathrev->rev, depth, pool));
   return SVN_NO_ERROR;
 }
 
@@ -81,16 +79,12 @@ svn_client__checkout_internal(svn_revnum
                               apr_pool_t *pool)
 {
   svn_error_t *err = NULL;
-  svn_revnum_t revnum;
   svn_boolean_t sleep_here = FALSE;
   svn_boolean_t *use_sleep = timestamp_sleep ? timestamp_sleep : &sleep_here;
-  const char *session_url;
   svn_node_kind_t kind;
-  const char *uuid, *repos_root;
   apr_pool_t *session_pool = svn_pool_create(pool);
   svn_ra_session_t *ra_session;
-  svn_revnum_t tmp_revnum;
-  const char *tmp_session_url;
+  svn_client__pathrev_t *pathrev;
 
   /* Sanity check.  Without these, the checkout is meaningless. */
   SVN_ERR_ASSERT(local_abspath != NULL);
@@ -104,26 +98,22 @@ svn_client__checkout_internal(svn_revnum
     return svn_error_create(SVN_ERR_CLIENT_BAD_REVISION, NULL, NULL);
 
   /* Get the RA connection. */
-  SVN_ERR(svn_client__ra_session_from_path(&ra_session, &tmp_revnum,
-                                           &tmp_session_url, url, NULL,
-                                           peg_revision, revision, ctx,
-                                           session_pool));
-
-  SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root, pool));
-  SVN_ERR(svn_ra_get_uuid2(ra_session, &uuid, pool));
-  session_url = apr_pstrdup(pool, tmp_session_url);
-  revnum = tmp_revnum;
-  SVN_ERR(svn_ra_check_path(ra_session, "", revnum, &kind, pool));
+  SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &pathrev,
+                                            url, NULL, peg_revision, revision,
+                                            ctx, session_pool));
+
+  pathrev = svn_client__pathrev_dup(pathrev, pool);
+  SVN_ERR(svn_ra_check_path(ra_session, "", pathrev->rev, &kind, pool));
 
   svn_pool_destroy(session_pool);
 
   if (kind == svn_node_none)
     return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
-                             _("URL '%s' doesn't exist"), session_url);
+                             _("URL '%s' doesn't exist"), pathrev->url);
   else if (kind == svn_node_file)
     return svn_error_createf
       (SVN_ERR_UNSUPPORTED_FEATURE , NULL,
-       _("URL '%s' refers to a file, not a directory"), session_url);
+       _("URL '%s' refers to a file, not a directory"), pathrev->url);
 
   SVN_ERR(svn_io_check_path(local_abspath, &kind, pool));
 
@@ -133,8 +123,7 @@ svn_client__checkout_internal(svn_revnum
          entries file should only have an entry for THIS_DIR with a
          URL, revnum, and an 'incomplete' flag.  */
       SVN_ERR(svn_io_make_dir_recursively(local_abspath, pool));
-      err = initialize_area(local_abspath, session_url,
-                            repos_root, uuid, revnum, depth, ctx, pool);
+      err = initialize_area(local_abspath, pathrev, depth, ctx, pool);
     }
   else if (kind == svn_node_dir)
     {
@@ -144,8 +133,7 @@ svn_client__checkout_internal(svn_revnum
       SVN_ERR(svn_wc_check_wc2(&wc_format, ctx->wc_ctx, local_abspath, pool));
       if (! wc_format)
         {
-          err = initialize_area(local_abspath, session_url,
-                                repos_root, uuid, revnum, depth, ctx, pool);
+          err = initialize_area(local_abspath, pathrev, depth, ctx, pool);
         }
       else
         {
@@ -156,7 +144,7 @@ svn_client__checkout_internal(svn_revnum
           /* If PATH's existing URL matches the incoming one, then
              just update.  This allows 'svn co' to restart an
              interrupted checkout.  Otherwise bail out. */
-          if (strcmp(entry_url, session_url) != 0)
+          if (strcmp(entry_url, pathrev->url) != 0)
             return svn_error_createf(
                           SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
                           _("'%s' is already a working copy for a"

Modified: subversion/branches/ev2-export/subversion/libsvn_client/client.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/client.h?rev=1309471&r1=1309470&r2=1309471&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/client.h (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/client.h Wed Apr  4 15:57:38 2012
@@ -36,6 +36,7 @@
 #include "svn_client.h"
 
 #include "private/svn_magic.h"
+#include "private/svn_client_private.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -146,16 +147,15 @@ svn_client__repos_locations(const char *
 /* Trace a line of history of a particular versioned resource back to a
  * specific revision.
  *
- * Set *OP_URL to the URL that the object PEG_URL@PEG_REVNUM had in
+ * Set *OP_LOC_P to the location that the object PEG_LOC had in
  * revision OP_REVNUM.
  *
  * RA_SESSION is an open RA session to the correct repository; it may be
  * temporarily reparented inside this function. */
 svn_error_t *
-svn_client__repos_location(const char **start_url,
+svn_client__repos_location(svn_client__pathrev_t **op_loc_p,
                            svn_ra_session_t *ra_session,
-                           const char *peg_url,
-                           svn_revnum_t peg_revnum,
+                           const svn_client__pathrev_t *peg_loc,
                            svn_revnum_t op_revnum,
                            svn_client_ctx_t *ctx,
                            apr_pool_t *result_pool,
@@ -194,13 +194,9 @@ svn_client__repos_location_segments(apr_
    Ancestry is determined by the 'copy-from' relationship and the normal
    successor relationship.
 
-   Set *ANCESTOR_RELPATH, *ANCESTOR_URL, and *ANCESTOR_REVISION to the
-   path (relative to the root of the repository, with no leading '/'),
-   URL, and revision, respectively, of the youngest common ancestor of
-   the two locations URL1@REV1 and URL2@REV2.  Set *ANCESTOR_RELPATH and
-   *ANCESTOR_URL to NULL and *ANCESTOR_REVISION to SVN_INVALID_REVNUM if
-   they have no common ancestor.  This function assumes that URL1@REV1
-   and URL2@REV2 both refer to the same repository.
+   Set *ANCESTOR_P to the location of the youngest common ancestor of
+   LOC1 and LOC2.  If the locations have no common ancestor (including if
+   they don't have the same repository root URL), set *ANCESTOR_P to NULL.
 
    Use the authentication baton cached in CTX to authenticate against
    the repository.  Use POOL for all allocations.
@@ -208,15 +204,12 @@ svn_client__repos_location_segments(apr_
    See also svn_client__youngest_common_ancestor().
 */
 svn_error_t *
-svn_client__get_youngest_common_ancestor(const char **ancestor_relpath,
-                                         const char **ancestor_url,
-                                         svn_revnum_t *ancestor_revision,
-                                         const char *url1,
-                                         svn_revnum_t rev1,
-                                         const char *url2,
-                                         svn_revnum_t rev2,
+svn_client__get_youngest_common_ancestor(svn_client__pathrev_t **ancestor_p,
+                                         const svn_client__pathrev_t *loc1,
+                                         const svn_client__pathrev_t *loc2,
                                          svn_client_ctx_t *ctx,
-                                         apr_pool_t *pool);
+                                         apr_pool_t *result_pool,
+                                         apr_pool_t *scratch_pool);
 
 /* Given PATH_OR_URL, which contains either a working copy path or an
    absolute URL, a peg revision PEG_REVISION, and a desired revision
@@ -253,6 +246,19 @@ svn_client__ra_session_from_path(svn_ra_
                                  svn_client_ctx_t *ctx,
                                  apr_pool_t *pool);
 
+/* Like svn_client__ra_session_from_path() but returning a path-rev
+ * instead of separate URL and rev outputs.  RESOLVED_LOC_P may be NULL
+ * if not wanted. */
+svn_error_t *
+svn_client__ra_session_from_path2(svn_ra_session_t **ra_session_p,
+                                 svn_client__pathrev_t **resolved_loc_p,
+                                 const char *path_or_url,
+                                 const char *base_dir_abspath,
+                                 const svn_opt_revision_t *peg_revision,
+                                 const svn_opt_revision_t *revision,
+                                 svn_client_ctx_t *ctx,
+                                 apr_pool_t *pool);
+
 /* Ensure that RA_SESSION's session URL matches SESSION_URL,
    reparenting that session if necessary.
    Store the previous session URL in *OLD_SESSION_URL (so that if the

Modified: subversion/branches/ev2-export/subversion/libsvn_client/commit_util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/commit_util.c?rev=1309471&r1=1309470&r2=1309471&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/commit_util.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/commit_util.c Wed Apr  4 15:57:38 2012
@@ -628,21 +628,20 @@ harvest_committables(const char *local_a
       /* We should check if we should really add a delete operation */
       if (check_url_func)
         {
-          svn_revnum_t revision;
+          svn_client__pathrev_t *origin;
           const char *repos_url;
           svn_node_kind_t kind;
 
           /* Determine from what parent we would be the deleted child */
           SVN_ERR(svn_client__wc_node_get_origin(
-                    NULL, NULL, &revision, &repos_url,
-                    svn_dirent_dirname(local_abspath, scratch_pool),
+                    &origin, svn_dirent_dirname(local_abspath, scratch_pool),
                     ctx, scratch_pool, scratch_pool));
 
           repos_url = svn_path_url_add_component2(
-                        repos_url, svn_dirent_basename(local_abspath, NULL),
+                        origin->url, svn_dirent_basename(local_abspath, NULL),
                         scratch_pool);
 
-          SVN_ERR(check_url_func(check_url_baton, &kind, repos_url, revision,
+          SVN_ERR(check_url_func(check_url_baton, &kind, repos_url, origin->rev,
                                  scratch_pool));
 
           if (kind == svn_node_none)

Modified: subversion/branches/ev2-export/subversion/libsvn_client/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/copy.c?rev=1309471&r1=1309470&r2=1309471&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/copy.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/copy.c Wed Apr  4 15:57:38 2012
@@ -93,12 +93,15 @@ calculate_target_mergeinfo(svn_ra_sessio
      bother checking. */
   if (local_abspath)
     {
+      svn_client__pathrev_t *origin;
+
       SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
-      SVN_ERR(svn_client__wc_node_get_origin(NULL, NULL,
-                                             &src_revnum, &src_url,
+      SVN_ERR(svn_client__wc_node_get_origin(&origin,
                                              local_abspath, ctx,
                                              pool, pool));
+      src_revnum = origin->rev;
+      src_url = origin->url;
 
       if (! src_url)
         locally_added = TRUE;
@@ -1039,14 +1042,16 @@ repos_to_repos_copy(const apr_array_head
                                                    path_driver_info_t *);
 
           item = svn_client_commit_item3_create(pool);
-          item->url = svn_path_url_add_component2(top_url, info->dst_path, pool);
+          item->url = svn_path_url_add_component2(top_url, info->dst_path,
+                                                  pool);
           item->state_flags = SVN_CLIENT_COMMIT_ITEM_ADD;
           APR_ARRAY_PUSH(commit_items, svn_client_commit_item3_t *) = item;
 
           if (is_move && (! info->resurrection))
             {
               item = apr_pcalloc(pool, sizeof(*item));
-              item->url = svn_path_url_add_component2(top_url, info->src_path, pool);
+              item->url = svn_path_url_add_component2(top_url, info->src_path,
+                                                      pool);
               item->state_flags = SVN_CLIENT_COMMIT_ITEM_DELETE;
               APR_ARRAY_PUSH(commit_items, svn_client_commit_item3_t *) = item;
             }

Modified: subversion/branches/ev2-export/subversion/libsvn_client/info.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/info.c?rev=1309471&r1=1309470&r2=1309471&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/info.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/info.c Wed Apr  4 15:57:38 2012
@@ -66,19 +66,16 @@ static svn_error_t *
 build_info_from_dirent(svn_client_info2_t **info,
                        const svn_dirent_t *dirent,
                        svn_lock_t *lock,
-                       const char *URL,
-                       svn_revnum_t revision,
-                       const char *repos_UUID,
-                       const char *repos_root,
+                       const svn_client__pathrev_t *pathrev,
                        apr_pool_t *pool)
 {
   svn_client_info2_t *tmpinfo = apr_pcalloc(pool, sizeof(*tmpinfo));
 
-  tmpinfo->URL                  = URL;
-  tmpinfo->rev                  = revision;
+  tmpinfo->URL                  = pathrev->url;
+  tmpinfo->rev                  = pathrev->rev;
   tmpinfo->kind                 = dirent->kind;
-  tmpinfo->repos_UUID           = repos_UUID;
-  tmpinfo->repos_root_URL       = repos_root;
+  tmpinfo->repos_UUID           = pathrev->repos_uuid;
+  tmpinfo->repos_root_URL       = pathrev->repos_root_url;
   tmpinfo->last_changed_rev     = dirent->created_rev;
   tmpinfo->last_changed_date    = dirent->time;
   tmpinfo->last_changed_author  = dirent->last_author;
@@ -111,11 +108,8 @@ build_info_from_dirent(svn_client_info2_
 */
 static svn_error_t *
 push_dir_info(svn_ra_session_t *ra_session,
-              const char *session_URL,
+              const svn_client__pathrev_t *pathrev,
               const char *dir,
-              svn_revnum_t rev,
-              const char *repos_UUID,
-              const char *repos_root,
               svn_client_info_receiver2_t receiver,
               void *receiver_baton,
               svn_depth_t depth,
@@ -128,15 +122,16 @@ push_dir_info(svn_ra_session_t *ra_sessi
   apr_pool_t *subpool = svn_pool_create(pool);
 
   SVN_ERR(svn_ra_get_dir2(ra_session, &tmpdirents, NULL, NULL,
-                          dir, rev, DIRENT_FIELDS, pool));
+                          dir, pathrev->rev, DIRENT_FIELDS, pool));
 
   for (hi = apr_hash_first(pool, tmpdirents); hi; hi = apr_hash_next(hi))
     {
-      const char *path, *URL, *fs_path;
+      const char *path, *fs_path;
       svn_lock_t *lock;
       svn_client_info2_t *info;
       const char *name = svn__apr_hash_index_key(hi);
       svn_dirent_t *the_ent = svn__apr_hash_index_val(hi);
+      svn_client__pathrev_t *child_pathrev;
 
       svn_pool_clear(subpool);
 
@@ -144,14 +139,13 @@ push_dir_info(svn_ra_session_t *ra_sessi
         SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
 
       path = svn_relpath_join(dir, name, subpool);
-      URL = svn_path_url_add_component2(session_URL, name, subpool);
-      fs_path = svn_fspath__canonicalize(
-                  svn_uri_skip_ancestor(repos_root, URL, subpool), subpool);
+      child_pathrev = svn_client__pathrev_join_relpath(pathrev, name, subpool);
+      fs_path = svn_client__pathrev_fspath(child_pathrev, subpool);
 
       lock = apr_hash_get(locks, fs_path, APR_HASH_KEY_STRING);
 
-      SVN_ERR(build_info_from_dirent(&info, the_ent, lock, URL, rev,
-                                     repos_UUID, repos_root, subpool));
+      SVN_ERR(build_info_from_dirent(&info, the_ent, lock, child_pathrev,
+                                     subpool));
 
       if (depth >= svn_depth_immediates
           || (depth == svn_depth_files && the_ent->kind == svn_node_file))
@@ -161,8 +155,7 @@ push_dir_info(svn_ra_session_t *ra_sessi
 
       if (depth == svn_depth_infinity && the_ent->kind == svn_node_dir)
         {
-          SVN_ERR(push_dir_info(ra_session, URL, path,
-                                rev, repos_UUID, repos_root,
+          SVN_ERR(push_dir_info(ra_session, child_pathrev, path,
                                 receiver, receiver_baton,
                                 depth, ctx, locks, subpool));
         }
@@ -338,9 +331,7 @@ svn_client_info3(const char *abspath_or_
                  apr_pool_t *pool)
 {
   svn_ra_session_t *ra_session;
-  svn_revnum_t rev;
-  const char *url;
-  const char *repos_root_URL, *repos_UUID;
+  svn_client__pathrev_t *pathrev;
   svn_lock_t *lock;
   svn_boolean_t related;
   const char *base_name;
@@ -370,18 +361,14 @@ svn_client_info3(const char *abspath_or_
   /* Trace rename history (starting at path_or_url@peg_revision) and
      return RA session to the possibly-renamed URL as it exists in REVISION.
      The ra_session returned will be anchored on this "final" URL. */
-  SVN_ERR(svn_client__ra_session_from_path(&ra_session, &rev,
-                                           &url, abspath_or_url, NULL,
-                                           peg_revision,
-                                           revision, ctx, pool));
+  SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &pathrev,
+                                            abspath_or_url, NULL, peg_revision,
+                                            revision, ctx, pool));
 
-  SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root_URL, pool));
-  SVN_ERR(svn_ra_get_uuid2(ra_session, &repos_UUID, pool));
-
-  svn_uri_split(NULL, &base_name, url, pool);
+  svn_uri_split(NULL, &base_name, pathrev->url, pool);
 
   /* Get the dirent for the URL itself. */
-  err = ra_stat_compatible(ra_session, rev, &the_ent, DIRENT_FIELDS,
+  err = ra_stat_compatible(ra_session, pathrev->rev, &the_ent, DIRENT_FIELDS,
                            ctx, pool);
   if (err && err->apr_err == SVN_ERR_RA_NOT_IMPLEMENTED)
     {
@@ -407,7 +394,7 @@ svn_client_info3(const char *abspath_or_
   if (! the_ent)
     return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
                              _("URL '%s' non-existent in revision %ld"),
-                             url, rev);
+                             pathrev->url, pathrev->rev);
 
   /* Check if the URL exists in HEAD and refers to the same resource.
      In this case, we check the repository for a lock on this URL.
@@ -417,7 +404,8 @@ svn_client_info3(const char *abspath_or_
      ### check in a loop which only terminates if the HEAD revision is the same
      ### before and after this check.  That could, however, lead to a
      ### starvation situation instead.  */
-  SVN_ERR(same_resource_in_head(&related, url, rev, ra_session, ctx, pool));
+  SVN_ERR(same_resource_in_head(&related, pathrev->url, pathrev->rev,
+                                ra_session, ctx, pool));
   if (related)
     {
       err = svn_ra_get_lock(ra_session, &lock, "", pool);
@@ -437,8 +425,7 @@ svn_client_info3(const char *abspath_or_
     lock = NULL;
 
   /* Push the URL's dirent (and lock) at the callback.*/
-  SVN_ERR(build_info_from_dirent(&info, the_ent, lock, url, rev,
-                                 repos_UUID, repos_root_URL, pool));
+  SVN_ERR(build_info_from_dirent(&info, the_ent, lock, pathrev, pool));
   SVN_ERR(receiver(receiver_baton, base_name, info, pool));
 
   /* Possibly recurse, using the original RA session. */
@@ -466,8 +453,7 @@ pre_1_2_recurse:
       else
         locks = apr_hash_make(pool); /* use an empty hash */
 
-      SVN_ERR(push_dir_info(ra_session, url, "", rev,
-                            repos_UUID, repos_root_URL,
+      SVN_ERR(push_dir_info(ra_session, pathrev, "",
                             receiver, receiver_baton,
                             depth, ctx, locks, pool));
     }

Modified: subversion/branches/ev2-export/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/merge.c?rev=1309471&r1=1309470&r2=1309471&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/merge.c Wed Apr  4 15:57:38 2012
@@ -338,59 +338,6 @@ merge_source_dup(const merge_source_t *s
   return s;
 }
 
-/* Like svn_client__repos_location() but using svn_client__pathrev_t for input
- * and output. */
-static svn_error_t *
-repos_location(svn_client__pathrev_t **op_loc_p,
-               svn_ra_session_t *ra_session,
-               const svn_client__pathrev_t *peg_loc,
-               svn_revnum_t op_revnum,
-               svn_client_ctx_t *ctx,
-               apr_pool_t *result_pool,
-               apr_pool_t *scratch_pool)
-{
-  *op_loc_p = apr_palloc(result_pool, sizeof(**op_loc_p));
-  (*op_loc_p)->repos_root_url = peg_loc->repos_root_url;
-  (*op_loc_p)->repos_uuid = peg_loc->repos_uuid;
-  (*op_loc_p)->rev = op_revnum;
-  SVN_ERR(svn_client__repos_location(&(*op_loc_p)->url, ra_session,
-                                     peg_loc->url, peg_loc->rev,
-                                     op_revnum,
-                                     ctx, result_pool, scratch_pool));
-  return SVN_NO_ERROR;
-}
-
-/* Set *ANCESTOR_P to the location of the youngest common ancestor of
- * LOC1 and LOC2.  If the locations have no common ancestor, set
- * *ANCESTOR_P to NULL.
- *
- * Like svn_client__get_youngest_common_ancestor() but using
- * svn_client__pathrev_t for input and output.
- */
-static svn_error_t *
-get_youngest_common_ancestor(svn_client__pathrev_t **ancestor_p,
-                             const svn_client__pathrev_t *loc1,
-                             const svn_client__pathrev_t *loc2,
-                             svn_client_ctx_t *ctx,
-                             apr_pool_t *result_pool,
-                             apr_pool_t *scratch_pool)
-{
-  const char *url;
-  svn_revnum_t rev;
-
-  SVN_ERR(svn_client__get_youngest_common_ancestor(
-            NULL, &url, &rev,
-            loc1->url, loc1->rev, loc2->url, loc2->rev,
-            ctx, result_pool));
-  if (url)
-    *ancestor_p = svn_client__pathrev_create(loc1->repos_root_url,
-                                             loc1->repos_uuid,
-                                             rev, url, result_pool);
-  else
-    *ancestor_p = NULL;
-  return SVN_NO_ERROR;
-}
-
 /* Return SVN_ERR_UNSUPPORTED_FEATURE if URL is not inside the repository
    of LOCAL_ABSPATH.  Use SCRATCH_POOL for temporary allocations. */
 static svn_error_t *
@@ -583,32 +530,24 @@ make_conflict_versions(const svn_wc_conf
                        svn_node_kind_t node_kind,
                        merge_cmd_baton_t *merge_b)
 {
-  const char *left_url;
-  const char *right_url;
+  const char *child = svn_dirent_skip_ancestor(merge_b->target->abspath,
+                                               victim_abspath);
+  const char *left_relpath, *right_relpath;
 
-  /* Construct the source URLs of the victim. */
-  {
-    const char *child = svn_dirent_skip_ancestor(merge_b->target->abspath,
-                                                 victim_abspath);
-    SVN_ERR_ASSERT(child != NULL);
-    left_url = svn_path_url_add_component2(merge_b->merge_source.loc1->url,
-                                           child, merge_b->pool);
-    right_url = svn_path_url_add_component2(merge_b->merge_source.loc2->url,
-                                            child, merge_b->pool);
-  }
+  SVN_ERR_ASSERT(child != NULL);
+  left_relpath = svn_client__pathrev_relpath(merge_b->merge_source.loc1,
+                                             merge_b->pool);
+  right_relpath = svn_client__pathrev_relpath(merge_b->merge_source.loc2,
+                                              merge_b->pool);
 
   *left = svn_wc_conflict_version_create(
             merge_b->merge_source.loc1->repos_root_url,
-            svn_uri_skip_ancestor(
-              merge_b->merge_source.loc1->repos_root_url,
-              left_url, merge_b->pool),
+            svn_relpath_join(left_relpath, child, merge_b->pool),
             merge_b->merge_source.loc1->rev, node_kind, merge_b->pool);
 
   *right = svn_wc_conflict_version_create(
              merge_b->merge_source.loc2->repos_root_url,
-             svn_uri_skip_ancestor(
-               merge_b->merge_source.loc2->repos_root_url,
-               right_url, merge_b->pool),
+             svn_relpath_join(right_relpath, child, merge_b->pool),
              merge_b->merge_source.loc2->rev, node_kind, merge_b->pool);
 
   return SVN_NO_ERROR;
@@ -1071,10 +1010,10 @@ filter_self_referential_mergeinfo(apr_ar
                   /* Check if PATH@BASE_REVISION exists at
                      RANGE->START on the same line of history.
                      (start+1 because RANGE->start is not inclusive.) */
-                  err2 = repos_location(&start_loc, ra_session,
-                                        &target_base,
-                                        range->start + 1,
-                                        ctx, iterpool, iterpool);
+                  err2 = svn_client__repos_location(&start_loc, ra_session,
+                                                    &target_base,
+                                                    range->start + 1,
+                                                    ctx, iterpool, iterpool);
                   if (err2)
                     {
                       if (err2->apr_err == SVN_ERR_CLIENT_UNRELATED_RESOURCES
@@ -1148,8 +1087,8 @@ filter_self_referential_mergeinfo(apr_ar
           svn_mergeinfo_t implicit_mergeinfo;
 
           SVN_ERR(svn_client__get_history_as_mergeinfo(
-            &implicit_mergeinfo, NULL, target_base.url,
-            target_base.rev, target_base.rev, SVN_INVALID_REVNUM,
+            &implicit_mergeinfo, NULL,
+            &target_base, target_base.rev, SVN_INVALID_REVNUM,
             ra_session, ctx, iterpool));
 
           /* Remove PATH's implicit mergeinfo from the incoming mergeinfo. */
@@ -3579,8 +3518,7 @@ get_full_mergeinfo(svn_mergeinfo_t *reco
 
   if (implicit_mergeinfo)
     {
-      svn_revnum_t target_rev;
-      const char *target_url;
+      svn_client__pathrev_t *target;
 
       /* Assert that we have sane input. */
       SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(start) && SVN_IS_VALID_REVNUM(end)
@@ -3588,18 +3526,16 @@ get_full_mergeinfo(svn_mergeinfo_t *reco
 
       /* Retrieve the origin (original_*) of the node, or just the
          url if the node was not copied. */
-      SVN_ERR(svn_client__wc_node_get_origin(NULL, NULL,
-                                             &target_rev, &target_url,
-                                             target_abspath, ctx,
+      SVN_ERR(svn_client__wc_node_get_origin(&target, target_abspath, ctx,
                                              scratch_pool, scratch_pool));
 
-      if (! target_url)
+      if (! target->url)
         {
           /* We've been asked to operate on a locally added target, so its
            * implicit mergeinfo is empty. */
           *implicit_mergeinfo = apr_hash_make(result_pool);
         }
-      else if (target_rev <= end)
+      else if (target->rev <= end)
         {
           /* We're asking about a range outside our natural history
              altogether.  That means our implicit mergeinfo is empty. */
@@ -3614,14 +3550,13 @@ get_full_mergeinfo(svn_mergeinfo_t *reco
              TARGET_ABSPATH might not even exist, and even if it does the
              working copy is *at* TARGET_REV so its implicit history ends
              at TARGET_REV! */
-          if (target_rev < start)
-            start = target_rev;
+          if (target->rev < start)
+            start = target->rev;
 
           /* Fetch the implicit mergeinfo. */
           SVN_ERR(svn_client__get_history_as_mergeinfo(implicit_mergeinfo,
                                                        NULL,
-                                                       target_url, target_rev,
-                                                       start, end,
+                                                       target, start, end,
                                                        ra_session, ctx,
                                                        result_pool));
         }
@@ -4140,11 +4075,11 @@ calculate_remaining_ranges(svn_client__m
       svn_error_t *err;
       svn_client__pathrev_t *start_loc;
 
-      err = repos_location(&start_loc,
-                           ra_session,
-                           source->loc1,
-                           child_base_revision,
-                           ctx, scratch_pool, scratch_pool);
+      err = svn_client__repos_location(&start_loc,
+                                       ra_session,
+                                       source->loc1,
+                                       child_base_revision,
+                                       ctx, scratch_pool, scratch_pool);
       if (err)
         {
           if (err->apr_err == SVN_ERR_FS_NOT_FOUND
@@ -4205,10 +4140,9 @@ find_gaps_in_merge_source_history(svn_re
                                   apr_pool_t *scratch_pool)
 {
   svn_mergeinfo_t implicit_src_mergeinfo;
-  svn_revnum_t young_rev = MAX(source->loc1->rev, source->loc2->rev);
   svn_revnum_t old_rev = MIN(source->loc1->rev, source->loc2->rev);
-  const char *primary_url = (source->loc1->rev < source->loc2->rev)
-                            ? source->loc2->url : source->loc1->url;
+  const svn_client__pathrev_t *primary_src
+    = (source->loc1->rev < source->loc2->rev) ? source->loc2 : source->loc1;
   const char *merge_src_fspath;
   apr_array_header_t *rangelist;
 
@@ -4217,12 +4151,13 @@ find_gaps_in_merge_source_history(svn_re
 
   /* Get SOURCE as mergeinfo. */
   SVN_ERR(svn_client__get_history_as_mergeinfo(&implicit_src_mergeinfo, NULL,
-                                               primary_url, young_rev,
-                                               young_rev, old_rev, ra_session,
+                                               primary_src,
+                                               primary_src->rev, old_rev,
+                                               ra_session,
                                                merge_b->ctx, scratch_pool));
 
   SVN_ERR(svn_ra__get_fspath_relative_to_root(
-            ra_session, &merge_src_fspath, primary_url, scratch_pool));
+            ra_session, &merge_src_fspath, primary_src->url, scratch_pool));
   rangelist = apr_hash_get(implicit_src_mergeinfo,
                            merge_src_fspath,
                            APR_HASH_KEY_STRING);
@@ -6422,10 +6357,10 @@ normalize_merge_sources_internal(apr_arr
     {
       svn_client__pathrev_t *start_loc;
 
-      SVN_ERR(repos_location(&start_loc,
-                             ra_session, source_loc,
-                             youngest_requested,
-                             ctx, scratch_pool, scratch_pool));
+      SVN_ERR(svn_client__repos_location(&start_loc,
+                                         ra_session, source_loc,
+                                         youngest_requested,
+                                         ctx, scratch_pool, scratch_pool));
       source_peg_revnum = youngest_requested;
     }
 
@@ -7841,10 +7776,12 @@ record_mergeinfo_for_dir_merge(svn_merge
               svn_error_t *err;
               svn_mergeinfo_t subtree_history_as_mergeinfo;
               apr_array_header_t *child_merge_src_rangelist;
-              const char *subtree_mergeinfo_url =
-                svn_path_url_add_component2(merge_b->target->loc.repos_root_url,
-                                            child_merge_src_fspath + 1,
-                                            iterpool);
+              svn_client__pathrev_t *subtree_mergeinfo_pathrev
+                = svn_client__pathrev_create_with_relpath(
+                    merge_b->target->loc.repos_root_url,
+                    merge_b->target->loc.repos_uuid,
+                    merged_range->end, child_merge_src_fspath + 1,
+                    iterpool);
 
               /* Confirm that the naive mergeinfo we want to set on
                  CHILD->ABSPATH both exists and is part of
@@ -7854,7 +7791,7 @@ record_mergeinfo_for_dir_merge(svn_merge
                  because we only do this for forward merges. */
               err = svn_client__get_history_as_mergeinfo(
                 &subtree_history_as_mergeinfo, NULL,
-                subtree_mergeinfo_url, merged_range->end,
+                subtree_mergeinfo_pathrev,
                 merged_range->end, merged_range->start,
                 merge_b->ra_session2, merge_b->ctx, iterpool);
 
@@ -8002,7 +7939,7 @@ record_mergeinfo_for_added_subtrees(
           apr_array_header_t *rangelist;
           const char *rel_added_path;
           const char *added_path_mergeinfo_fspath;
-          const char *added_path_mergeinfo_url;
+          svn_client__pathrev_t *added_path_pathrev;
 
           SVN_ERR(svn_wc_read_kind(&added_path_kind, merge_b->ctx->wc_ctx,
                                    added_abspath, FALSE, iterpool));
@@ -8040,14 +7977,14 @@ record_mergeinfo_for_added_subtrees(
              will describe non-existent merge sources. To avoid this we get
              take the intersection of the naive mergeinfo with
              MERGEINFO_PATH/rel_added_path's history. */
-          added_path_mergeinfo_url =
-            svn_path_url_add_component2(merge_b->target->loc.repos_root_url,
-                                        added_path_mergeinfo_fspath + 1,
-                                        iterpool);
+          added_path_pathrev = svn_client__pathrev_create_with_relpath(
+                                 merge_b->target->loc.repos_root_url,
+                                 merge_b->target->loc.repos_uuid,
+                                 MAX(merged_range->start, merged_range->end),
+                                 added_path_mergeinfo_fspath + 1, iterpool);
           SVN_ERR(svn_client__get_history_as_mergeinfo(
             &adds_history_as_mergeinfo, NULL,
-            added_path_mergeinfo_url,
-            MAX(merged_range->start, merged_range->end),
+            added_path_pathrev,
             MAX(merged_range->start, merged_range->end),
             MIN(merged_range->start, merged_range->end),
             merge_b->ra_session2, merge_b->ctx, iterpool));
@@ -9355,17 +9292,15 @@ open_target_wc(merge_target_t **target_p
                apr_pool_t *scratch_pool)
 {
   merge_target_t *target = apr_palloc(result_pool, sizeof(*target));
+  svn_client__pathrev_t *origin;
 
   target->abspath = apr_pstrdup(result_pool, wc_abspath);
 
   SVN_ERR(svn_wc_read_kind(&target->kind, ctx->wc_ctx, wc_abspath, FALSE,
                            scratch_pool));
-
-  SVN_ERR(svn_client__wc_node_get_origin(&target->loc.repos_root_url,
-                                         &target->loc.repos_uuid,
-                                         &target->loc.rev, &target->loc.url,
-                                         wc_abspath, ctx,
+  SVN_ERR(svn_client__wc_node_get_origin(&origin, wc_abspath, ctx,
                                          result_pool, scratch_pool));
+  target->loc = *origin;
 
   SVN_ERR(ensure_wc_is_suitable_merge_target(
             wc_abspath, ctx,
@@ -9388,19 +9323,10 @@ open_source_session(svn_client__pathrev_
                     apr_pool_t *result_pool,
                     apr_pool_t *scratch_pool)
 {
-  svn_client__pathrev_t *location = apr_palloc(result_pool, sizeof(*location));
-  svn_ra_session_t *ra_session;
-
-  SVN_ERR(svn_client__ra_session_from_path(
-            &ra_session, &location->rev, &location->url,
+  SVN_ERR(svn_client__ra_session_from_path2(
+            ra_session_p, location_p,
             path_or_url, NULL, peg_revision, peg_revision,
             ctx, result_pool));
-  SVN_ERR(svn_ra_get_repos_root2(ra_session, &location->repos_root_url,
-                                 result_pool));
-  SVN_ERR(svn_ra_get_uuid2(ra_session, &location->repos_uuid, result_pool));
-
-  *location_p = location;
-  *ra_session_p = ra_session;
   return SVN_NO_ERROR;
 }
 
@@ -9468,8 +9394,8 @@ merge_locked(const char *source1,
 
   /* Unless we're ignoring ancestry, see if the two sources are related.  */
   if (! ignore_ancestry)
-    SVN_ERR(get_youngest_common_ancestor(&yca, source1_loc, source2_loc,
-                                         ctx, scratch_pool, scratch_pool));
+    SVN_ERR(svn_client__get_youngest_common_ancestor(
+              &yca, source1_loc, source2_loc, ctx, scratch_pool, scratch_pool));
 
   /* Check for a youngest common ancestor.  If we have one, we'll be
      doing merge tracking.
@@ -9917,12 +9843,6 @@ find_unsynced_ranges(const svn_client__p
      are not yet merged to it. */
   if (potentially_unmerged_ranges)
     {
-      const char *source_repos_rel_path
-        = svn_uri_skip_ancestor(source_loc->repos_root_url, source_loc->url,
-                                scratch_pool);
-      const char *target_repos_rel_path
-        = svn_uri_skip_ancestor(target_loc->repos_root_url, target_loc->url,
-                                scratch_pool);
       svn_revnum_t oldest_rev =
         (APR_ARRAY_IDX(potentially_unmerged_ranges,
                        0,
@@ -9937,9 +9857,10 @@ find_unsynced_ranges(const svn_client__p
 
       log_baton.merged_catalog = merged_catalog;
       log_baton.unmerged_catalog = true_unmerged_catalog;
-      log_baton.source_repos_rel_path = source_repos_rel_path;
-      log_baton.target_fspath = apr_psprintf(scratch_pool, "/%s",
-                                             target_repos_rel_path);
+      log_baton.source_repos_rel_path
+        = svn_client__pathrev_relpath(source_loc, scratch_pool);
+      log_baton.target_fspath
+        = svn_client__pathrev_fspath(target_loc, scratch_pool);
       log_baton.result_pool = result_pool;
 
       APR_ARRAY_PUSH(log_targets, const char *) = "";
@@ -9994,9 +9915,9 @@ find_youngest_merged_rev(svn_revnum_t *y
  * that are not present in the source branch.
  *
  * SOURCE_MERGEINFO is the explicit or inherited mergeinfo of the source
- * branch SOURCE_URL@SOURCE_REV.  Extend SOURCE_MERGEINFO, modifying it in
+ * branch SOURCE_PATHREV.  Extend SOURCE_MERGEINFO, modifying it in
  * place, to include the natural history (implicit mergeinfo) of
- * SOURCE_URL@SOURCE_REV.  ### But make these additions in SCRATCH_POOL.
+ * SOURCE_PATHREV.  ### But make these additions in SCRATCH_POOL.
  *
  * ### [JAF] This function is named '..._subroutine' simply because I
  *     factored it out based on code similarity, without knowing what it's
@@ -10006,8 +9927,7 @@ static svn_error_t *
 find_unmerged_mergeinfo_subroutine(svn_mergeinfo_t *filtered_mergeinfo_p,
                                    svn_mergeinfo_t target_history_as_mergeinfo,
                                    svn_mergeinfo_t source_mergeinfo,
-                                   const char *source_url,
-                                   svn_revnum_t source_rev,
+                                   const svn_client__pathrev_t *source_pathrev,
                                    svn_ra_session_t *source_ra_session,
                                    svn_client_ctx_t *ctx,
                                    apr_pool_t *result_pool,
@@ -10019,7 +9939,7 @@ find_unmerged_mergeinfo_subroutine(svn_m
      path's explicit or inherited mergeinfo. */
   SVN_ERR(svn_client__get_history_as_mergeinfo(
             &source_history_as_mergeinfo, NULL /* has_rev_zero_history */,
-            source_url, source_rev, source_rev, SVN_INVALID_REVNUM,
+            source_pathrev, source_pathrev->rev, SVN_INVALID_REVNUM,
             source_ra_session, ctx, scratch_pool));
   SVN_ERR(svn_mergeinfo_merge2(source_mergeinfo,
                                source_history_as_mergeinfo,
@@ -10126,6 +10046,7 @@ find_unmerged_mergeinfo(svn_mergeinfo_ca
         = svn_relpath_skip_ancestor(target_repos_rel_path, target_path);
       const char *source_path;
       const char *source_url;
+      svn_client__pathrev_t *source_pathrev;
       svn_mergeinfo_t source_mergeinfo, filtered_mergeinfo;
 
       svn_pool_clear(iterpool);
@@ -10198,12 +10119,15 @@ find_unmerged_mergeinfo(svn_mergeinfo_ca
             source_mergeinfo = apr_hash_make(iterpool);
         }
 
+      SVN_ERR(svn_client__pathrev_create_with_session(
+                &source_pathrev, source_ra_session, source_rev, source_url,
+                iterpool));
       /* Use scratch_pool rather than iterpool because filtered_mergeinfo
          is going into new_catalog below and needs to last to the end of
          this function. */
       SVN_ERR(find_unmerged_mergeinfo_subroutine(
                 &filtered_mergeinfo, target_history_as_mergeinfo,
-                source_mergeinfo, source_url, source_rev,
+                source_mergeinfo, source_pathrev,
                 source_ra_session, ctx, scratch_pool, iterpool));
       apr_hash_set(new_catalog,
                    apr_pstrdup(scratch_pool, source_path),
@@ -10226,7 +10150,7 @@ find_unmerged_mergeinfo(svn_mergeinfo_ca
       const char *source_url;
       svn_mergeinfo_t source_mergeinfo = svn__apr_hash_index_val(hi);
       svn_mergeinfo_t filtered_mergeinfo;
-      const char *target_url;
+      svn_client__pathrev_t *target_pathrev;
       svn_mergeinfo_t target_history_as_mergeinfo;
       svn_error_t *err;
 
@@ -10234,12 +10158,12 @@ find_unmerged_mergeinfo(svn_mergeinfo_ca
 
       source_url = svn_path_url_add_component2(source_session_url,
                                                path_rel_to_session, iterpool);
-      target_url = svn_path_url_add_component2(target->loc.url,
-                                               path_rel_to_session, iterpool);
+      target_pathrev = svn_client__pathrev_join_relpath(
+                         &target->loc, path_rel_to_session, iterpool);
       err = svn_client__get_history_as_mergeinfo(&target_history_as_mergeinfo,
                                                  NULL /* has_rev_zero_history */,
-                                                 target_url,
-                                                 target->loc.rev, target->loc.rev,
+                                                 target_pathrev,
+                                                 target->loc.rev,
                                                  SVN_INVALID_REVNUM,
                                                  target_ra_session,
                                                  ctx, iterpool);
@@ -10260,6 +10184,8 @@ find_unmerged_mergeinfo(svn_mergeinfo_ca
         }
       else
         {
+          svn_client__pathrev_t *pathrev;
+
           SVN_ERR(find_youngest_merged_rev(youngest_merged_rev,
                                            target_history_as_mergeinfo,
                                            source_mergeinfo,
@@ -10269,9 +10195,12 @@ find_unmerged_mergeinfo(svn_mergeinfo_ca
              is going into new_catalog below and needs to last to the end of
              this function. */
           /* ### Why looking at SOURCE_url at TARGET_rev? */
+          SVN_ERR(svn_client__pathrev_create_with_session(
+                    &pathrev, source_ra_session, target->loc.rev, source_url,
+                    iterpool));
           SVN_ERR(find_unmerged_mergeinfo_subroutine(
                     &filtered_mergeinfo, target_history_as_mergeinfo,
-                    source_mergeinfo, source_url, target->loc.rev,
+                    source_mergeinfo, pathrev,
                     source_ra_session, ctx, scratch_pool, iterpool));
           if (apr_hash_count(filtered_mergeinfo))
             apr_hash_set(new_catalog,
@@ -10371,7 +10300,7 @@ calculate_left_hand_side(svn_client__pat
        hi = apr_hash_next(hi))
     {
       const char *absolute_path = svn__apr_hash_index_key(hi);
-      const char *url;
+      svn_client__pathrev_t *target_child;
       const char *path_rel_to_root;
       svn_mergeinfo_t target_history_as_mergeinfo;
 
@@ -10384,12 +10313,13 @@ calculate_left_hand_side(svn_client__pat
                                                 NULL, FALSE,
                                                 NULL, scratch_pool,
                                                 iterpool));
-      url = svn_path_url_add_component2(target->loc.repos_root_url,
-                                        path_rel_to_root, iterpool);
+      target_child = svn_client__pathrev_create_with_relpath(
+                       target->loc.repos_root_url, target->loc.repos_uuid,
+                       target->loc.rev, path_rel_to_root, iterpool);
       SVN_ERR(svn_client__get_history_as_mergeinfo(&target_history_as_mergeinfo,
                                                    NULL /* has_rev_zero_hist */,
-                                                   url,
-                                                   target->loc.rev, target->loc.rev,
+                                                   target_child,
+                                                   target->loc.rev,
                                                    SVN_INVALID_REVNUM,
                                                    target_ra_session,
                                                    ctx, scratch_pool));
@@ -10402,8 +10332,8 @@ calculate_left_hand_side(svn_client__pat
   /* Check that SOURCE_LOC and TARGET->loc are
      actually related, we can't reintegrate if they are not.  Also
      get an initial value for the YCA revision number. */
-  SVN_ERR(get_youngest_common_ancestor(&yc_ancestor, source_loc, &target->loc,
-                                       ctx, iterpool, iterpool));
+  SVN_ERR(svn_client__get_youngest_common_ancestor(
+            &yc_ancestor, source_loc, &target->loc, ctx, iterpool, iterpool));
   if (! yc_ancestor)
     return svn_error_createf(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
                              _("'%s@%ld' must be ancestrally related to "
@@ -10427,8 +10357,7 @@ calculate_left_hand_side(svn_client__pat
                                svn_mergeinfo_inherited,
                                TRUE, iterpool));
 
-  source_repos_rel_path = svn_uri_skip_ancestor(source_loc->repos_root_url,
-                                                source_loc->url, scratch_pool);
+  source_repos_rel_path = svn_client__pathrev_relpath(source_loc, scratch_pool);
   if (mergeinfo_catalog)
     SVN_ERR(svn_mergeinfo__add_prefix_to_catalog(&mergeinfo_catalog,
                                                  mergeinfo_catalog,
@@ -10473,9 +10402,9 @@ calculate_left_hand_side(svn_client__pat
       /* We've previously merged some or all of the target, up to
          youngest_merged_rev, to the source.  Set
          *LEFT_P to cover the youngest part of this range. */
-      SVN_ERR(repos_location(left_p, target_ra_session,
-                             &target->loc, youngest_merged_rev,
-                             ctx, result_pool, iterpool));
+      SVN_ERR(svn_client__repos_location(left_p, target_ra_session,
+                                         &target->loc, youngest_merged_rev,
+                                         ctx, result_pool, iterpool));
     }
 
   svn_pool_destroy(iterpool);
@@ -10569,8 +10498,9 @@ find_reintegrate_merge(merge_source_t **
   if (strcmp(source.loc1->url, target->loc.url))
     SVN_ERR(svn_ra_reparent(target_ra_session, source.loc1->url, scratch_pool));
 
-  SVN_ERR(get_youngest_common_ancestor(&yc_ancestor, source.loc2, source.loc1,
-                                       ctx, scratch_pool, scratch_pool));
+  SVN_ERR(svn_client__get_youngest_common_ancestor(
+            &yc_ancestor, source.loc2, source.loc1,
+            ctx, scratch_pool, scratch_pool));
 
   if (! yc_ancestor)
     return svn_error_createf(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
@@ -11136,8 +11066,9 @@ find_symmetric_merge(svn_client__pathrev
 {
   svn_client__pathrev_t *base_on_source, *base_on_target, *mid;
 
-  SVN_ERR(get_youngest_common_ancestor(yca_p, s_t->source, &s_t->target->loc,
-                                       ctx, result_pool, result_pool));
+  SVN_ERR(svn_client__get_youngest_common_ancestor(
+            yca_p, s_t->source, &s_t->target->loc,
+            ctx, result_pool, result_pool));
 
   /* Find the latest revision of A synced to B and the latest
    * revision of B synced to A.

Modified: subversion/branches/ev2-export/subversion/libsvn_client/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/mergeinfo.c?rev=1309471&r1=1309470&r2=1309471&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/mergeinfo.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/mergeinfo.c Wed Apr  4 15:57:38 2012
@@ -748,26 +748,26 @@ svn_client__get_wc_or_repos_mergeinfo_ca
 
 svn_error_t *
 svn_client__get_history_as_mergeinfo(svn_mergeinfo_t *mergeinfo_p,
-                                     svn_boolean_t *has_rev_zero_history,
-                                     const char *url,
-                                     svn_revnum_t peg_revnum,
-                                     svn_revnum_t range_youngest,
-                                     svn_revnum_t range_oldest,
-                                     svn_ra_session_t *ra_session,
-                                     svn_client_ctx_t *ctx,
-                                     apr_pool_t *pool)
+                                      svn_boolean_t *has_rev_zero_history,
+                                      const svn_client__pathrev_t *pathrev,
+                                      svn_revnum_t range_youngest,
+                                      svn_revnum_t range_oldest,
+                                      svn_ra_session_t *ra_session,
+                                      svn_client_ctx_t *ctx,
+                                      apr_pool_t *pool)
 {
   apr_array_header_t *segments;
 
   /* Fetch the location segments for our URL@PEG_REVNUM. */
   if (! SVN_IS_VALID_REVNUM(range_youngest))
-    range_youngest = peg_revnum;
+    range_youngest = pathrev->rev;
   if (! SVN_IS_VALID_REVNUM(range_oldest))
     range_oldest = 0;
 
-  SVN_ERR(svn_client__repos_location_segments(&segments, ra_session, url,
-                                              peg_revnum, range_youngest,
-                                              range_oldest, ctx, pool));
+  SVN_ERR(svn_client__repos_location_segments(&segments, ra_session,
+                                              pathrev->url, pathrev->rev,
+                                              range_youngest, range_oldest,
+                                              ctx, pool));
 
   if (has_rev_zero_history)
     {
@@ -1064,16 +1064,15 @@ get_mergeinfo(svn_mergeinfo_catalog_t *m
      contact the repository for the requested PEG_REVISION. */
   if (!use_url)
     {
-      const char *origin_url = NULL;
+      svn_client__pathrev_t *origin;
       SVN_ERR(svn_dirent_get_absolute(&local_abspath, path_or_url,
                                       scratch_pool));
 
-      SVN_ERR(svn_client__wc_node_get_origin(NULL, NULL, &rev, &origin_url,
-                                             local_abspath, ctx,
+      SVN_ERR(svn_client__wc_node_get_origin(&origin, local_abspath, ctx,
                                              scratch_pool, scratch_pool));
-
-      if (!origin_url
-          || strcmp(origin_url, url) != 0
+      rev = origin->rev;
+      if (!origin->url
+          || strcmp(origin->url, url) != 0
           || peg_rev != rev)
       {
         use_url = TRUE; /* Don't rely on local mergeinfo */
@@ -1715,32 +1714,30 @@ svn_client_mergeinfo_log(svn_boolean_t f
   if (!finding_merged)
     {
       svn_ra_session_t *target_session;
-      svn_revnum_t rev;
-      const char *url;
+      svn_client__pathrev_t *pathrev;
 
-      SVN_ERR(svn_client__ra_session_from_path(
-                &target_session, &rev, &url,
+      SVN_ERR(svn_client__ra_session_from_path2(
+                &target_session, &pathrev,
                 target_path_or_url, NULL,
                 target_peg_revision, target_peg_revision,
                 ctx, sesspool));
       SVN_ERR(svn_client__get_history_as_mergeinfo(
                 &target_history, NULL,
-                url, rev, SVN_INVALID_REVNUM, SVN_INVALID_REVNUM,
+                pathrev, SVN_INVALID_REVNUM, SVN_INVALID_REVNUM,
                 target_session, ctx, scratch_pool));
     }
   {
     svn_ra_session_t *source_session;
-    svn_revnum_t rev;
-    const char *url;
+    svn_client__pathrev_t *pathrev;
 
-    SVN_ERR(svn_client__ra_session_from_path(
-              &source_session, &rev, &url,
+    SVN_ERR(svn_client__ra_session_from_path2(
+              &source_session, &pathrev,
               source_path_or_url, NULL,
               source_peg_revision, source_peg_revision,
               ctx, sesspool));
     SVN_ERR(svn_client__get_history_as_mergeinfo(
               &source_history, NULL,
-              url, rev, SVN_INVALID_REVNUM, SVN_INVALID_REVNUM,
+              pathrev, SVN_INVALID_REVNUM, SVN_INVALID_REVNUM,
               source_session, ctx, scratch_pool));
   }
   /* Close the source and target sessions. */

Modified: subversion/branches/ev2-export/subversion/libsvn_client/mergeinfo.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/mergeinfo.h?rev=1309471&r1=1309470&r2=1309471&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/mergeinfo.h (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/mergeinfo.h Wed Apr  4 15:57:38 2012
@@ -26,6 +26,7 @@
 
 #include "svn_wc.h"
 #include "svn_client.h"
+#include "private/svn_client_private.h"
 
 
 /*** Data Structures ***/
@@ -289,7 +290,7 @@ svn_client__get_wc_or_repos_mergeinfo_ca
   apr_pool_t *scratch_pool);
 
 /* Set *MERGEINFO_P to a mergeinfo constructed solely from the
-   natural history of URL at PEG_REVNUM.
+   natural history of PATHREV.
 
    If RANGE_YOUNGEST and RANGE_OLDEST are valid, use them to bound the
    revision ranges of returned mergeinfo.  They are governed by the same
@@ -305,8 +306,7 @@ svn_client__get_wc_or_repos_mergeinfo_ca
 svn_error_t *
 svn_client__get_history_as_mergeinfo(svn_mergeinfo_t *mergeinfo_p,
                                      svn_boolean_t *has_rev_zero_history,
-                                     const char *url,
-                                     svn_revnum_t peg_revnum,
+                                     const svn_client__pathrev_t *pathrev,
                                      svn_revnum_t range_youngest,
                                      svn_revnum_t range_oldest,
                                      svn_ra_session_t *ra_session,

Modified: subversion/branches/ev2-export/subversion/libsvn_client/ra.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/ra.c?rev=1309471&r1=1309470&r2=1309471&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/ra.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/ra.c Wed Apr  4 15:57:38 2012
@@ -391,9 +391,7 @@ svn_client_open_ra_session(svn_ra_sessio
    for a URL or 'working' for a WC path.  If REVISION->kind is
    'unspecified', the operative revision is the peg revision.
 
-   Store the actual revision number of the object in *REV_P, and the
-   final resulting URL in *URL_P. REV_P and/or URL_P may be NULL if not
-   wanted.
+   Store the actual location of the object in *RESOLVED_LOC_P.
 
    RA_SESSION should be an open RA session pointing at the URL of
    PATH_OR_URL, or NULL, in which case this function will open its own
@@ -404,8 +402,7 @@ svn_client_open_ra_session(svn_ra_sessio
 
    Use POOL for all allocations. */
 static svn_error_t *
-resolve_rev_and_url(svn_revnum_t *rev_p,
-                    const char **url_p,
+resolve_rev_and_url(svn_client__pathrev_t **resolved_loc_p,
                     svn_ra_session_t *ra_session,
                     const char *path_or_url,
                     const svn_opt_revision_t *peg_revision,
@@ -430,29 +427,25 @@ resolve_rev_and_url(svn_revnum_t *rev_p,
                                       ra_session, path_or_url, &peg_rev,
                                       &start_rev, NULL, ctx, pool));
 
-  if (rev_p)
-    *rev_p = rev;
-  if (url_p)
-    *url_p = url;
-
+  SVN_ERR(svn_client__pathrev_create_with_session(resolved_loc_p,
+                                                  ra_session, rev, url, pool));
   return SVN_NO_ERROR;
 }
 
 svn_error_t *
-svn_client__ra_session_from_path(svn_ra_session_t **ra_session_p,
-                                 svn_revnum_t *rev_p,
-                                 const char **url_p,
-                                 const char *path_or_url,
-                                 const char *base_dir_abspath,
-                                 const svn_opt_revision_t *peg_revision,
-                                 const svn_opt_revision_t *revision,
-                                 svn_client_ctx_t *ctx,
-                                 apr_pool_t *pool)
+svn_client__ra_session_from_path2(svn_ra_session_t **ra_session_p,
+                                  svn_client__pathrev_t **resolved_loc_p,
+                                  const char *path_or_url,
+                                  const char *base_dir_abspath,
+                                  const svn_opt_revision_t *peg_revision,
+                                  const svn_opt_revision_t *revision,
+                                  svn_client_ctx_t *ctx,
+                                  apr_pool_t *pool)
 {
   svn_ra_session_t *ra_session;
   const char *initial_url;
   const char *corrected_url;
-  const char *resolved_url;
+  svn_client__pathrev_t *resolved_loc;
 
   SVN_ERR(svn_client_url_from_path2(&initial_url, path_or_url, ctx, pool,
                                     pool));
@@ -471,16 +464,41 @@ svn_client__ra_session_from_path(svn_ra_
   if (corrected_url && svn_path_is_url(path_or_url))
     path_or_url = corrected_url;
 
-  SVN_ERR(resolve_rev_and_url(rev_p, &resolved_url, ra_session,
+  SVN_ERR(resolve_rev_and_url(&resolved_loc, ra_session,
                               path_or_url, peg_revision, revision,
                               ctx, pool));
 
   /* Make the session point to the real URL. */
-  SVN_ERR(svn_ra_reparent(ra_session, resolved_url, pool));
+  SVN_ERR(svn_ra_reparent(ra_session, resolved_loc->url, pool));
 
   *ra_session_p = ra_session;
+  if (resolved_loc_p)
+    *resolved_loc_p = resolved_loc;
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client__ra_session_from_path(svn_ra_session_t **ra_session_p,
+                                 svn_revnum_t *rev_p,
+                                 const char **url_p,
+                                 const char *path_or_url,
+                                 const char *base_dir_abspath,
+                                 const svn_opt_revision_t *peg_revision,
+                                 const svn_opt_revision_t *revision,
+                                 svn_client_ctx_t *ctx,
+                                 apr_pool_t *pool)
+{
+  svn_client__pathrev_t *resolved_loc;
+
+  SVN_ERR(svn_client__ra_session_from_path2(ra_session_p, &resolved_loc,
+                                            path_or_url, base_dir_abspath,
+                                            peg_revision, revision,
+                                            ctx, pool));
+  if (rev_p)
+    *rev_p = resolved_loc->rev;
   if (url_p)
-    *url_p = resolved_url;
+    *url_p = resolved_loc->url;
 
   return SVN_NO_ERROR;
 }
@@ -649,24 +667,28 @@ repos_locations(const char **start_url,
 }
 
 svn_error_t *
-svn_client__repos_location(const char **op_url,
+svn_client__repos_location(svn_client__pathrev_t **op_loc_p,
                            svn_ra_session_t *ra_session,
-                           const char *peg_url,
-                           svn_revnum_t peg_revnum,
+                           const svn_client__pathrev_t *peg_loc,
                            svn_revnum_t op_revnum,
                            svn_client_ctx_t *ctx,
                            apr_pool_t *result_pool,
                            apr_pool_t *scratch_pool)
 {
   const char *old_session_url;
+  const char *op_url;
 
   SVN_ERR(svn_client__ensure_ra_session_url(&old_session_url, ra_session,
-                                            peg_url, scratch_pool));
-  SVN_ERR(repos_locations(op_url, NULL,
-                          ra_session, peg_url, peg_revnum,
+                                            peg_loc->url, scratch_pool));
+  SVN_ERR(repos_locations(&op_url, NULL, ra_session,
+                          peg_loc->url, peg_loc->rev,
                           op_revnum, SVN_INVALID_REVNUM,
                           result_pool, scratch_pool));
   SVN_ERR(svn_ra_reparent(ra_session, old_session_url, scratch_pool));
+
+  *op_loc_p = svn_client__pathrev_create(peg_loc->repos_root_url,
+                                         peg_loc->repos_uuid,
+                                         op_revnum, op_url, result_pool);
   return SVN_NO_ERROR;
 }
 
@@ -808,19 +830,15 @@ svn_client__repos_locations(const char *
 
 
 svn_error_t *
-svn_client__get_youngest_common_ancestor(const char **ancestor_relpath,
-                                         const char **ancestor_url,
-                                         svn_revnum_t *ancestor_revision,
-                                         const char *url1,
-                                         svn_revnum_t rev1,
-                                         const char *url2,
-                                         svn_revnum_t rev2,
+svn_client__get_youngest_common_ancestor(svn_client__pathrev_t **ancestor_p,
+                                         const svn_client__pathrev_t *loc1,
+                                         const svn_client__pathrev_t *loc2,
                                          svn_client_ctx_t *ctx,
-                                         apr_pool_t *pool)
+                                         apr_pool_t *result_pool,
+                                         apr_pool_t *scratch_pool)
 {
-  apr_pool_t *sesspool = svn_pool_create(pool);
+  apr_pool_t *sesspool = svn_pool_create(scratch_pool);
   svn_ra_session_t *session;
-  const char *repos_root_url;
   apr_hash_t *history1, *history2;
   apr_hash_index_t *hi;
   svn_revnum_t yc_revision = SVN_INVALID_REVNUM;
@@ -828,31 +846,36 @@ svn_client__get_youngest_common_ancestor
   svn_boolean_t has_rev_zero_history1;
   svn_boolean_t has_rev_zero_history2;
 
+  if (strcmp(loc1->repos_root_url, loc2->repos_root_url) != 0)
+    {
+      *ancestor_p = NULL;
+      return SVN_NO_ERROR;
+    }
+
   /* Open an RA session for the two locations. */
-  SVN_ERR(svn_client_open_ra_session(&session, url1, ctx, sesspool));
-  SVN_ERR(svn_ra_get_repos_root2(session, &repos_root_url, pool));
+  SVN_ERR(svn_client_open_ra_session(&session, loc1->url, ctx, sesspool));
 
   /* We're going to cheat and use history-as-mergeinfo because it
      saves us a bunch of annoying custom data comparisons and such. */
   SVN_ERR(svn_client__get_history_as_mergeinfo(&history1,
                                                &has_rev_zero_history1,
-                                               url1, rev1,
+                                               loc1,
                                                SVN_INVALID_REVNUM,
                                                SVN_INVALID_REVNUM,
-                                               session, ctx, pool));
+                                               session, ctx, scratch_pool));
   SVN_ERR(svn_client__get_history_as_mergeinfo(&history2,
                                                &has_rev_zero_history2,
-                                               url2, rev2,
+                                               loc2,
                                                SVN_INVALID_REVNUM,
                                                SVN_INVALID_REVNUM,
-                                               session, ctx, pool));
+                                               session, ctx, scratch_pool));
   /* Close the source and target sessions. */
   svn_pool_destroy(sesspool);
 
   /* Loop through the first location's history, check for overlapping
      paths and ranges in the second location's history, and
      remembering the youngest matching location. */
-  for (hi = apr_hash_first(pool, history1); hi; hi = apr_hash_next(hi))
+  for (hi = apr_hash_first(scratch_pool, history1); hi; hi = apr_hash_next(hi))
     {
       const char *path = svn__apr_hash_index_key(hi);
       apr_ssize_t path_len = svn__apr_hash_index_klen(hi);
@@ -865,7 +888,7 @@ svn_client__get_youngest_common_ancestor
           /* We have a path match.  Now, did our two histories share
              any revisions at that path? */
           SVN_ERR(svn_rangelist_intersect(&common, ranges1, ranges2,
-                                          TRUE, pool));
+                                          TRUE, scratch_pool));
           if (common->nelts)
             {
               svn_merge_range_t *yc_range =
@@ -888,14 +911,16 @@ svn_client__get_youngest_common_ancestor
       yc_revision = 0;
     }
 
-  if (ancestor_relpath)
-    *ancestor_relpath = yc_relpath;
-  if (ancestor_url)
-    *ancestor_url
-      = yc_relpath ? svn_path_url_add_component2(repos_root_url, yc_relpath,
-                                                 pool) : NULL;
-  if (ancestor_revision)
-    *ancestor_revision = yc_revision;
+  if (yc_relpath)
+    {
+      *ancestor_p = svn_client__pathrev_create_with_relpath(
+                      loc1->repos_root_url, loc1->repos_uuid,
+                      yc_revision, yc_relpath, result_pool);
+    }
+  else
+    {
+      *ancestor_p = NULL;
+    }
   return SVN_NO_ERROR;
 }
 
@@ -912,22 +937,30 @@ svn_client__youngest_common_ancestor(con
 {
   apr_pool_t *sesspool = svn_pool_create(scratch_pool);
   svn_ra_session_t *session;
-  const char *url1, *url2;
-  svn_revnum_t rev1, rev2;
+  svn_client__pathrev_t *loc1, *loc2, *ancestor;
 
   /* Resolve the two locations */
-  SVN_ERR(svn_client__ra_session_from_path(&session, &rev1, &url1,
-                                           path_or_url1, NULL,
-                                           revision1, revision1,
-                                           ctx, sesspool));
-  SVN_ERR(resolve_rev_and_url(&rev2, &url2, session,
+  SVN_ERR(svn_client__ra_session_from_path2(&session, &loc1,
+                                            path_or_url1, NULL,
+                                            revision1, revision1,
+                                            ctx, sesspool));
+  SVN_ERR(resolve_rev_and_url(&loc2, session,
                               path_or_url2, revision2, revision2,
                               ctx, scratch_pool));
 
   SVN_ERR(svn_client__get_youngest_common_ancestor(
-            NULL, ancestor_url, ancestor_rev,
-            url1, rev1, url2, rev2, ctx, result_pool));
+            &ancestor, loc1, loc2, ctx, result_pool, scratch_pool));
 
+  if (ancestor)
+    {
+      *ancestor_url = ancestor->url;
+      *ancestor_rev = ancestor->rev;
+    }
+  else
+    {
+      *ancestor_url = NULL;
+      *ancestor_rev = SVN_INVALID_REVNUM;
+    }
   svn_pool_destroy(sesspool);
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/ev2-export/subversion/libsvn_client/repos_diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/repos_diff.c?rev=1309471&r1=1309470&r2=1309471&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/repos_diff.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/repos_diff.c Wed Apr  4 15:57:38 2012
@@ -418,17 +418,6 @@ remove_non_prop_changes(apr_hash_t *pris
     }
 }
 
-/* Get the props attached to a directory in the repository at BASE_REVISION. */
-static svn_error_t *
-get_dirprops_from_ra(struct dir_baton *b, svn_revnum_t base_revision)
-{
-  return svn_ra_get_dir2(b->edit_baton->ra_session,
-                         NULL, NULL, &(b->pristine_props),
-                         b->path,
-                         base_revision,
-                         0,
-                         b->pool);
-}
 
 /* Get the empty file associated with the edit baton. This is cached so
  * that it can be reused, all empty files are the same.
@@ -472,7 +461,8 @@ open_root(void *edit_baton,
   struct edit_baton *eb = edit_baton;
   struct dir_baton *b = make_dir_baton("", NULL, eb, FALSE, pool);
 
-  SVN_ERR(get_dirprops_from_ra(b, base_revision));
+  SVN_ERR(svn_ra_get_dir2(eb->ra_session, NULL, NULL, &b->pristine_props,
+                          b->path, base_revision, 0, pool));
 
   *root_baton = b;
   return SVN_NO_ERROR;
@@ -766,7 +756,8 @@ open_directory(const char *path,
       return SVN_NO_ERROR;
     }
 
-  SVN_ERR(get_dirprops_from_ra(b, base_revision));
+  SVN_ERR(svn_ra_get_dir2(eb->ra_session, NULL, NULL, &b->pristine_props,
+                          b->path, base_revision, 0, pool));
 
   SVN_ERR(eb->diff_callbacks->dir_opened(
                 &b->tree_conflicted, &b->skip,

Modified: subversion/branches/ev2-export/subversion/libsvn_client/switch.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/switch.c?rev=1309471&r1=1309470&r2=1309471&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/switch.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/switch.c Wed Apr  4 15:57:38 2012
@@ -197,20 +197,23 @@ switch_internal(svn_revnum_t *result_rev
      ### okay? */
   if (! ignore_ancestry)
     {
-      const char *target_url, *yc_url;
-      svn_revnum_t target_rev, yc_rev;
+      const char *target_url;
+      svn_revnum_t target_rev;
+      svn_client__pathrev_t *switch_loc, *target_loc, *yca;
 
+      SVN_ERR(svn_client__pathrev_create_with_session(
+                &switch_loc, ra_session, revnum, switch_rev_url, pool));
       SVN_ERR(svn_wc__node_get_url(&target_url, ctx->wc_ctx, local_abspath,
                                    pool, pool));
       SVN_ERR(svn_wc__node_get_base_rev(&target_rev, ctx->wc_ctx,
                                         local_abspath, pool));
+      SVN_ERR(svn_client__pathrev_create_with_session(
+                &target_loc, ra_session, target_rev, target_url, pool));
       /* ### It would be nice if this function could reuse the existing
              ra session instead of opening two for its own use. */
-      SVN_ERR(svn_client__get_youngest_common_ancestor(NULL, &yc_url, &yc_rev,
-                                                       switch_rev_url, revnum,
-                                                       target_url, target_rev,
-                                                       ctx, pool));
-      if (! (yc_url && SVN_IS_VALID_REVNUM(yc_rev)))
+      SVN_ERR(svn_client__get_youngest_common_ancestor(
+                &yca, switch_loc, target_loc, ctx, pool, pool));
+      if (! yca)
         return svn_error_createf(SVN_ERR_CLIENT_UNRELATED_RESOURCES, NULL,
                                  _("'%s' shares no common ancestry with '%s'"),
                                  switch_url, local_abspath);

Modified: subversion/branches/ev2-export/subversion/libsvn_client/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/util.c?rev=1309471&r1=1309470&r2=1309471&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/util.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/util.c Wed Apr  4 15:57:38 2012
@@ -50,6 +50,9 @@ svn_client__pathrev_create(const char *r
 {
   svn_client__pathrev_t *loc = apr_palloc(result_pool, sizeof(*loc));
 
+  SVN_ERR_ASSERT_NO_RETURN(svn_path_is_url(repos_root_url));
+  SVN_ERR_ASSERT_NO_RETURN(svn_path_is_url(url));
+
   loc->repos_root_url = apr_pstrdup(result_pool, repos_root_url);
   loc->repos_uuid = apr_pstrdup(result_pool, repos_uuid);
   loc->rev = rev;
@@ -58,13 +61,79 @@ svn_client__pathrev_create(const char *r
 }
 
 svn_client__pathrev_t *
-svn_client__pathrev_dup(const svn_client__pathrev_t *loc,
+svn_client__pathrev_create_with_relpath(const char *repos_root_url,
+                                        const char *repos_uuid,
+                                        svn_revnum_t rev,
+                                        const char *relpath,
+                                        apr_pool_t *result_pool)
+{
+  SVN_ERR_ASSERT_NO_RETURN(svn_relpath_is_canonical(relpath));
+
+  return svn_client__pathrev_create(
+           repos_root_url, repos_uuid, rev,
+           svn_path_url_add_component2(repos_root_url, relpath, result_pool),
+           result_pool);
+}
+
+svn_error_t *
+svn_client__pathrev_create_with_session(svn_client__pathrev_t **pathrev_p,
+                                        svn_ra_session_t *ra_session,
+                                        svn_revnum_t rev,
+                                        const char *url,
+                                        apr_pool_t *result_pool)
+{
+  svn_client__pathrev_t *pathrev = apr_palloc(result_pool, sizeof(*pathrev));
+
+  SVN_ERR_ASSERT(svn_path_is_url(url));
+
+  SVN_ERR(svn_ra_get_repos_root2(ra_session, &pathrev->repos_root_url,
+                                 result_pool));
+  SVN_ERR(svn_ra_get_uuid2(ra_session, &pathrev->repos_uuid, result_pool));
+  pathrev->rev = rev;
+  pathrev->url = apr_pstrdup(result_pool, url);
+  *pathrev_p = pathrev;
+  return SVN_NO_ERROR;
+}
+
+svn_client__pathrev_t *
+svn_client__pathrev_dup(const svn_client__pathrev_t *pathrev,
                         apr_pool_t *result_pool)
 {
-  return svn_client__pathrev_create(loc->repos_root_url, loc->repos_uuid,
-                                    loc->rev, loc->url, result_pool);
+  return svn_client__pathrev_create(
+           pathrev->repos_root_url, pathrev->repos_uuid,
+           pathrev->rev, pathrev->url, result_pool);
+}
+
+svn_client__pathrev_t *
+svn_client__pathrev_join_relpath(const svn_client__pathrev_t *pathrev,
+                                 const char *relpath,
+                                 apr_pool_t *result_pool)
+{
+  return svn_client__pathrev_create(
+           pathrev->repos_root_url, pathrev->repos_uuid, pathrev->rev,
+           svn_path_url_add_component2(pathrev->url, relpath, result_pool),
+           result_pool);
+}
+
+const char *
+svn_client__pathrev_relpath(const svn_client__pathrev_t *pathrev,
+                            apr_pool_t *result_pool)
+{
+  return svn_uri_skip_ancestor(pathrev->repos_root_url, pathrev->url,
+                               result_pool);
 }
 
+const char *
+svn_client__pathrev_fspath(const svn_client__pathrev_t *pathrev,
+                           apr_pool_t *result_pool)
+{
+  return svn_fspath__canonicalize(svn_uri_skip_ancestor(
+                                    pathrev->repos_root_url, pathrev->url,
+                                    result_pool),
+                                  result_pool);
+}
+
+
 svn_client_commit_item3_t *
 svn_client_commit_item3_create(apr_pool_t *pool)
 {
@@ -163,26 +232,28 @@ svn_client__path_relative_to_root(const 
 }
 
 svn_error_t *
-svn_client__wc_node_get_origin(const char **repos_root_url_p,
-                               const char **repos_uuid_p,
-                               svn_revnum_t *rev_p,
-                               const char **url_p,
+svn_client__wc_node_get_origin(svn_client__pathrev_t **origin_p,
                                const char *wc_abspath,
                                svn_client_ctx_t *ctx,
                                apr_pool_t *result_pool,
                                apr_pool_t *scratch_pool)
 {
-  const char *repos_root_url, *relpath;
+  const char *relpath;
+
+  *origin_p = apr_palloc(result_pool, sizeof(**origin_p));
 
-  SVN_ERR(svn_wc__node_get_origin(NULL /* is_copy */, rev_p, &relpath,
-                                  &repos_root_url, repos_uuid_p,
+  SVN_ERR(svn_wc__node_get_origin(NULL /* is_copy */,
+                                  &(*origin_p)->rev,
+                                  &relpath,
+                                  &(*origin_p)->repos_root_url,
+                                  &(*origin_p)->repos_uuid,
                                   NULL, ctx->wc_ctx, wc_abspath,
                                   FALSE /* scan_deleted */,
                                   result_pool, scratch_pool));
-  if (repos_root_url && relpath)
+  if ((*origin_p)->repos_root_url && relpath)
     {
-      *url_p = svn_path_url_add_component2(repos_root_url, relpath,
-                                           result_pool);
+      (*origin_p)->url = svn_path_url_add_component2(
+                           (*origin_p)->repos_root_url, relpath, result_pool);
     }
   else
     {
@@ -192,17 +263,16 @@ svn_client__wc_node_get_origin(const cha
        * If it's locally added or deleted, find the repository root
        * URL and UUID anyway, and leave the node URL and revision as NULL
        * and INVALID.  If it's unversioned, this will throw an error. */
-      *url_p = NULL;
-      SVN_ERR(svn_client_get_repos_root(&repos_root_url, repos_uuid_p,
-                                        wc_abspath,
-                                        ctx, result_pool, scratch_pool));
+      SVN_ERR(svn_wc__node_get_repos_info(&(*origin_p)->repos_root_url,
+                                          &(*origin_p)->repos_uuid,
+                                          ctx->wc_ctx, wc_abspath,
+                                          result_pool, scratch_pool));
+      (*origin_p)->rev = SVN_INVALID_REVNUM;
+      (*origin_p)->url = NULL;
     }
 
-  if (repos_root_url_p)
-    *repos_root_url_p = repos_root_url;
-
-  SVN_ERR_ASSERT(!repos_root_url_p || *repos_root_url_p);
-  SVN_ERR_ASSERT(!repos_uuid_p || *repos_uuid_p);
+  SVN_ERR_ASSERT((*origin_p)->repos_root_url);
+  SVN_ERR_ASSERT((*origin_p)->repos_uuid);
   return SVN_NO_ERROR;
 }