Modified: 
subversion/branches/revprop-packing/subversion/libsvn_client/commit_util.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_client/commit_util.c?rev=1231318&r1=1231317&r2=1231318&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_client/commit_util.c 
(original)
+++ subversion/branches/revprop-packing/subversion/libsvn_client/commit_util.c 
Fri Jan 13 21:40:26 2012
@@ -410,6 +410,12 @@ bail_on_tree_conflicted_ancestor(svn_wc_
    when harvesting committables; that is, don't add a path to
    COMMITTABLES unless it's a member of one of those changelists.
 
+   IS_EXPLICIT_TARGET should always be passed as TRUE, except when
+   harvest_committables() calls itself in recursion. This provides a way to
+   tell whether LOCAL_ABSPATH was an original target or whether it was reached
+   by recursing deeper into a dir target. (This is used to skip all file
+   externals that aren't explicit commit targets.)
+
    If CANCEL_FUNC is non-null, call it with CANCEL_BATON to see
    if the user has cancelled the operation.
 
@@ -428,6 +434,7 @@ harvest_committables(svn_wc_context_t *w
                      apr_hash_t *changelists,
                      svn_boolean_t skip_files,
                      svn_boolean_t skip_dirs,
+                     svn_boolean_t is_explicit_target,
                      svn_client__check_url_kind_t check_url_func,
                      void *check_url_baton,
                      svn_cancel_func_t cancel_func,
@@ -543,10 +550,24 @@ harvest_committables(svn_wc_context_t *w
          svn_dirent_local_style(local_abspath, scratch_pool));
     }
 
-  /* ### in need of comment */
-  if (copy_mode
-      && is_update_root
-      && db_kind == svn_node_file)
+  /* Handle file externals.
+   * (IS_UPDATE_ROOT is more generally defined, but at the moment this
+   * condition matches only file externals.)
+   *
+   * Don't copy files that svn:externals brought into the WC. So in copy_mode,
+   * even explicit targets are skipped.
+   *
+   * Exclude file externals from recursion. Hande file externals only when
+   * passed as explicit target. Note that svn_client_commit6() passes all
+   * committable externals in as explicit targets iff they count.
+   *
+   * Also note that dir externals will never be reached recursively by this
+   * function, since svn_wc__node_get_children_of_working_node() (used below
+   * to recurse) does not return switched subdirs. */
+  if (is_update_root
+      && db_kind == svn_node_file
+      && (copy_mode
+          || ! is_explicit_target))
     {
       return SVN_NO_ERROR;
     }
@@ -606,7 +627,7 @@ harvest_committables(svn_wc_context_t *w
 
           /* Determine from what parent we would be the deleted child */
           SVN_ERR(svn_wc__node_get_origin(NULL, &revision, &repos_relpath,
-                                          NULL, NULL, wc_ctx,
+                                          NULL, NULL, NULL, wc_ctx,
                                           svn_dirent_dirname(local_abspath,
                                                              scratch_pool),
                                           FALSE, scratch_pool, scratch_pool));
@@ -663,7 +684,7 @@ harvest_committables(svn_wc_context_t *w
 
           SVN_ERR(svn_wc__node_get_origin(NULL, &cf_rev,
                                       &cf_relpath, NULL,
-                                      NULL,
+                                      NULL, NULL,
                                       wc_ctx, local_abspath, FALSE,
                                       scratch_pool, scratch_pool));
 
@@ -841,6 +862,7 @@ harvest_committables(svn_wc_context_t *w
                                        changelists,
                                        (depth < svn_depth_files),
                                        (depth < svn_depth_immediates),
+                                       FALSE, /* IS_EXPLICIT_TARGET */
                                        check_url_func, check_url_baton,
                                        cancel_func, cancel_baton,
                                        notify_func, notify_baton,
@@ -1010,13 +1032,13 @@ svn_client__harvest_committables(svn_cli
    * Since we don't know what's included in the commit until we've
    * harvested all the targets, we can't reliably check this as we
    * go.  So in `danglers', we record named targets whose parents
-   * are unversioned, then after harvesting the total commit group, we
-   * check to make sure those parents are included.
+   * do not yet exist in the repository. Then after harvesting the total
+   * commit group, we check to make sure those parents are included.
    *
-   * Each key of danglers is an unversioned parent.  The (const char *)
-   * value is one of that parent's children which is named as part of
-   * the commit; the child is included only to make a better error
-   * message.
+   * Each key of danglers is a parent which does not exist in the
+   * repository.  The (const char *) value is one of that parent's
+   * children which is named as part of the commit; the child is
+   * included only to make a better error message.
    *
    * (The reason we don't bother to check unnamed -- i.e, implicit --
    * targets is that they can only join the commit if their parents
@@ -1100,6 +1122,22 @@ svn_client__harvest_committables(svn_cli
 
           if (is_added)
             {
+              svn_boolean_t is_copy;
+              const char *copy_root_abspath;
+
+              /* Copies are always committed recursively as long as the
+               * copy root is in the commit target list.
+               * So for nodes copied along with a parent, the copy root path
+               * is the dangling parent. See issue #4059. */
+              SVN_ERR(svn_wc__node_get_origin(&is_copy,
+                                              NULL, NULL, NULL, NULL,
+                                              &copy_root_abspath,
+                                              ctx->wc_ctx,
+                                              target_abspath,
+                                              FALSE, iterpool, iterpool));
+              if (is_copy && strcmp(copy_root_abspath, target_abspath) != 0)
+                parent_abspath = copy_root_abspath;
+
               /* Copy the parent and target into pool; iterpool
                  lasts only for this loop iteration, and we check
                  danglers after the loop is over. */
@@ -1125,6 +1163,7 @@ svn_client__harvest_committables(svn_cli
                                    FALSE /* COPY_MODE_ROOT */,
                                    depth, just_locked, changelist_hash,
                                    FALSE, FALSE,
+                                   TRUE /* IS_EXPLICIT_TARGET */,
                                    check_url_func, check_url_baton,
                                    ctx->cancel_func, ctx->cancel_baton,
                                    ctx->notify_func2, ctx->notify_baton2,
@@ -1147,31 +1186,31 @@ svn_client__harvest_committables(svn_cli
 
       svn_pool_clear(iterpool);
 
-       if (! look_up_committable(*committables, dangling_parent, iterpool))
-         {
-           const char *dangling_child = svn__apr_hash_index_val(hi);
-
-           if (ctx->notify_func2 != NULL)
-             {
-               svn_wc_notify_t *notify;
-
-               notify = svn_wc_create_notify(dangling_child,
-                                             svn_wc_notify_failed_no_parent,
-                                             scratch_pool);
-
-               ctx->notify_func2(ctx->notify_baton2, notify, iterpool);
-             }
-
-           return svn_error_createf(
-                            SVN_ERR_ILLEGAL_TARGET, NULL,
-                            _("'%s' is not under version control "
-                              "and is not part of the commit, "
-                              "yet its child '%s' is part of the commit"),
-                            /* Probably one or both of these is an entry, but
-                               safest to local_stylize just in case. */
-                            svn_dirent_local_style(dangling_parent, iterpool),
-                            svn_dirent_local_style(dangling_child, iterpool));
-         }
+      if (! look_up_committable(*committables, dangling_parent, iterpool))
+        {
+          const char *dangling_child = svn__apr_hash_index_val(hi);
+
+          if (ctx->notify_func2 != NULL)
+            {
+              svn_wc_notify_t *notify;
+
+              notify = svn_wc_create_notify(dangling_child,
+                                            svn_wc_notify_failed_no_parent,
+                                            scratch_pool);
+
+              ctx->notify_func2(ctx->notify_baton2, notify, iterpool);
+            }
+
+          return svn_error_createf(
+                           SVN_ERR_ILLEGAL_TARGET, NULL,
+                           _("'%s' is not known to exist in the repository "
+                             "and is not part of the commit, "
+                             "yet its child '%s' is part of the commit"),
+                           /* Probably one or both of these is an entry, but
+                              safest to local_stylize just in case. */
+                           svn_dirent_local_style(dangling_parent, iterpool),
+                           svn_dirent_local_style(dangling_child, iterpool));
+        }
     }
 
   svn_pool_destroy(iterpool);
@@ -1218,6 +1257,7 @@ harvest_copy_committables(void *baton, v
                                FALSE,  /* JUST_LOCKED */
                                NULL,
                                FALSE, FALSE, /* skip files, dirs */
+                               TRUE, /* IS_EXPLICIT_TARGET (don't care) */
                                btn->check_url_func,
                                btn->check_url_baton,
                                btn->ctx->cancel_func,
@@ -1341,14 +1381,9 @@ svn_client__condense_commit_items(const 
     {
       svn_client_commit_item3_t *this_item
         = APR_ARRAY_IDX(ci, i, svn_client_commit_item3_t *);
-      size_t url_len = strlen(this_item->url);
-      size_t base_url_len = strlen(*base_url);
 
-      if (url_len > base_url_len)
-        this_item->session_relpath = svn_uri__is_child(*base_url,
-                                                       this_item->url, pool);
-      else
-        this_item->session_relpath = "";
+      this_item->session_relpath = svn_uri_skip_ancestor(*base_url,
+                                                         this_item->url, pool);
     }
 #ifdef SVN_CLIENT_COMMIT_DEBUG
   /* ### TEMPORARY CODE ### */

Modified: subversion/branches/revprop-packing/subversion/libsvn_client/copy.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_client/copy.c?rev=1231318&r1=1231317&r2=1231318&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_client/copy.c 
(original)
+++ subversion/branches/revprop-packing/subversion/libsvn_client/copy.c Fri Jan 
13 21:40:26 2012
@@ -98,7 +98,7 @@ calculate_target_mergeinfo(svn_ra_sessio
 
       SVN_ERR(svn_wc__node_get_origin(NULL, &src_revnum,
                                       &repos_relpath, &repos_root_url,
-                                      NULL,
+                                      NULL, NULL,
                                       ctx->wc_ctx, local_abspath, FALSE,
                                       pool, pool));
 
@@ -113,20 +113,11 @@ calculate_target_mergeinfo(svn_ra_sessio
 
   if (! locally_added)
     {
-      /* Fetch any existing (explicit) mergeinfo.  We'll temporarily
-         reparent to the target URL here, just to keep the code simple.
-         We could, as an alternative, first see if the target URL was a
-         child of the session URL and use the relative "remainder",
-         falling back to this reparenting as necessary.  */
-      const char *old_session_url = NULL;
-      SVN_ERR(svn_client__ensure_ra_session_url(&old_session_url,
-                                                ra_session, src_url, pool));
-      SVN_ERR(svn_client__get_repos_mergeinfo(ra_session, &src_mergeinfo,
-                                              "", src_revnum,
-                                              svn_mergeinfo_inherited, TRUE,
-                                              FALSE, pool));
-      if (old_session_url)
-        SVN_ERR(svn_ra_reparent(ra_session, old_session_url, pool));
+      /* Fetch any existing (explicit) mergeinfo. */
+      SVN_ERR(svn_client__get_repos_mergeinfo(&src_mergeinfo, ra_session,
+                                              src_url, src_revnum,
+                                              svn_mergeinfo_inherited,
+                                              TRUE, pool));
     }
 
   *target_mergeinfo = src_mergeinfo;
@@ -150,7 +141,7 @@ extend_wc_mergeinfo(const char *target_a
 
   /* Combine the provided mergeinfo with any mergeinfo from the WC. */
   if (wc_mergeinfo && mergeinfo)
-    SVN_ERR(svn_mergeinfo_merge(wc_mergeinfo, mergeinfo, pool));
+    SVN_ERR(svn_mergeinfo_merge2(wc_mergeinfo, mergeinfo, pool, pool));
   else if (! wc_mergeinfo)
     wc_mergeinfo = mergeinfo;
 
@@ -240,47 +231,41 @@ get_copy_pair_ancestors(const apr_array_
 }
 
 
-struct do_wc_to_wc_copies_with_write_lock_baton {
-  const apr_array_header_t *copy_pairs;
-  svn_client_ctx_t *ctx;
-  const char *dst_parent;
-};
-
 /* The guts of do_wc_to_wc_copies */
 static svn_error_t *
-do_wc_to_wc_copies_with_write_lock(void *baton,
-                                   apr_pool_t *result_pool,
+do_wc_to_wc_copies_with_write_lock(const apr_array_header_t *copy_pairs,
+                                   const char *dst_parent,
+                                   svn_client_ctx_t *ctx,
                                    apr_pool_t *scratch_pool)
 {
-  struct do_wc_to_wc_copies_with_write_lock_baton *b = baton;
   int i;
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   svn_error_t *err = SVN_NO_ERROR;
 
-  for (i = 0; i < b->copy_pairs->nelts; i++)
+  for (i = 0; i < copy_pairs->nelts; i++)
     {
       const char *dst_abspath;
-      svn_client__copy_pair_t *pair = APR_ARRAY_IDX(b->copy_pairs, i,
+      svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
                                                     svn_client__copy_pair_t *);
       svn_pool_clear(iterpool);
 
       /* Check for cancellation */
-      if (b->ctx->cancel_func)
-        SVN_ERR(b->ctx->cancel_func(b->ctx->cancel_baton));
+      if (ctx->cancel_func)
+        SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
 
       /* Perform the copy */
       dst_abspath = svn_dirent_join(pair->dst_parent_abspath, pair->base_name,
                                     iterpool);
-      err = svn_wc_copy3(b->ctx->wc_ctx, pair->src_abspath_or_url, dst_abspath,
+      err = svn_wc_copy3(ctx->wc_ctx, pair->src_abspath_or_url, dst_abspath,
                          FALSE /* metadata_only */,
-                         b->ctx->cancel_func, b->ctx->cancel_baton,
-                         b->ctx->notify_func2, b->ctx->notify_baton2, 
iterpool);
+                         ctx->cancel_func, ctx->cancel_baton,
+                         ctx->notify_func2, ctx->notify_baton2, iterpool);
       if (err)
         break;
     }
   svn_pool_destroy(iterpool);
 
-  svn_io_sleep_for_timestamps(b->dst_parent, scratch_pool);
+  svn_io_sleep_for_timestamps(dst_parent, scratch_pool);
   SVN_ERR(err);
   return SVN_NO_ERROR;
 }
@@ -293,7 +278,6 @@ do_wc_to_wc_copies(const apr_array_heade
                    apr_pool_t *pool)
 {
   const char *dst_parent, *dst_parent_abspath;
-  struct do_wc_to_wc_copies_with_write_lock_baton baton;
 
   SVN_ERR(get_copy_pair_ancestors(copy_pairs, NULL, &dst_parent, NULL, pool));
   if (copy_pairs->nelts == 1)
@@ -301,40 +285,31 @@ do_wc_to_wc_copies(const apr_array_heade
 
   SVN_ERR(svn_dirent_get_absolute(&dst_parent_abspath, dst_parent, pool));
 
-  baton.copy_pairs = copy_pairs;
-  baton.ctx = ctx;
-  baton.dst_parent = dst_parent;
-  SVN_ERR(svn_wc__call_with_write_lock(do_wc_to_wc_copies_with_write_lock,
-                                       &baton, ctx->wc_ctx, dst_parent_abspath,
-                                       FALSE, pool, pool));
+  SVN_WC__CALL_WITH_WRITE_LOCK(
+    do_wc_to_wc_copies_with_write_lock(copy_pairs, dst_parent, ctx, pool),
+    ctx->wc_ctx, dst_parent_abspath, FALSE, pool);
 
   return SVN_NO_ERROR;
 }
 
-struct do_wc_to_wc_moves_with_locks_baton {
-  svn_client_ctx_t *ctx;
-  svn_client__copy_pair_t *pair;
-  const char *dst_parent_abspath;
-  svn_boolean_t lock_src;
-  svn_boolean_t lock_dst;
-};
-
 /* The locked bit of do_wc_to_wc_moves. */
 static svn_error_t *
-do_wc_to_wc_moves_with_locks2(void *baton,
-                              apr_pool_t *result_pool,
+do_wc_to_wc_moves_with_locks2(svn_client__copy_pair_t *pair,
+                              const char *dst_parent_abspath,
+                              svn_boolean_t lock_src,
+                              svn_boolean_t lock_dst,
+                              svn_client_ctx_t *ctx,
                               apr_pool_t *scratch_pool)
 {
-  struct do_wc_to_wc_moves_with_locks_baton *b = baton;
   const char *dst_abspath;
 
-  dst_abspath = svn_dirent_join(b->dst_parent_abspath, b->pair->base_name,
+  dst_abspath = svn_dirent_join(dst_parent_abspath, pair->base_name,
                                 scratch_pool);
 
-  SVN_ERR(svn_wc_move(b->ctx->wc_ctx, b->pair->src_abspath_or_url,
+  SVN_ERR(svn_wc_move(ctx->wc_ctx, pair->src_abspath_or_url,
                      dst_abspath, FALSE /* metadata_only */,
-                     b->ctx->cancel_func, b->ctx->cancel_baton,
-                     b->ctx->notify_func2, b->ctx->notify_baton2,
+                     ctx->cancel_func, ctx->cancel_baton,
+                     ctx->notify_func2, ctx->notify_baton2,
                      scratch_pool));
 
   return SVN_NO_ERROR;
@@ -342,18 +317,21 @@ do_wc_to_wc_moves_with_locks2(void *bato
 
 /* Wrapper to add an optional second lock */
 static svn_error_t *
-do_wc_to_wc_moves_with_locks1(void *baton,
-                              apr_pool_t *result_pool,
+do_wc_to_wc_moves_with_locks1(svn_client__copy_pair_t *pair,
+                              const char *dst_parent_abspath,
+                              svn_boolean_t lock_src,
+                              svn_boolean_t lock_dst,
+                              svn_client_ctx_t *ctx,
                               apr_pool_t *scratch_pool)
 {
-  struct do_wc_to_wc_moves_with_locks_baton *b = baton;
-
-  if (b->lock_dst)
-    SVN_ERR(svn_wc__call_with_write_lock(do_wc_to_wc_moves_with_locks2, b,
-                                         b->ctx->wc_ctx, b->dst_parent_abspath,
-                                         FALSE, result_pool, scratch_pool));
+  if (lock_dst)
+    SVN_WC__CALL_WITH_WRITE_LOCK(
+      do_wc_to_wc_moves_with_locks2(pair, dst_parent_abspath, lock_src,
+                                    lock_dst, ctx, scratch_pool),
+      ctx->wc_ctx, dst_parent_abspath, FALSE, scratch_pool);
   else
-    SVN_ERR(do_wc_to_wc_moves_with_locks2(b, result_pool, scratch_pool));
+    SVN_ERR(do_wc_to_wc_moves_with_locks2(pair, dst_parent_abspath, lock_src,
+                                          lock_dst, ctx, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -373,7 +351,7 @@ do_wc_to_wc_moves(const apr_array_header
   for (i = 0; i < copy_pairs->nelts; i++)
     {
       const char *src_parent_abspath;
-      struct do_wc_to_wc_moves_with_locks_baton baton;
+      svn_boolean_t lock_src, lock_dst;
 
       svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
                                                     svn_client__copy_pair_t *);
@@ -397,32 +375,31 @@ do_wc_to_wc_moves(const apr_array_header
           || svn_dirent_is_child(src_parent_abspath, pair->dst_parent_abspath,
                                  iterpool))
         {
-          baton.lock_src = TRUE;
-          baton.lock_dst = FALSE;
+          lock_src = TRUE;
+          lock_dst = FALSE;
         }
       else if (svn_dirent_is_child(pair->dst_parent_abspath, 
src_parent_abspath,
                                    iterpool))
         {
-          baton.lock_src = FALSE;
-          baton.lock_dst = TRUE;
+          lock_src = FALSE;
+          lock_dst = TRUE;
         }
       else
         {
-          baton.lock_src = TRUE;
-          baton.lock_dst = TRUE;
+          lock_src = TRUE;
+          lock_dst = TRUE;
         }
 
       /* Perform the copy and then the delete. */
-      baton.ctx = ctx;
-      baton.pair = pair;
-      baton.dst_parent_abspath = pair->dst_parent_abspath;
-      if (baton.lock_src)
-        SVN_ERR(svn_wc__call_with_write_lock(do_wc_to_wc_moves_with_locks1,
-                                             &baton,
-                                             ctx->wc_ctx, src_parent_abspath,
-                                             FALSE, iterpool, iterpool));
+      if (lock_src)
+        SVN_WC__CALL_WITH_WRITE_LOCK(
+          do_wc_to_wc_moves_with_locks1(pair, pair->dst_parent_abspath,
+                                        lock_src, lock_dst, ctx, iterpool),
+          ctx->wc_ctx, src_parent_abspath,
+          FALSE, iterpool);
       else
-        SVN_ERR(do_wc_to_wc_moves_with_locks1(&baton, iterpool, iterpool));
+        SVN_ERR(do_wc_to_wc_moves_with_locks1(pair, pair->dst_parent_abspath,
+                                              lock_src, lock_dst, ctx, 
iterpool));
 
     }
   svn_pool_destroy(iterpool);
@@ -761,7 +738,7 @@ repos_to_repos_copy(const apr_array_head
   apr_hash_t *action_hash = apr_hash_make(pool);
   apr_array_header_t *path_infos;
   const char *top_url, *top_url_all, *top_url_dst;
-  const char *message, *repos_root, *ignored_url;
+  const char *message, *repos_root;
   svn_revnum_t youngest = SVN_INVALID_REVNUM;
   svn_ra_session_t *ra_session = NULL;
   const svn_delta_editor_t *editor;
@@ -795,8 +772,6 @@ repos_to_repos_copy(const apr_array_head
       svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
                                                     svn_client__copy_pair_t *);
       apr_hash_t *mergeinfo;
-      svn_opt_revision_t *src_rev, *ignored_rev, dead_end_rev;
-      dead_end_rev.kind = svn_opt_revision_unspecified;
 
       /* Are the source and destination URLs at or under REPOS_ROOT? */
       if (! (svn_uri__is_ancestor(repos_root, pair->src_abspath_or_url)
@@ -806,31 +781,20 @@ repos_to_repos_copy(const apr_array_head
            _("Source and destination URLs appear not to point to the "
              "same repository."));
 
-      /* Resolve revision keywords and such into real revision number,
-         passing NULL for the path (to ensure error if trying to get a
-         revision based on the working copy). */
-      SVN_ERR(svn_client__get_revision_number(&pair->src_revnum, &youngest,
-                                              ctx->wc_ctx, NULL,
-                                              ra_session,
-                                              &pair->src_op_revision, pool));
-
-      /* Run the history function to get the source's URL in the
+      /* Run the history function to get the source's URL and revnum in the
          operational revision. */
-      SVN_ERR(svn_client__ensure_ra_session_url(&ignored_url, ra_session,
-                                                pair->src_abspath_or_url,
-                                                pool));
-      SVN_ERR(svn_client__repos_locations(&pair->src_abspath_or_url, &src_rev,
-                                          &ignored_url, &ignored_rev,
+      SVN_ERR(svn_ra_reparent(ra_session, pair->src_abspath_or_url, pool));
+      SVN_ERR(svn_client__repos_locations(&pair->src_abspath_or_url,
+                                          &pair->src_revnum,
+                                          NULL, NULL,
                                           ra_session,
                                           pair->src_abspath_or_url,
                                           &pair->src_peg_revision,
-                                          &pair->src_op_revision,
-                                          &dead_end_rev, ctx, pool));
+                                          &pair->src_op_revision, NULL,
+                                          ctx, pool));
 
       /* Go ahead and grab mergeinfo from the source, too. */
-      SVN_ERR(svn_client__ensure_ra_session_url(&ignored_url, ra_session,
-                                                pair->src_abspath_or_url,
-                                                pool));
+      SVN_ERR(svn_ra_reparent(ra_session, pair->src_abspath_or_url, pool));
       SVN_ERR(calculate_target_mergeinfo(ra_session, &mergeinfo, NULL,
                                          pair->src_abspath_or_url,
                                          pair->src_revnum, ctx, pool));
@@ -895,16 +859,13 @@ repos_to_repos_copy(const apr_array_head
     }
 
   /* Point the RA session to our current TOP_URL. */
-  SVN_ERR(svn_client__ensure_ra_session_url(&ignored_url, ra_session,
-                                            top_url, pool));
+  SVN_ERR(svn_ra_reparent(ra_session, top_url, pool));
 
   /* If we're allowed to create nonexistent parent directories of our
      destinations, then make a list in NEW_DIRS of the parent
      directories of the destination that don't yet exist.  */
   if (make_parents)
     {
-      const char *dir;
-
       new_dirs = apr_array_make(pool, 0, sizeof(const char *));
 
       /* If this is a move, TOP_URL is at least the common ancestor of
@@ -927,17 +888,17 @@ repos_to_repos_copy(const apr_array_head
 
                 svn copy --parents URL/src URL/dst
 
-             where src exists and dst does not.  The svn_uri_dirname()
-             call above will produce a string equivalent to TOP_URL,
-             which means svn_uri_is_child() will return NULL.  In this
-             case, do not try to add dst to the NEW_DIRS list since it
+             where src exists and dst does not.  If the dirname of the
+             destination path is equal to TOP_URL,
+             do not try to add dst to the NEW_DIRS list since it
              will be added to the commit items array later in this
              function. */
-          dir = svn_uri__is_child(
-                  top_url,
-                  svn_uri_dirname(first_pair->dst_abspath_or_url, pool),
-                  pool);
-          if (dir)
+          const char *dir = svn_uri_skip_ancestor(
+                              top_url,
+                              svn_uri_dirname(first_pair->dst_abspath_or_url,
+                                              pool),
+                              pool);
+          if (dir && *dir)
             SVN_ERR(find_absent_parents1(ra_session, dir, new_dirs, pool));
         }
       /* If, however, this is *not* a move, TOP_URL only points to the
@@ -956,8 +917,9 @@ repos_to_repos_copy(const apr_array_head
           for (i = 0; i < new_urls->nelts; i++)
             {
               const char *new_url = APR_ARRAY_IDX(new_urls, i, const char *);
-              dir = svn_uri__is_child(top_url, new_url, pool);
-              APR_ARRAY_PUSH(new_dirs, const char *) = dir ? dir : "";
+              const char *dir = svn_uri_skip_ancestor(top_url, new_url, pool);
+
+              APR_ARRAY_PUSH(new_dirs, const char *) = dir;
             }
         }
     }
@@ -973,10 +935,12 @@ repos_to_repos_copy(const apr_array_head
                                                     svn_client__copy_pair_t *);
       path_driver_info_t *info = APR_ARRAY_IDX(path_infos, i,
                                                path_driver_info_t *);
+      const char *relpath = svn_uri_skip_ancestor(pair->dst_abspath_or_url,
+                                                  pair->src_abspath_or_url,
+                                                  pool);
 
       if ((strcmp(pair->dst_abspath_or_url, repos_root) != 0)
-          && (svn_uri__is_child(pair->dst_abspath_or_url,
-                                pair->src_abspath_or_url, pool) != NULL))
+          && (relpath != NULL && *relpath != '\0'))
         {
           info->resurrection = TRUE;
           top_url = svn_uri_dirname(top_url, pool);
@@ -1000,21 +964,15 @@ repos_to_repos_copy(const apr_array_head
       svn_node_kind_t dst_kind;
       const char *src_rel, *dst_rel;
 
-      src_rel = svn_uri__is_child(top_url, pair->src_abspath_or_url, pool);
+      src_rel = svn_uri_skip_ancestor(top_url, pair->src_abspath_or_url, pool);
       if (src_rel)
         {
           SVN_ERR(svn_ra_check_path(ra_session, src_rel, pair->src_revnum,
                                     &info->src_kind, pool));
         }
-      else if (strcmp(pair->src_abspath_or_url, top_url) == 0)
-        {
-          src_rel = "";
-          SVN_ERR(svn_ra_check_path(ra_session, src_rel, pair->src_revnum,
-                                    &info->src_kind, pool));
-        }
       else
         {
-          const char *old_url = NULL;
+          const char *old_url;
 
           src_rel = NULL;
           SVN_ERR_ASSERT(! is_move);
@@ -1033,9 +991,7 @@ repos_to_repos_copy(const apr_array_head
 
       /* Figure out the basename that will result from this operation,
          and ensure that we aren't trying to overwrite existing paths.  */
-      dst_rel = svn_uri__is_child(top_url, pair->dst_abspath_or_url, pool);
-      if (! dst_rel)
-        dst_rel = "";
+      dst_rel = svn_uri_skip_ancestor(top_url, pair->dst_abspath_or_url, pool);
       SVN_ERR(svn_ra_check_path(ra_session, dst_rel, youngest,
                                 &dst_kind, pool));
       if (dst_kind != svn_node_none)
@@ -1289,9 +1245,8 @@ wc_to_repos_copy(const apr_array_header_
         APR_ARRAY_IDX(copy_pairs, i, svn_client__copy_pair_t *);
 
       svn_pool_clear(iterpool);
-      dst_rel = svn_uri__is_child(top_dst_url,
-                                  pair->dst_abspath_or_url,
-                                  iterpool);
+      dst_rel = svn_uri_skip_ancestor(top_dst_url, pair->dst_abspath_or_url,
+                                      iterpool);
       SVN_ERR(svn_ra_check_path(ra_session, dst_rel, SVN_INVALID_REVNUM,
                                 &dst_kind, iterpool));
       if (dst_kind != svn_node_none)
@@ -1412,7 +1367,8 @@ wc_to_repos_copy(const apr_array_header_
                                           pair->src_abspath_or_url,
                                           iterpool, iterpool));
       if (wc_mergeinfo && mergeinfo)
-        SVN_ERR(svn_mergeinfo_merge(mergeinfo, wc_mergeinfo, iterpool));
+        SVN_ERR(svn_mergeinfo_merge2(mergeinfo, wc_mergeinfo, iterpool,
+                                     iterpool));
       else if (! mergeinfo)
         mergeinfo = wc_mergeinfo;
       if (mergeinfo)
@@ -1757,8 +1713,9 @@ repos_to_wc_copy_locked(const apr_array_
       parent = top_dst_path;
 
     SVN_ERR(svn_dirent_get_absolute(&parent_abspath, parent, scratch_pool));
-    dst_err = svn_client_uuid_from_path2(&dst_uuid, parent_abspath, ctx,
-                                         scratch_pool, scratch_pool);
+    dst_err = svn_client_get_repos_root(NULL /* root_url */, &dst_uuid,
+                                        parent_abspath, ctx,
+                                        scratch_pool, scratch_pool);
     if (dst_err && dst_err->apr_err != SVN_ERR_RA_NO_REPOS_UUID)
       return dst_err;
 
@@ -1793,29 +1750,6 @@ repos_to_wc_copy_locked(const apr_array_
   return SVN_NO_ERROR;
 }
 
-struct repos_to_wc_copy_baton {
-  const apr_array_header_t *copy_pairs;
-  const char *top_dst_path;
-  svn_boolean_t ignore_externals;
-  svn_ra_session_t *ra_session;
-  svn_client_ctx_t *ctx;
-};
-
-/* Implements svn_wc__with_write_lock_func_t. */
-static svn_error_t *
-repos_to_wc_copy_cb(void *baton,
-                    apr_pool_t *result_pool,
-                    apr_pool_t *scratch_pool)
-{
-  struct repos_to_wc_copy_baton *b = baton;
-
-  SVN_ERR(repos_to_wc_copy_locked(b->copy_pairs, b->top_dst_path,
-                                  b->ignore_externals, b->ra_session,
-                                  b->ctx, scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
 static svn_error_t *
 repos_to_wc_copy(const apr_array_header_t *copy_pairs,
                  svn_boolean_t make_parents,
@@ -1827,7 +1761,6 @@ repos_to_wc_copy(const apr_array_header_
   const char *top_src_url, *top_dst_path;
   apr_pool_t *iterpool = svn_pool_create(pool);
   const char *lock_abspath;
-  struct repos_to_wc_copy_baton baton;
   int i;
 
   /* Get the real path for the source, based upon its peg revision. */
@@ -1835,19 +1768,15 @@ repos_to_wc_copy(const apr_array_header_
     {
       svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
                                                     svn_client__copy_pair_t *);
-      const char *src, *ignored_url;
-      svn_opt_revision_t *new_rev, *ignored_rev, dead_end_rev;
+      const char *src;
 
       svn_pool_clear(iterpool);
-      dead_end_rev.kind = svn_opt_revision_unspecified;
 
-      SVN_ERR(svn_client__repos_locations(&src, &new_rev,
-                                          &ignored_url, &ignored_rev,
+      SVN_ERR(svn_client__repos_locations(&src, &pair->src_revnum, NULL, NULL,
                                           NULL,
                                           pair->src_abspath_or_url,
                                           &pair->src_peg_revision,
-                                          &pair->src_op_revision,
-                                          &dead_end_rev,
+                                          &pair->src_op_revision, NULL,
                                           ctx, iterpool));
 
       pair->src_original = pair->src_abspath_or_url;
@@ -1870,18 +1799,6 @@ repos_to_wc_copy(const apr_array_header_
                                                NULL, NULL, FALSE, TRUE,
                                                ctx, pool));
 
-  /* Pass null for the path, to ensure error if trying to get a
-     revision based on the working copy.  */
-  for (i = 0; i < copy_pairs->nelts; i++)
-    {
-      svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
-                                                    svn_client__copy_pair_t *);
-
-      SVN_ERR(svn_client__get_revision_number(&pair->src_revnum, NULL,
-                                              ctx->wc_ctx, NULL, ra_session,
-                                              &pair->src_op_revision, pool));
-    }
-
   /* Get the correct src path for the peg revision used, and verify that we
      aren't overwriting an existing path. */
   for (i = 0; i < copy_pairs->nelts; i++)
@@ -1943,15 +1860,10 @@ repos_to_wc_copy(const apr_array_header_
     }
   svn_pool_destroy(iterpool);
 
-  baton.copy_pairs = copy_pairs;
-  baton.top_dst_path = top_dst_path;
-  baton.ignore_externals = ignore_externals;
-  baton.ra_session = ra_session;
-  baton.ctx = ctx;
-
-  SVN_ERR(svn_wc__call_with_write_lock(repos_to_wc_copy_cb, &baton,
-                                       ctx->wc_ctx, lock_abspath,
-                                       FALSE, pool, pool));
+  SVN_WC__CALL_WITH_WRITE_LOCK(
+    repos_to_wc_copy_locked(copy_pairs, top_dst_path, ignore_externals,
+                            ra_session, ctx, pool),
+    ctx->wc_ctx, lock_abspath, FALSE, pool);
   return SVN_NO_ERROR;
 }
 
@@ -2161,9 +2073,9 @@ try_copy(const apr_array_header_t *sourc
     {
       if (!srcs_are_urls)
         {
-          /* If we are doing a wc->* move, but with an operational revision
+          /* If we are doing a wc->* copy, but with an operational revision
              other than the working copy revision, we are really doing a
-             repo->* move, because we're going to need to get the rev from the
+             repo->* copy, because we're going to need to get the rev from the
              repo. */
 
           svn_boolean_t need_repos_op_rev = FALSE;
@@ -2206,7 +2118,7 @@ try_copy(const apr_array_header_t *sourc
                   SVN_ERR(svn_wc__node_get_origin(NULL, &copyfrom_rev,
                                                   &copyfrom_repos_relpath,
                                                   &copyfrom_repos_root_url,
-                                                  NULL,
+                                                  NULL, NULL,
                                                   ctx->wc_ctx,
                                                   pair->src_abspath_or_url,
                                                   TRUE, iterpool, iterpool));

Modified: subversion/branches/revprop-packing/subversion/libsvn_client/delete.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_client/delete.c?rev=1231318&r1=1231317&r2=1231318&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_client/delete.c 
(original)
+++ subversion/branches/revprop-packing/subversion/libsvn_client/delete.c Fri 
Jan 13 21:40:26 2012
@@ -237,7 +237,7 @@ delete_urls_multi_repos(const apr_array_
       for (hi = apr_hash_first(pool, sessions); hi; hi = apr_hash_next(hi))
         {
           repos_root = svn__apr_hash_index_key(hi);
-          repos_relpath = svn_uri__is_child(repos_root, uri, pool);
+          repos_relpath = svn_uri_skip_ancestor(repos_root, uri, pool);
 
           if (repos_relpath)
             {
@@ -264,7 +264,7 @@ delete_urls_multi_repos(const apr_array_
           SVN_ERR(svn_ra_reparent(ra_session, repos_root, pool));
 
           apr_hash_set(sessions, repos_root, APR_HASH_KEY_STRING, ra_session);
-          repos_relpath = svn_uri__is_child(repos_root, uri, pool);
+          repos_relpath = svn_uri_skip_ancestor(repos_root, uri, pool);
 
           relpaths_list = apr_array_make(pool, 1, sizeof(const char *));
           apr_hash_set(relpaths, repos_root, APR_HASH_KEY_STRING,
@@ -272,6 +272,12 @@ delete_urls_multi_repos(const apr_array_
           APR_ARRAY_PUSH(relpaths_list, const char *) = repos_relpath;
         }
 
+      /* Check we identified a non-root relpath.  Return an RA error
+         code for 1.6 compatibility. */
+      if (!repos_relpath || !*repos_relpath)
+        return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
+                                 "URL '%s' not within a repository", uri);
+
       /* Now, test to see if the thing actually exists. */
       SVN_ERR(svn_ra_check_path(ra_session, repos_relpath, SVN_INVALID_REVNUM,
                                 &kind, pool));
@@ -329,29 +335,43 @@ svn_client__wc_delete(const char *path,
   return SVN_NO_ERROR;
 }
 
-/* Callback baton for delete_with_write_lock_baton. */
-struct delete_with_write_lock_baton
-{
-  const char *path;
-  svn_boolean_t force;
-  svn_boolean_t keep_local;
-  svn_client_ctx_t *ctx;
-};
-
-/* Implements svn_wc__with_write_lock_func_t. */
-static svn_error_t *
-delete_with_write_lock_func(void *baton,
-                            apr_pool_t *result_pool,
-                            apr_pool_t *scratch_pool)
+svn_error_t *
+svn_client__wc_delete_many(const apr_array_header_t *targets,
+                           svn_boolean_t force,
+                           svn_boolean_t dry_run,
+                           svn_boolean_t keep_local,
+                           svn_wc_notify_func2_t notify_func,
+                           void *notify_baton,
+                           svn_client_ctx_t *ctx,
+                           apr_pool_t *pool)
 {
-  struct delete_with_write_lock_baton *args = baton;
+  int i;
+  apr_array_header_t *abs_targets;
+
+  abs_targets = apr_array_make(pool, targets->nelts, sizeof(const char *));
+  for (i = 0; i < targets->nelts; i++)
+    {
+      const char *path = APR_ARRAY_IDX(targets, i, const char *);
+      const char *local_abspath;
+
+      SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
+      APR_ARRAY_PUSH(abs_targets, const char *) = local_abspath;
+
+      if (!force && !keep_local)
+        /* Verify that there are no "awkward" files */
+        SVN_ERR(svn_client__can_delete(local_abspath, ctx, pool));
+    }
+
+  if (!dry_run)
+    /* Mark the entry for commit deletion and perform wc deletion */
+    return svn_error_trace(svn_wc__delete_many(ctx->wc_ctx, abs_targets,
+                                               keep_local, TRUE,
+                                               ctx->cancel_func,
+                                               ctx->cancel_baton,
+                                               notify_func, notify_baton,
+                                               pool));
 
-  /* Let the working copy library handle the PATH. */
-  return svn_client__wc_delete(args->path, args->force,
-                               FALSE, args->keep_local,
-                               args->ctx->notify_func2,
-                               args->ctx->notify_baton2,
-                               args->ctx, scratch_pool);
+  return SVN_NO_ERROR;
 }
 
 svn_error_t *
@@ -379,32 +399,75 @@ svn_client_delete4(const apr_array_heade
     }
   else
     {
-      apr_pool_t *subpool = svn_pool_create(pool);
+      const char *local_abspath;
+      apr_hash_t *wcroots;
+      apr_hash_index_t *hi;
       int i;
-
+      int j;
+      apr_pool_t *iterpool;
+      svn_boolean_t is_new_target;
+
+      /* Build a map of wcroots and targets within them. */
+      wcroots = apr_hash_make(pool);
+      iterpool = svn_pool_create(pool);
       for (i = 0; i < paths->nelts; i++)
         {
-          struct delete_with_write_lock_baton dwwlb;
-          const char *path = APR_ARRAY_IDX(paths, i, const char *);
-          const char *local_abspath;
+          const char *wcroot_abspath;
+          apr_array_header_t *targets;
 
-          svn_pool_clear(subpool);
+          svn_pool_clear(iterpool);
 
           /* See if the user wants us to stop. */
           if (ctx->cancel_func)
             SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
 
-          SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, subpool));
-          dwwlb.path = path;
-          dwwlb.force = force;
-          dwwlb.keep_local = keep_local;
-          dwwlb.ctx = ctx;
-          SVN_ERR(svn_wc__call_with_write_lock(delete_with_write_lock_func,
-                                               &dwwlb, ctx->wc_ctx,
-                                               local_abspath, TRUE,
-                                               pool, subpool));
+          SVN_ERR(svn_dirent_get_absolute(&local_abspath,
+                                          APR_ARRAY_IDX(paths, i,
+                                                        const char *),
+                                          pool));
+          SVN_ERR(svn_wc__get_wc_root(&wcroot_abspath, ctx->wc_ctx,
+                                      local_abspath, pool, iterpool));
+          targets = apr_hash_get(wcroots, wcroot_abspath,
+                                 APR_HASH_KEY_STRING);
+          if (targets == NULL)
+            {
+              targets = apr_array_make(pool, 1, sizeof(const char *));
+              apr_hash_set(wcroots, wcroot_abspath, APR_HASH_KEY_STRING,
+                           targets);
+             }
+
+          /* Make sure targets are unique. */
+          is_new_target = TRUE;
+          for (j = 0; j < targets->nelts; j++)
+            {
+              if (strcmp(APR_ARRAY_IDX(targets, j, const char *),
+                         local_abspath) == 0)
+                {
+                  is_new_target = FALSE;
+                  break;
+                }
+            }
+
+          if (is_new_target)
+            APR_ARRAY_PUSH(targets, const char *) = local_abspath;
+        }
+
+      /* Delete the targets from each working copy in turn. */
+      for (hi = apr_hash_first(pool, wcroots); hi; hi = apr_hash_next(hi))
+        {
+          const char *wcroot_abspath = svn__apr_hash_index_key(hi);
+          const apr_array_header_t *targets = svn__apr_hash_index_val(hi);
+
+          svn_pool_clear(iterpool);
+
+          SVN_WC__CALL_WITH_WRITE_LOCK(
+            svn_client__wc_delete_many(targets, force, FALSE, keep_local,
+                                       ctx->notify_func2, ctx->notify_baton2,
+                                       ctx, iterpool),
+            ctx->wc_ctx, wcroot_abspath, TRUE /* lock_anchor */,
+            iterpool);
         }
-      svn_pool_destroy(subpool);
+      svn_pool_destroy(iterpool);
     }
 
   return SVN_NO_ERROR;

Modified: 
subversion/branches/revprop-packing/subversion/libsvn_client/deprecated.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_client/deprecated.c?rev=1231318&r1=1231317&r2=1231318&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_client/deprecated.c 
(original)
+++ subversion/branches/revprop-packing/subversion/libsvn_client/deprecated.c 
Fri Jan 13 21:40:26 2012
@@ -39,10 +39,12 @@
 #include "svn_props.h"
 #include "svn_utf.h"
 #include "svn_string.h"
+#include "svn_pools.h"
 
 #include "client.h"
 #include "mergeinfo.h"
 
+#include "private/svn_opt_private.h"
 #include "private/svn_wc_private.h"
 #include "svn_private_config.h"
 
@@ -837,6 +839,37 @@ svn_client_delete(svn_client_commit_info
 /*** From diff.c ***/
 
 svn_error_t *
+svn_client_diff5(const apr_array_header_t *diff_options,
+                 const char *path1,
+                 const svn_opt_revision_t *revision1,
+                 const char *path2,
+                 const svn_opt_revision_t *revision2,
+                 const char *relative_to_dir,
+                 svn_depth_t depth,
+                 svn_boolean_t ignore_ancestry,
+                 svn_boolean_t no_diff_deleted,
+                 svn_boolean_t show_copies_as_adds,
+                 svn_boolean_t ignore_content_type,
+                 svn_boolean_t use_git_diff_format,
+                 const char *header_encoding,
+                 apr_file_t *outfile,
+                 apr_file_t *errfile,
+                 const apr_array_header_t *changelists,
+                 svn_client_ctx_t *ctx,
+                 apr_pool_t *pool)
+{
+  svn_stream_t *outstream = svn_stream_from_aprfile2(outfile, TRUE, pool);
+  svn_stream_t *errstream = svn_stream_from_aprfile2(errfile, TRUE, pool);
+
+  return svn_client_diff6(diff_options, path1, revision1, path2,
+                          revision2, relative_to_dir, depth,
+                          ignore_ancestry, no_diff_deleted,
+                          show_copies_as_adds, ignore_content_type,
+                          use_git_diff_format, header_encoding,
+                          outstream, errstream, changelists, ctx, pool);
+}
+
+svn_error_t *
 svn_client_diff4(const apr_array_header_t *options,
                  const char *path1,
                  const svn_opt_revision_t *revision1,
@@ -926,6 +959,49 @@ svn_client_diff(const apr_array_header_t
 }
 
 svn_error_t *
+svn_client_diff_peg5(const apr_array_header_t *diff_options,
+                     const char *path,
+                     const svn_opt_revision_t *peg_revision,
+                     const svn_opt_revision_t *start_revision,
+                     const svn_opt_revision_t *end_revision,
+                     const char *relative_to_dir,
+                     svn_depth_t depth,
+                     svn_boolean_t ignore_ancestry,
+                     svn_boolean_t no_diff_deleted,
+                     svn_boolean_t show_copies_as_adds,
+                     svn_boolean_t ignore_content_type,
+                     svn_boolean_t use_git_diff_format,
+                     const char *header_encoding,
+                     apr_file_t *outfile,
+                     apr_file_t *errfile,
+                     const apr_array_header_t *changelists,
+                     svn_client_ctx_t *ctx,
+                     apr_pool_t *pool)
+{
+  svn_stream_t *outstream = svn_stream_from_aprfile2(outfile, TRUE, pool);
+  svn_stream_t *errstream = svn_stream_from_aprfile2(errfile, TRUE, pool);
+
+  return svn_client_diff_peg6(diff_options,
+                              path,
+                              peg_revision,
+                              start_revision,
+                              end_revision,
+                              relative_to_dir,
+                              depth,
+                              ignore_ancestry,
+                              no_diff_deleted,
+                              show_copies_as_adds,
+                              ignore_content_type,
+                              use_git_diff_format,
+                              header_encoding,
+                              outstream,
+                              errstream,
+                              changelists,
+                              ctx,
+                              pool);
+}
+
+svn_error_t *
 svn_client_diff_peg4(const apr_array_header_t *options,
                      const char *path,
                      const svn_opt_revision_t *peg_revision,
@@ -1287,16 +1363,11 @@ svn_client_log4(const apr_array_header_t
                 apr_pool_t *pool)
 {
   apr_array_header_t *revision_ranges;
-  svn_opt_revision_range_t *range;
-
-  range = apr_palloc(pool, sizeof(svn_opt_revision_range_t));
-  range->start = *start;
-  range->end = *end;
 
   revision_ranges = apr_array_make(pool, 1,
                                    sizeof(svn_opt_revision_range_t *));
-
-  APR_ARRAY_PUSH(revision_ranges, svn_opt_revision_range_t *) = range;
+  APR_ARRAY_PUSH(revision_ranges, svn_opt_revision_range_t *)
+    = svn_opt__revision_range_create(start, end, pool);
 
   return svn_client_log5(targets, peg_revision, revision_ranges, limit,
                          discover_changed_paths, strict_node_history,
@@ -1502,13 +1573,11 @@ svn_client_merge_peg2(const char *source
                       svn_client_ctx_t *ctx,
                       apr_pool_t *pool)
 {
-  svn_opt_revision_range_t range;
   apr_array_header_t *ranges_to_merge =
     apr_array_make(pool, 1, sizeof(svn_opt_revision_range_t *));
 
-  range.start = *revision1;
-  range.end = *revision2;
-  APR_ARRAY_PUSH(ranges_to_merge, svn_opt_revision_range_t *) = &range;
+  APR_ARRAY_PUSH(ranges_to_merge, svn_opt_revision_range_t *)
+    = svn_opt__revision_range_create(revision1, revision2, pool);
   return svn_client_merge_peg3(source, ranges_to_merge,
                                peg_revision,
                                target_wcpath,
@@ -2390,6 +2459,41 @@ svn_client_revert(const apr_array_header
 
 /*** From ra.c ***/
 svn_error_t *
+svn_client_uuid_from_url(const char **uuid,
+                         const char *url,
+                         svn_client_ctx_t *ctx,
+                         apr_pool_t *pool)
+{
+  svn_ra_session_t *ra_session;
+  apr_pool_t *subpool = svn_pool_create(pool);
+
+  /* use subpool to create a temporary RA session */
+  SVN_ERR(svn_client__open_ra_session_internal(&ra_session, NULL, url,
+                                               NULL, /* no base dir */
+                                               NULL, FALSE, TRUE,
+                                               ctx, subpool));
+
+  SVN_ERR(svn_ra_get_uuid2(ra_session, uuid, pool));
+
+  /* destroy the RA session */
+  svn_pool_destroy(subpool);
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_uuid_from_path2(const char **uuid,
+                           const char *local_abspath,
+                           svn_client_ctx_t *ctx,
+                           apr_pool_t *result_pool,
+                           apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(
+    svn_wc__node_get_repos_info(NULL, uuid, ctx->wc_ctx, local_abspath,
+                                result_pool, scratch_pool));
+}
+
+svn_error_t *
 svn_client_uuid_from_path(const char **uuid,
                           const char *path,
                           svn_wc_adm_access_t *adm_access,
@@ -2405,6 +2509,20 @@ svn_client_uuid_from_path(const char **u
 
 /*** From url.c ***/
 svn_error_t *
+svn_client_root_url_from_path(const char **url,
+                              const char *path_or_url,
+                              svn_client_ctx_t *ctx,
+                              apr_pool_t *pool)
+{
+  if (!svn_path_is_url(path_or_url))
+    SVN_ERR(svn_dirent_get_absolute(&path_or_url, path_or_url, pool));
+
+  return svn_error_trace(
+           svn_client_get_repos_root(url, NULL, path_or_url,
+                                     ctx, pool, pool));
+}
+
+svn_error_t *
 svn_client_url_from_path(const char **url,
                          const char *path_or_url,
                          apr_pool_t *pool)


Reply via email to