Modified: 
subversion/branches/revprop-packing/subversion/libsvn_client/externals.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_client/externals.c?rev=1231318&r1=1231317&r2=1231318&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_client/externals.c 
(original)
+++ subversion/branches/revprop-packing/subversion/libsvn_client/externals.c 
Fri Jan 13 21:40:26 2012
@@ -126,8 +126,8 @@ relegate_dir_external(svn_wc_context_t *
 static svn_error_t *
 switch_dir_external(const char *local_abspath,
                     const char *url,
-                    const svn_opt_revision_t *revision,
                     const svn_opt_revision_t *peg_revision,
+                    const svn_opt_revision_t *revision,
                     const char *defining_abspath,
                     svn_boolean_t *timestamp_sleep,
                     svn_client_ctx_t *ctx,
@@ -135,10 +135,18 @@ switch_dir_external(const char *local_ab
 {
   svn_node_kind_t kind;
   svn_error_t *err;
+  svn_revnum_t external_peg_rev = SVN_INVALID_REVNUM;
+  svn_revnum_t external_rev = SVN_INVALID_REVNUM;
   apr_pool_t *subpool = svn_pool_create(pool);
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
+  if (peg_revision->kind == svn_opt_revision_number)
+    external_peg_rev = peg_revision->value.number;
+
+  if (revision->kind == svn_opt_revision_number)
+    external_rev = revision->value.number;
+
   /* If path is a directory, try to update/switch to the correct URL
      and revision. */
   SVN_ERR(svn_io_check_path(local_abspath, &kind, pool));
@@ -230,8 +238,8 @@ switch_dir_external(const char *local_ab
                                                 svn_uri_skip_ancestor(
                                                             repos_root_url,
                                                             url, subpool),
-                                                SVN_INVALID_REVNUM,
-                                                SVN_INVALID_REVNUM,
+                                                external_peg_rev,
+                                                external_rev,
                                                 subpool));
 
               svn_pool_destroy(subpool);
@@ -288,8 +296,8 @@ switch_dir_external(const char *local_ab
                                       repos_root_url, repos_uuid,
                                       svn_uri_skip_ancestor(repos_root_url,
                                                             url, pool),
-                                      SVN_INVALID_REVNUM,
-                                      SVN_INVALID_REVNUM,
+                                      external_peg_rev,
+                                      external_rev,
                                       pool));
   }
 
@@ -504,219 +512,6 @@ cleanup:
   return svn_error_trace(err);
 }
 
-/* Return the scheme of @a uri in @a scheme allocated from @a pool.
-   If @a uri does not appear to be a valid URI, then @a scheme will
-   not be updated.  */
-static svn_error_t *
-uri_scheme(const char **scheme, const char *uri, apr_pool_t *pool)
-{
-  apr_size_t i;
-
-  for (i = 0; uri[i] && uri[i] != ':'; ++i)
-    if (uri[i] == '/')
-      goto error;
-
-  if (i > 0 && uri[i] == ':' && uri[i+1] == '/' && uri[i+2] == '/')
-    {
-      *scheme = apr_pstrmemdup(pool, uri, i);
-      return SVN_NO_ERROR;
-    }
-
-error:
-  return svn_error_createf(SVN_ERR_BAD_URL, 0,
-                           _("URL '%s' does not begin with a scheme"),
-                           uri);
-}
-
-/* If the URL for @a item is relative, then using the repository root
-   URL @a repos_root_url and the parent directory URL @parent_dir_url,
-   resolve it into an absolute URL and save it in @a item.
-
-   Regardless if the URL is absolute or not, if there are no errors,
-   the URL in @a item will be canonicalized.
-
-   The following relative URL formats are supported:
-
-     ../    relative to the parent directory of the external
-     ^/     relative to the repository root
-     //     relative to the scheme
-     /      relative to the server's hostname
-
-   The ../ and ^/ relative URLs may use .. to remove path elements up
-   to the server root.
-
-   The external URL should not be canonicalized before calling this function,
-   as otherwise the scheme relative URL '//host/some/path' would have been
-   canonicalized to '/host/some/path' and we would not be able to match on
-   the leading '//'. */
-static svn_error_t *
-resolve_relative_external_url(const char **resolved_url,
-                              const svn_wc_external_item2_t *item,
-                              const char *repos_root_url,
-                              const char *parent_dir_url,
-                              apr_pool_t *result_pool,
-                              apr_pool_t *scratch_pool)
-{
-  const char *url = item->url;
-  apr_uri_t parent_dir_uri;
-  apr_status_t status;
-
-  *resolved_url = item->url;
-
-  /* If the URL is already absolute, there is nothing to do. */
-  if (svn_path_is_url(url))
-    {
-      /* "http://server/path"; */
-      *resolved_url = svn_uri_canonicalize(url, result_pool);
-      return SVN_NO_ERROR;
-    }
-
-  if (url[0] == '/')
-    {
-      /* "/path", "//path", and "///path" */
-      int num_leading_slashes = 1;
-      if (url[1] == '/')
-        {
-          num_leading_slashes++;
-          if (url[2] == '/')
-            num_leading_slashes++;
-        }
-
-      /* "//schema-relative" and in some cases "///schema-relative".
-         This last format is supported on file:// schema relative. */
-      url = apr_pstrcat(scratch_pool,
-                        apr_pstrndup(scratch_pool, url, num_leading_slashes),
-                        svn_relpath_canonicalize(url + num_leading_slashes,
-                                                 scratch_pool),
-                        (char*)NULL);
-    }
-  else
-    {
-      /* "^/path" and "../path" */
-      url = svn_relpath_canonicalize(url, scratch_pool);
-    }
-
-  /* Parse the parent directory URL into its parts. */
-  status = apr_uri_parse(scratch_pool, parent_dir_url, &parent_dir_uri);
-  if (status)
-    return svn_error_createf(SVN_ERR_BAD_URL, 0,
-                             _("Illegal parent directory URL '%s'"),
-                             parent_dir_url);
-
-  /* If the parent directory URL is at the server root, then the URL
-     may have no / after the hostname so apr_uri_parse() will leave
-     the URL's path as NULL. */
-  if (! parent_dir_uri.path)
-    parent_dir_uri.path = apr_pstrmemdup(scratch_pool, "/", 1);
-  parent_dir_uri.query = NULL;
-  parent_dir_uri.fragment = NULL;
-
-  /* Handle URLs relative to the current directory or to the
-     repository root.  The backpaths may only remove path elements,
-     not the hostname.  This allows an external to refer to another
-     repository in the same server relative to the location of this
-     repository, say using SVNParentPath. */
-  if ((0 == strncmp("../", url, 3)) ||
-      (0 == strncmp("^/", url, 2)))
-    {
-      apr_array_header_t *base_components;
-      apr_array_header_t *relative_components;
-      int i;
-
-      /* Decompose either the parent directory's URL path or the
-         repository root's URL path into components.  */
-      if (0 == strncmp("../", url, 3))
-        {
-          base_components = svn_path_decompose(parent_dir_uri.path,
-                                               scratch_pool);
-          relative_components = svn_path_decompose(url, scratch_pool);
-        }
-      else
-        {
-          apr_uri_t repos_root_uri;
-
-          status = apr_uri_parse(scratch_pool, repos_root_url,
-                                 &repos_root_uri);
-          if (status)
-            return svn_error_createf(SVN_ERR_BAD_URL, 0,
-                                     _("Illegal repository root URL '%s'"),
-                                     repos_root_url);
-
-          /* If the repository root URL is at the server root, then
-             the URL may have no / after the hostname so
-             apr_uri_parse() will leave the URL's path as NULL. */
-          if (! repos_root_uri.path)
-            repos_root_uri.path = apr_pstrmemdup(scratch_pool, "/", 1);
-
-          base_components = svn_path_decompose(repos_root_uri.path,
-                                               scratch_pool);
-          relative_components = svn_path_decompose(url + 2, scratch_pool);
-        }
-
-      for (i = 0; i < relative_components->nelts; ++i)
-        {
-          const char *component = APR_ARRAY_IDX(relative_components,
-                                                i,
-                                                const char *);
-          if (0 == strcmp("..", component))
-            {
-              /* Constructing the final absolute URL together with
-                 apr_uri_unparse() requires that the path be absolute,
-                 so only pop a component if the component being popped
-                 is not the component for the root directory. */
-              if (base_components->nelts > 1)
-                apr_array_pop(base_components);
-            }
-          else
-            APR_ARRAY_PUSH(base_components, const char *) = component;
-        }
-
-      parent_dir_uri.path = (char *)svn_path_compose(base_components,
-                                                     scratch_pool);
-      *resolved_url = svn_uri_canonicalize(apr_uri_unparse(scratch_pool,
-                                                           &parent_dir_uri, 0),
-                                       result_pool);
-      return SVN_NO_ERROR;
-    }
-
-  /* The remaining URLs are relative to the either the scheme or
-     server root and can only refer to locations inside that scope, so
-     backpaths are not allowed. */
-  if (svn_path_is_backpath_present(url + 2))
-    return svn_error_createf(SVN_ERR_BAD_URL, 0,
-                             _("The external relative URL '%s' cannot have "
-                               "backpaths, i.e. '..'"),
-                             item->url);
-
-  /* Relative to the scheme: Build a new URL from the parts we know.  */
-  if (0 == strncmp("//", url, 2))
-    {
-      const char *scheme;
-
-      SVN_ERR(uri_scheme(&scheme, repos_root_url, scratch_pool));
-      *resolved_url = svn_uri_canonicalize(apr_pstrcat(scratch_pool, scheme,
-                                                       ":", url, (char *)NULL),
-                                           result_pool);
-      return SVN_NO_ERROR;
-    }
-
-  /* Relative to the server root: Just replace the path portion of the
-     parent's URL.  */
-  if (url[0] == '/')
-    {
-      parent_dir_uri.path = (char *)url;
-      *resolved_url = svn_uri_canonicalize(apr_uri_unparse(scratch_pool,
-                                                           &parent_dir_uri, 0),
-                                           result_pool);
-      return SVN_NO_ERROR;
-    }
-
-  return svn_error_createf(SVN_ERR_BAD_URL, 0,
-                           _("Unrecognized format for the relative external "
-                             "URL '%s'"),
-                           item->url);
-}
-
 static svn_error_t *
 handle_external_item_removal(const struct external_change_baton_t *eb,
                              const char *defining_abspath,
@@ -811,6 +606,7 @@ handle_external_item_change(const struct
   svn_ra_session_t *ra_session;
   svn_client__ra_session_from_path_results ra_cache = { 0 };
   const char *new_url;
+  svn_node_kind_t kind;
 
   ra_cache.kind = svn_node_unknown;
 
@@ -824,155 +620,99 @@ handle_external_item_change(const struct
      iterpool, since the hash table values outlive the iterpool and
      any pointers they have should also outlive the iterpool.  */
 
-   SVN_ERR(resolve_relative_external_url(&new_url,
-                                         new_item, eb->repos_root_url,
-                                         parent_dir_url,
-                                         scratch_pool, scratch_pool));
-
-  /* If the external is being checked out, exported or updated,
-     determine if the external is a file or directory. */
-  if (new_item)
-    {
-      svn_node_kind_t kind;
+  SVN_ERR(svn_wc__resolve_relative_external_url(&new_url,
+                                                new_item, eb->repos_root_url,
+                                                parent_dir_url,
+                                                scratch_pool, scratch_pool));
+
+  /* Determine if the external is a file or directory. */
+  /* Get the RA connection. */
+  SVN_ERR(svn_client__ra_session_from_path(&ra_session,
+                                           &ra_cache.ra_revnum,
+                                           &ra_cache.ra_session_url,
+                                           new_url, NULL,
+                                           &(new_item->peg_revision),
+                                           &(new_item->revision), eb->ctx,
+                                           scratch_pool));
 
-      /* Get the RA connection. */
-      SVN_ERR(svn_client__ra_session_from_path(&ra_session,
-                                               &ra_cache.ra_revnum,
-                                               &ra_cache.ra_session_url,
-                                               new_url, NULL,
-                                               &(new_item->peg_revision),
-                                               &(new_item->revision), eb->ctx,
-                                               scratch_pool));
-
-      SVN_ERR(svn_ra_get_uuid2(ra_session, &ra_cache.repos_uuid,
-                               scratch_pool));
-      SVN_ERR(svn_ra_get_repos_root2(ra_session, &ra_cache.repos_root_url,
-                                     scratch_pool));
-      SVN_ERR(svn_ra_check_path(ra_session, "", ra_cache.ra_revnum, &kind,
-                                scratch_pool));
+  SVN_ERR(svn_ra_get_uuid2(ra_session, &ra_cache.repos_uuid,
+                           scratch_pool));
+  SVN_ERR(svn_ra_get_repos_root2(ra_session, &ra_cache.repos_root_url,
+                                 scratch_pool));
+  SVN_ERR(svn_ra_check_path(ra_session, "", ra_cache.ra_revnum, &kind,
+                            scratch_pool));
+
+  if (svn_node_none == kind)
+    return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
+                             _("URL '%s' at revision %ld doesn't exist"),
+                             ra_cache.ra_session_url,
+                             ra_cache.ra_revnum);
+
+  if (svn_node_dir != kind && svn_node_file != kind)
+    return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
+                             _("URL '%s' at revision %ld is not a file "
+                               "or a directory"),
+                             ra_cache.ra_session_url,
+                             ra_cache.ra_revnum);
 
-      if (svn_node_none == kind)
-        return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
-                                 _("URL '%s' at revision %ld doesn't exist"),
-                                 ra_cache.ra_session_url,
-                                 ra_cache.ra_revnum);
-
-      if (svn_node_dir != kind && svn_node_file != kind)
-        return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
-                                 _("URL '%s' at revision %ld is not a file "
-                                   "or a directory"),
-                                 ra_cache.ra_session_url,
-                                 ra_cache.ra_revnum);
+  ra_cache.kind = kind;
 
-      ra_cache.kind = kind;
-    }
 
   /* Not protecting against recursive externals.  Detecting them in
      the global case is hard, and it should be pretty obvious to a
      user when it happens.  Worst case: your disk fills up :-). */
 
-  if (! old_defining_abspath)
+  /* First notify that we're about to handle an external. */
+  if (eb->ctx->notify_func2)
     {
-      /* This branch is only used during a checkout or an export. */
-
-      /* First notify that we're about to handle an external. */
-      if (eb->ctx->notify_func2)
-        (*eb->ctx->notify_func2)(
-           eb->ctx->notify_baton2,
-           svn_wc_create_notify(local_abspath, svn_wc_notify_update_external,
-                                scratch_pool), scratch_pool);
-
-      switch (ra_cache.kind)
-        {
-        case svn_node_dir:
-          /* The target dir might have multiple components.  Guarantee
-             the path leading down to the last component. */
-          SVN_ERR(svn_io_make_dir_recursively(svn_dirent_dirname(local_abspath,
-                                                                 scratch_pool),
-                                              scratch_pool));
-
-          SVN_ERR(switch_dir_external(
-                   local_abspath, new_url,
-                   &(new_item->peg_revision), &(new_item->revision),
-                   parent_dir_abspath, eb->timestamp_sleep, eb->ctx,
-                   scratch_pool));
-          break;
-        case svn_node_file:
-          if (strcmp(eb->repos_root_url, ra_cache.repos_root_url))
-            return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-                      _("Unsupported external: "
-                        "url of file external '%s' is not in repository '%s'"),
-                      new_url, eb->repos_root_url);
-          SVN_ERR(switch_file_external(local_abspath,
-                                       new_url,
-                                       &new_item->peg_revision,
-                                       &new_item->revision,
-                                       parent_dir_abspath,
-                                       ra_session,
-                                       ra_cache.ra_session_url,
-                                       ra_cache.ra_revnum,
-                                       ra_cache.repos_root_url,
-                                       eb->timestamp_sleep, eb->ctx,
-                                       scratch_pool));
-          break;
-        default:
-          SVN_ERR_MALFUNCTION();
-          break;
-        }
+      (*eb->ctx->notify_func2)(
+         eb->ctx->notify_baton2,
+         svn_wc_create_notify(local_abspath,
+                              svn_wc_notify_update_external,
+                              scratch_pool),
+         scratch_pool);
     }
-  else
-    {
-      /* This branch handles a definition change or simple update. */
 
-      /* First notify that we're about to handle an external. */
-      if (eb->ctx->notify_func2)
-        {
-          svn_wc_notify_t *nt;
-
-          nt = svn_wc_create_notify(local_abspath,
-                                    svn_wc_notify_update_external,
-                                    scratch_pool);
-
-          eb->ctx->notify_func2(eb->ctx->notify_baton2, nt, scratch_pool);
-        }
-
-      /* Either the URL changed, or the exact same item is present in
-         both hashes, and caller wants to update such unchanged items.
-         In the latter case, the call below will try to make sure that
-         the external really is a WC pointing to the correct
-         URL/revision. */
-      switch (ra_cache.kind)
-        {
-        case svn_node_dir:
-          SVN_ERR(switch_dir_external(local_abspath, new_url,
-                                      &(new_item->revision),
-                                      &(new_item->peg_revision),
-                                      parent_dir_abspath,
-                                      eb->timestamp_sleep, eb->ctx,
-                                      scratch_pool));
-          break;
-        case svn_node_file:
-          if (strcmp(eb->repos_root_url, ra_cache.repos_root_url))
-            return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-                      _("Unsupported external: "
-                        "url of file external '%s' is not in repository '%s'"),
-                      new_url, eb->repos_root_url);
-          SVN_ERR(switch_file_external(local_abspath,
-                                       new_url,
-                                       &new_item->peg_revision,
-                                       &new_item->revision,
-                                       parent_dir_abspath,
-                                       ra_session,
-                                       ra_cache.ra_session_url,
-                                       ra_cache.ra_revnum,
-                                       ra_cache.repos_root_url,
-                                       eb->timestamp_sleep, eb->ctx,
-                                       scratch_pool));
-          break;
-        default:
-          SVN_ERR_MALFUNCTION();
-          break;
-        }
+  if (! old_defining_abspath)
+    {
+      /* The target dir might have multiple components.  Guarantee the path
+         leading down to the last component. */
+      SVN_ERR(svn_io_make_dir_recursively(svn_dirent_dirname(local_abspath,
+                                                             scratch_pool),
+                                          scratch_pool));
+    }
+
+  switch (ra_cache.kind)
+    {
+      case svn_node_dir:
+        SVN_ERR(switch_dir_external(local_abspath, new_url,
+                                    &(new_item->peg_revision),
+                                    &(new_item->revision),
+                                    parent_dir_abspath,
+                                    eb->timestamp_sleep, eb->ctx,
+                                    scratch_pool));
+        break;
+      case svn_node_file:
+        if (strcmp(eb->repos_root_url, ra_cache.repos_root_url))
+          return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+                    _("Unsupported external: "
+                      "url of file external '%s' is not in repository '%s'"),
+                    new_url, eb->repos_root_url);
+        SVN_ERR(switch_file_external(local_abspath,
+                                     new_url,
+                                     &new_item->peg_revision,
+                                     &new_item->revision,
+                                     parent_dir_abspath,
+                                     ra_session,
+                                     ra_cache.ra_session_url,
+                                     ra_cache.ra_revnum,
+                                     ra_cache.repos_root_url,
+                                     eb->timestamp_sleep, eb->ctx,
+                                     scratch_pool));
+        break;
+      default:
+        SVN_ERR_MALFUNCTION();
+        break;
     }
 
   return SVN_NO_ERROR;
@@ -1156,6 +896,7 @@ svn_client__handle_externals(apr_hash_t 
     {
       const char *item_abspath = svn__apr_hash_index_key(hi);
       const char *defining_abspath = svn__apr_hash_index_val(hi);
+      const char *parent_abspath;
 
       svn_pool_clear(iterpool);
 
@@ -1164,6 +905,30 @@ svn_client__handle_externals(apr_hash_t 
                           handle_external_item_removal(&eb, defining_abspath,
                                                        item_abspath, iterpool),
                           iterpool));
+
+      /* Are there any unversioned directories between the removed
+       * external and the DEFINING_ABSPATH which we can remove? */
+      parent_abspath = item_abspath;
+      do {
+        svn_wc_status3_t *parent_status;
+
+        parent_abspath = svn_dirent_dirname(parent_abspath, iterpool);
+        SVN_ERR(svn_wc_status3(&parent_status, ctx->wc_ctx, parent_abspath,
+                               iterpool, iterpool));
+        if (parent_status->node_status == svn_wc_status_unversioned)
+          {
+            svn_error_t *err;
+
+            err = svn_io_dir_remove_nonrecursive(parent_abspath, iterpool);
+            if (err && APR_STATUS_IS_ENOTEMPTY(err->apr_err))
+              {
+                svn_error_clear(err);
+                break;
+              }
+            else
+              SVN_ERR(err);
+          }
+      } while (strcmp(parent_abspath, defining_abspath) != 0);
     }
 
 
@@ -1232,9 +997,10 @@ svn_client__export_externals(apr_hash_t 
           item_abspath = svn_dirent_join(local_abspath, item->target_dir,
                                          sub_iterpool);
 
-          SVN_ERR(resolve_relative_external_url(&new_url, item,
-                                                repos_root_url, dir_url,
-                                                sub_iterpool, sub_iterpool));
+          SVN_ERR(svn_wc__resolve_relative_external_url(&new_url, item,
+                                                        repos_root_url,
+                                                        dir_url, sub_iterpool,
+                                                        sub_iterpool));
 
           /* The target dir might have multiple components.  Guarantee
              the path leading down to the last component. */

Modified: subversion/branches/revprop-packing/subversion/libsvn_client/info.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_client/info.c?rev=1231318&r1=1231317&r2=1231318&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_client/info.c 
(original)
+++ subversion/branches/revprop-packing/subversion/libsvn_client/info.c Fri Jan 
13 21:40:26 2012
@@ -145,8 +145,8 @@ push_dir_info(svn_ra_session_t *ra_sessi
 
       path = svn_relpath_join(dir, name, subpool);
       URL = svn_path_url_add_component2(session_URL, name, subpool);
-      fs_path = svn_fspath__canonicalize(svn_uri__is_child(repos_root, URL,
-                                                           subpool), subpool);
+      fs_path = svn_fspath__canonicalize(
+                  svn_uri_skip_ancestor(repos_root, URL, subpool), subpool);
 
       lock = apr_hash_get(locks, fs_path, APR_HASH_KEY_STRING);
 
@@ -186,20 +186,17 @@ same_resource_in_head(svn_boolean_t *sam
                       apr_pool_t *pool)
 {
   svn_error_t *err;
-  svn_opt_revision_t start_rev, end_rev, peg_rev;
-  svn_opt_revision_t *ignored_rev;
-  const char *head_url, *ignored_url;
+  svn_opt_revision_t start_rev, peg_rev;
+  const char *head_url;
 
   start_rev.kind = svn_opt_revision_head;
   peg_rev.kind = svn_opt_revision_number;
   peg_rev.value.number = rev;
-  end_rev.kind = svn_opt_revision_unspecified;
 
-  err = svn_client__repos_locations(&head_url, &ignored_rev,
-                                    &ignored_url, &ignored_rev,
+  err = svn_client__repos_locations(&head_url, NULL, NULL, NULL,
                                     ra_session,
                                     url, &peg_rev,
-                                    &start_rev, &end_rev,
+                                    &start_rev, NULL,
                                     ctx, pool);
   if (err &&
       ((err->apr_err == SVN_ERR_CLIENT_UNRELATED_RESOURCES) ||
@@ -258,6 +255,75 @@ wc_info_receiver(void *baton,
                                  abspath_or_url, &client_info, scratch_pool);
 }
 
+/* Like svn_ra_stat() but with a compatibility hack for pre-1.2 svnserve. */
+static svn_error_t *
+ra_stat_compatible(svn_ra_session_t *ra_session,
+                   svn_revnum_t rev,
+                   svn_dirent_t **dirent_p,
+                   apr_uint32_t dirent_fields,
+                   svn_client_ctx_t *ctx,
+                   apr_pool_t *pool)
+{
+  const char *repos_root_URL, *url;
+  svn_error_t *err;
+  svn_dirent_t *the_ent;
+
+  SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root_URL, pool));
+  SVN_ERR(svn_ra_get_session_url(ra_session, &url, pool));
+
+  err = svn_ra_stat(ra_session, "", rev, &the_ent, pool);
+
+  /* svn_ra_stat() will work against old versions of mod_dav_svn, but
+     not old versions of svnserve.  In the case of a pre-1.2 svnserve,
+     catch the specific error it throws:*/
+  if (err && err->apr_err == SVN_ERR_RA_NOT_IMPLEMENTED)
+    {
+      /* Fall back to pre-1.2 strategy for fetching dirent's URL. */
+      svn_node_kind_t url_kind;
+      svn_ra_session_t *parent_ra_session;
+      apr_hash_t *parent_ents;
+      const char *parent_url, *base_name;
+
+      if (strcmp(url, repos_root_URL) == 0)
+        {
+          /* In this universe, there's simply no way to fetch
+             information about the repository's root directory! */
+          return err;
+        }
+
+      svn_error_clear(err);
+
+      SVN_ERR(svn_ra_check_path(ra_session, "", rev, &url_kind, pool));
+      if (url_kind == svn_node_none)
+        return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
+                                 _("URL '%s' non-existent in revision %ld"),
+                                 url, rev);
+
+      /* Open a new RA session to the item's parent. */
+      svn_uri_split(&parent_url, &base_name, url, pool);
+      SVN_ERR(svn_client__open_ra_session_internal(&parent_ra_session, NULL,
+                                                   parent_url, NULL,
+                                                   NULL, FALSE, TRUE,
+                                                   ctx, pool));
+
+      /* Get all parent's entries, and find the item's dirent in the hash. */
+      SVN_ERR(svn_ra_get_dir2(parent_ra_session, &parent_ents, NULL, NULL,
+                              "", rev, dirent_fields, pool));
+      the_ent = apr_hash_get(parent_ents, base_name, APR_HASH_KEY_STRING);
+      if (the_ent == NULL)
+        return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
+                                 _("URL '%s' non-existent in revision %ld"),
+                                 url, rev);
+    }
+  else if (err)
+    {
+      return svn_error_trace(err);
+    }
+
+  *dirent_p = the_ent;
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_client_info3(const char *abspath_or_url,
                  const svn_opt_revision_t *peg_revision,
@@ -271,15 +337,13 @@ svn_client_info3(const char *abspath_or_
                  svn_client_ctx_t *ctx,
                  apr_pool_t *pool)
 {
-  svn_ra_session_t *ra_session, *parent_ra_session;
+  svn_ra_session_t *ra_session;
   svn_revnum_t rev;
   const char *url;
-  svn_node_kind_t url_kind;
   const char *repos_root_URL, *repos_UUID;
   svn_lock_t *lock;
   svn_boolean_t related;
-  apr_hash_t *parent_ents;
-  const char *parent_url, *base_name;
+  const char *base_name;
   svn_dirent_t *the_ent;
   svn_client_info2_t *info;
   svn_error_t *err;
@@ -314,56 +378,26 @@ svn_client_info3(const char *abspath_or_
   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(&parent_url, &base_name, url, pool);
+  svn_uri_split(NULL, &base_name, url, pool);
 
   /* Get the dirent for the URL itself. */
-  err = svn_ra_stat(ra_session, "", rev, &the_ent, pool);
-
-  /* svn_ra_stat() will work against old versions of mod_dav_svn, but
-     not old versions of svnserve.  In the case of a pre-1.2 svnserve,
-     catch the specific error it throws:*/
+  err = ra_stat_compatible(ra_session, rev, &the_ent, DIRENT_FIELDS,
+                           ctx, pool);
   if (err && err->apr_err == SVN_ERR_RA_NOT_IMPLEMENTED)
     {
-      /* Fall back to pre-1.2 strategy for fetching dirent's URL. */
       svn_error_clear(err);
 
-      if (strcmp(url, repos_root_URL) == 0)
-        {
-          /* In this universe, there's simply no way to fetch
-             information about the repository's root directory!
-             If we're recursing, degrade gracefully: rather than
-             throw an error, return no information about the
-             repos root. */
-          if (depth > svn_depth_empty)
-            goto pre_1_2_recurse;
-
-          /* Otherwise, we really are stuck.  Better tell the user
-             what's going on. */
-          return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-                                   _("Server does not support retrieving "
-                                     "information about the repository root"));
-        }
-
-      SVN_ERR(svn_ra_check_path(ra_session, "", rev, &url_kind, pool));
-      if (url_kind == svn_node_none)
-        return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
-                                 _("URL '%s' non-existent in revision %ld"),
-                                 url, rev);
-
-      /* Open a new RA session to the item's parent. */
-      SVN_ERR(svn_client__open_ra_session_internal(&parent_ra_session, NULL,
-                                                   parent_url, NULL,
-                                                   NULL, FALSE, TRUE,
-                                                   ctx, pool));
-
-      /* Get all parent's entries, and find the item's dirent in the hash. */
-      SVN_ERR(svn_ra_get_dir2(parent_ra_session, &parent_ents, NULL, NULL,
-                              "", rev, DIRENT_FIELDS, pool));
-      the_ent = apr_hash_get(parent_ents, base_name, APR_HASH_KEY_STRING);
-      if (the_ent == NULL)
-        return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
-                                 _("URL '%s' non-existent in revision %ld"),
-                                 url, rev);
+      /* If we're recursing, degrade gracefully: rather than
+         throw an error, return no information about the
+         repos root. */
+      if (depth > svn_depth_empty)
+        goto pre_1_2_recurse;
+
+      /* Otherwise, we really are stuck.  Better tell the user
+         what's going on. */
+      return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+                               _("Server does not support retrieving "
+                                 "information about the repository root"));
     }
   else if (err)
     {

Modified: subversion/branches/revprop-packing/subversion/libsvn_client/list.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_client/list.c?rev=1231318&r1=1231317&r2=1231318&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_client/list.c 
(original)
+++ subversion/branches/revprop-packing/subversion/libsvn_client/list.c Fri Jan 
13 21:40:26 2012
@@ -32,6 +32,7 @@
 #include "client.h"
 
 #include "private/svn_fspath.h"
+#include "private/svn_ra_private.h"
 #include "svn_private_config.h"
 
 /* Get the directory entries of DIR at REV (relative to the root of
@@ -91,7 +92,7 @@ get_dir_contents(apr_uint32_t dirent_fie
     {
       svn_sort__item_t *item = &APR_ARRAY_IDX(array, i, svn_sort__item_t);
       const char *path;
-      svn_dirent_t *the_ent = apr_hash_get(tmpdirents, item->key, item->klen);
+      svn_dirent_t *the_ent = item->value;
       svn_lock_t *lock;
 
       svn_pool_clear(iterpool);
@@ -121,42 +122,21 @@ get_dir_contents(apr_uint32_t dirent_fie
   return SVN_NO_ERROR;
 }
 
-svn_error_t *
-svn_client_list2(const char *path_or_url,
-                 const svn_opt_revision_t *peg_revision,
-                 const svn_opt_revision_t *revision,
-                 svn_depth_t depth,
-                 apr_uint32_t dirent_fields,
-                 svn_boolean_t fetch_locks,
-                 svn_client_list_func_t list_func,
-                 void *baton,
-                 svn_client_ctx_t *ctx,
-                 apr_pool_t *pool)
+/* Like svn_ra_stat() but with a compatibility hack for pre-1.2 svnserve. */
+static svn_error_t *
+ra_stat_compatible(svn_ra_session_t *ra_session,
+                   svn_revnum_t rev,
+                   svn_dirent_t **dirent_p,
+                   apr_uint32_t dirent_fields,
+                   svn_client_ctx_t *ctx,
+                   apr_pool_t *pool)
 {
-  svn_ra_session_t *ra_session;
-  svn_revnum_t rev;
-  svn_dirent_t *dirent;
-  const char *url;
-  const char *repos_root;
-  const char *fs_path;
+  const char *repos_root, *url;
   svn_error_t *err;
-  apr_hash_t *locks;
-
-  /* We use the kind field to determine if we should recurse, so we
-     always need it. */
-  dirent_fields |= SVN_DIRENT_KIND;
-
-  /* Get an RA plugin for this filesystem object. */
-  SVN_ERR(svn_client__ra_session_from_path(&ra_session, &rev,
-                                           &url, path_or_url, NULL,
-                                           peg_revision,
-                                           revision, ctx, pool));
+  svn_dirent_t *dirent;
 
   SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root, pool));
-
-  SVN_ERR(svn_client__path_relative_to_root(&fs_path, ctx->wc_ctx, url,
-                                            repos_root, TRUE, ra_session,
-                                            pool, pool));
+  SVN_ERR(svn_ra_get_session_url(ra_session, &url, pool));
 
   err = svn_ra_stat(ra_session, "", rev, &dirent, pool);
 
@@ -240,6 +220,45 @@ svn_client_list2(const char *path_or_url
   else if (err)
     return svn_error_trace(err);
 
+  *dirent_p = dirent;
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_list2(const char *path_or_url,
+                 const svn_opt_revision_t *peg_revision,
+                 const svn_opt_revision_t *revision,
+                 svn_depth_t depth,
+                 apr_uint32_t dirent_fields,
+                 svn_boolean_t fetch_locks,
+                 svn_client_list_func_t list_func,
+                 void *baton,
+                 svn_client_ctx_t *ctx,
+                 apr_pool_t *pool)
+{
+  svn_ra_session_t *ra_session;
+  svn_revnum_t rev;
+  svn_dirent_t *dirent;
+  const char *url;
+  const char *fs_path;
+  svn_error_t *err;
+  apr_hash_t *locks;
+
+  /* We use the kind field to determine if we should recurse, so we
+     always need it. */
+  dirent_fields |= SVN_DIRENT_KIND;
+
+  /* Get an RA plugin for this filesystem object. */
+  SVN_ERR(svn_client__ra_session_from_path(&ra_session, &rev,
+                                           &url, path_or_url, NULL,
+                                           peg_revision,
+                                           revision, ctx, pool));
+
+  SVN_ERR(svn_ra__get_fspath_relative_to_root(ra_session, &fs_path, url,
+                                              pool));
+
+  SVN_ERR(ra_stat_compatible(ra_session, rev, &dirent, dirent_fields,
+                             ctx, pool));
   if (! dirent)
     return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,
                              _("URL '%s' non-existent in revision %ld"),

Modified: subversion/branches/revprop-packing/subversion/libsvn_client/log.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_client/log.c?rev=1231318&r1=1231317&r2=1231318&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_client/log.c 
(original)
+++ subversion/branches/revprop-packing/subversion/libsvn_client/log.c Fri Jan 
13 21:40:26 2012
@@ -211,8 +211,7 @@ pre_15_receiver(void *baton, svn_log_ent
                                   name, &value, pool));
           if (log_entry->revprops == NULL)
             log_entry->revprops = apr_hash_make(pool);
-          apr_hash_set(log_entry->revprops, (const void *)name,
-                       APR_HASH_KEY_STRING, (const void *)value);
+          apr_hash_set(log_entry->revprops, name, APR_HASH_KEY_STRING, value);
         }
       if (log_entry->revprops)
         {
@@ -284,7 +283,6 @@ svn_client_log5(const apr_array_header_t
   svn_boolean_t has_log_revprops;
   const char *actual_url;
   apr_array_header_t *condensed_targets;
-  svn_revnum_t ignored_revnum;
   svn_opt_revision_t session_opt_rev;
   const char *ra_target;
   pre_15_receiver_baton_t rb = {0};
@@ -301,8 +299,7 @@ svn_client_log5(const apr_array_header_t
 
   /* Make a copy of PEG_REVISION, we may need to change it to a
      default value. */
-  peg_rev.kind = peg_revision->kind;
-  peg_rev.value = peg_revision->value;
+  peg_rev = *peg_revision;
 
   /* Use the passed URL, if there is one.  */
   url_or_path = APR_ARRAY_IDX(targets, 0, const char *);
@@ -330,7 +327,7 @@ svn_client_log5(const apr_array_header_t
       else if (range->start.kind == svn_opt_revision_unspecified)
         {
           /* Default to any specified peg revision.  Otherwise, if the
-           * first target is an URL, then we default to HEAD:0.  Lastly,
+           * first target is a URL, then we default to HEAD:0.  Lastly,
            * the default is BASE:0 since WC@HEAD may not exist. */
           if (peg_rev.kind == svn_opt_revision_unspecified)
             {
@@ -428,7 +425,7 @@ svn_client_log5(const apr_array_header_t
                                 _("When specifying working copy paths, only "
                                   "one target may be given"));
 
-      /* An unspecified PEG_REVISION for a working copy path defautls
+      /* An unspecified PEG_REVISION for a working copy path defaults
          to svn_opt_revision_working. */
       if (peg_rev.kind == svn_opt_revision_unspecified)
           peg_rev.kind = svn_opt_revision_working;
@@ -486,8 +483,8 @@ svn_client_log5(const apr_array_header_t
     else
       ra_target = url_or_path;
 
-    SVN_ERR(svn_client__ra_session_from_path(&ra_session, &ignored_revnum,
-                                             &actual_url, ra_target, NULL,
+    SVN_ERR(svn_client__ra_session_from_path(&ra_session, NULL, &actual_url,
+                                             ra_target, NULL,
                                              &peg_rev, &session_opt_rev,
                                              ctx, pool));
 


Reply via email to