You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2013/12/19 22:49:14 UTC

svn commit: r1552441 - in /subversion/trunk/subversion: libsvn_client/client.h libsvn_client/info.c libsvn_client/list.c libsvn_ra/ra_loader.c

Author: rhuijben
Date: Thu Dec 19 21:49:13 2013
New Revision: 1552441

URL: http://svn.apache.org/r1552441
Log:
Move a backwards compatibility wrapper for svnserve versions 1.0-1.1 to the
ra layer. This will slowdown 'svn list' and 'svn info' a tiny bit for some
cases when using these old versions because we can't limit the ra calls
on knowledge in the callers, but this will make the ra layer easier to use
and maintain. (Callers can stop worrying about this limitation in old
svnserve versions)

We can't really move this in ra_svn as within ra_svn we can't use the normal
ra apis.

* subversion/libsvn_client/client.h
  (svn_client__ra_stat_compatible): Remove function.

* subversion/libsvn_client/info.c
  (svn_client_info4): Use the normal ra function.

* subversion/libsvn_client/list.c
  (svn_client__ra_stat_compatible): Remove function. Move code to ra layer.

* subversion/libsvn_ra/ra_loader.c
  (includes): Add svn_time.h.
  (svn_ra_stat): Move svnserve fallback code here.

Modified:
    subversion/trunk/subversion/libsvn_client/client.h
    subversion/trunk/subversion/libsvn_client/info.c
    subversion/trunk/subversion/libsvn_client/list.c
    subversion/trunk/subversion/libsvn_ra/ra_loader.c

Modified: subversion/trunk/subversion/libsvn_client/client.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/client.h?rev=1552441&r1=1552440&r2=1552441&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/client.h (original)
+++ subversion/trunk/subversion/libsvn_client/client.h Thu Dec 19 21:49:13 2013
@@ -943,18 +943,6 @@ svn_client__condense_commit_items(const 
                                   apr_array_header_t *commit_items,
                                   apr_pool_t *pool);
 
-
-/* Like svn_ra_stat() on the ra session root, but with a compatibility
-   hack for pre-1.2 svnserve that don't support this api. */
-svn_error_t *
-svn_client__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 *result_pool);
-
-
 /* Commit the items in the COMMIT_ITEMS array using EDITOR/EDIT_BATON
    to describe the committed local mods.  Prior to this call,
    COMMIT_ITEMS should have been run through (and BASE_URL generated

Modified: subversion/trunk/subversion/libsvn_client/info.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/info.c?rev=1552441&r1=1552440&r2=1552441&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/info.c (original)
+++ subversion/trunk/subversion/libsvn_client/info.c Thu Dec 19 21:49:13 2013
@@ -389,8 +389,7 @@ svn_client_info4(const char *abspath_or_
   svn_uri_split(NULL, &base_name, pathrev->url, pool);
 
   /* Get the dirent for the URL itself. */
-  SVN_ERR(svn_client__ra_stat_compatible(ra_session, pathrev->rev, &the_ent,
-                                         DIRENT_FIELDS, ctx, pool));
+  SVN_ERR(svn_ra_stat(ra_session, "", pathrev->rev, &the_ent, pool));
 
   if (! the_ent)
     return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,

Modified: subversion/trunk/subversion/libsvn_client/list.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/list.c?rev=1552441&r1=1552440&r2=1552441&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/list.c (original)
+++ subversion/trunk/subversion/libsvn_client/list.c Thu Dec 19 21:49:13 2013
@@ -191,114 +191,6 @@ get_dir_contents(apr_uint32_t dirent_fie
   return SVN_NO_ERROR;
 }
 
-/* Like svn_ra_stat() but with a compatibility hack for pre-1.2 svnserve. */
-/* ### Maybe we should move this behavior into the svn_ra_stat wrapper? */
-svn_error_t *
-svn_client__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_error_t *err;
-
-  err = svn_ra_stat(ra_session, "", rev, dirent_p, pool);
-
-  /* svnserve before 1.2 doesn't support the above, so fall back on
-     a less efficient method. */
-  if (err && err->apr_err == SVN_ERR_RA_NOT_IMPLEMENTED)
-    {
-      const char *repos_root_url;
-      const char *session_url;
-      svn_node_kind_t kind;
-      svn_dirent_t *dirent;
-
-      svn_error_clear(err);
-
-      SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root_url, pool));
-      SVN_ERR(svn_ra_get_session_url(ra_session, &session_url, pool));
-
-      SVN_ERR(svn_ra_check_path(ra_session, "", rev, &kind, pool));
-
-      if (kind != svn_node_none)
-        {
-          if (strcmp(session_url, repos_root_url) != 0)
-            {
-              svn_ra_session_t *parent_session;
-              apr_hash_t *parent_ents;
-              const char *parent_url, *base_name;
-              apr_pool_t *subpool = svn_pool_create(pool);
-
-              /* Open another session to the path's parent.  This server
-                 doesn't support svn_ra_reparent anyway, so don't try it. */
-              svn_uri_split(&parent_url, &base_name, session_url, subpool);
-
-              SVN_ERR(svn_client_open_ra_session2(&parent_session, parent_url,
-                                                  NULL, ctx,
-                                                  subpool, subpool));
-
-              /* Get all parent's entries, no props. */
-              SVN_ERR(svn_ra_get_dir2(parent_session, &parent_ents, NULL,
-                                      NULL, "", rev, dirent_fields, subpool));
-
-              /* Get the relevant entry. */
-              dirent = svn_hash_gets(parent_ents, base_name);
-
-              if (dirent)
-                *dirent_p = svn_dirent_dup(dirent, pool);
-              else
-                *dirent_p = NULL;
-
-              svn_pool_destroy(subpool); /* Close RA session */
-            }
-          else
-            {
-              /* We can't get the directory entry for the repository root,
-                 but we can still get the information we want.
-                 The created-rev of the repository root must, by definition,
-                 be rev. */
-              dirent = apr_palloc(pool, sizeof(*dirent));
-              dirent->kind = kind;
-              dirent->size = SVN_INVALID_FILESIZE;
-              if (dirent_fields & SVN_DIRENT_HAS_PROPS)
-                {
-                  apr_hash_t *props;
-                  SVN_ERR(svn_ra_get_dir2(ra_session, NULL, NULL, &props,
-                                          "", rev, 0 /* no dirent fields */,
-                                          pool));
-                  dirent->has_props = (apr_hash_count(props) != 0);
-                }
-              dirent->created_rev = rev;
-              if (dirent_fields & (SVN_DIRENT_TIME | SVN_DIRENT_LAST_AUTHOR))
-                {
-                  apr_hash_t *props;
-                  svn_string_t *val;
-
-                  SVN_ERR(svn_ra_rev_proplist(ra_session, rev, &props,
-                                              pool));
-                  val = svn_hash_gets(props, SVN_PROP_REVISION_DATE);
-                  if (val)
-                    SVN_ERR(svn_time_from_cstring(&dirent->time, val->data,
-                                                  pool));
-                  else
-                    dirent->time = 0;
-
-                  val = svn_hash_gets(props, SVN_PROP_REVISION_AUTHOR);
-                  dirent->last_author = val ? val->data : NULL;
-                }
-
-              *dirent_p = dirent;
-            }
-        }
-      else
-        *dirent_p = NULL;
-    }
-  else
-    SVN_ERR(err);
-
-  return SVN_NO_ERROR;
-}
 
 /* List the file/directory entries for PATH_OR_URL at REVISION.
    The actual node revision selected is determined by the path as
@@ -373,8 +265,7 @@ list_internal(const char *path_or_url,
 
   fs_path = svn_client__pathrev_fspath(loc, pool);
 
-  SVN_ERR(svn_client__ra_stat_compatible(ra_session, loc->rev, &dirent,
-                                         dirent_fields, ctx, pool));
+  SVN_ERR(svn_ra_stat(ra_session, "", loc->rev, &dirent, pool));
   if (! dirent)
     return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,
                              _("URL '%s' non-existent in revision %ld"),

Modified: subversion/trunk/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra/ra_loader.c?rev=1552441&r1=1552440&r2=1552441&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/trunk/subversion/libsvn_ra/ra_loader.c Thu Dec 19 21:49:13 2013
@@ -36,6 +36,7 @@
 #include "svn_private_config.h"
 #include "svn_hash.h"
 #include "svn_version.h"
+#include "svn_time.h"
 #include "svn_types.h"
 #include "svn_error.h"
 #include "svn_error_codes.h"
@@ -965,8 +966,98 @@ svn_error_t *svn_ra_stat(svn_ra_session_
                          svn_dirent_t **dirent,
                          apr_pool_t *pool)
 {
+  svn_error_t *err;
   SVN_ERR_ASSERT(svn_relpath_is_canonical(path));
-  return session->vtable->stat(session, path, revision, dirent, pool);
+  err = session->vtable->stat(session, path, revision, dirent, pool);
+
+  /* svnserve before 1.2 doesn't support the above, so fall back on
+     a far less efficient, but still correct method. */
+  if (err && err->apr_err == SVN_ERR_RA_NOT_IMPLEMENTED)
+    {
+      /* ### TODO: Find out if we can somehow move this code in libsvn_ra_svn.
+       */
+      apr_pool_t *scratch_pool = svn_pool_create(pool);
+      svn_node_kind_t kind;
+
+      svn_error_clear(err);
+
+      SVN_ERR(svn_ra_check_path(session, "", revision, &kind, scratch_pool));
+
+      if (kind != svn_node_none)
+        {
+          const char *repos_root_url;
+          const char *session_url;
+
+          SVN_ERR(svn_ra_get_repos_root2(session, &repos_root_url, scratch_pool));
+          SVN_ERR(svn_ra_get_session_url(session, &session_url, scratch_pool));
+
+          if (strcmp(session_url, repos_root_url) != 0)
+            {
+              svn_ra_session_t *parent_session;
+              apr_hash_t *parent_ents;
+              const char *parent_url, *base_name;
+
+              /* Open another session to the path's parent.  This server
+                 doesn't support svn_ra_reparent anyway, so don't try it. */
+              svn_uri_split(&parent_url, &base_name, session_url,
+                            scratch_pool);
+
+              SVN_ERR(svn_ra_dup_session(&parent_session, session, parent_url,
+                                         scratch_pool, scratch_pool));
+
+              /* Get all parent's entries, no props. */
+              SVN_ERR(svn_ra_get_dir2(parent_session, &parent_ents, NULL,
+                                      NULL, "", revision, SVN_DIRENT_ALL,
+                                      scratch_pool));
+
+              /* Get the relevant entry. */
+              *dirent = svn_hash_gets(parent_ents, base_name);
+
+              if (*dirent)
+                *dirent = svn_dirent_dup(*dirent, pool);
+            }
+          else
+            {
+              apr_hash_t *props;
+              const svn_string_t *val;
+
+              /* We can't get the directory entry for the repository root,
+                 but we can still get the information we want.
+                 The created-rev of the repository root must, by definition,
+                 be rev. */
+              *dirent = apr_pcalloc(pool, sizeof(*dirent));
+              (*dirent)->kind = kind;
+              (*dirent)->size = SVN_INVALID_FILESIZE;
+
+              SVN_ERR(svn_ra_get_dir2(session, NULL, NULL, &props,
+                                      "", revision, 0 /* no dirent fields */,
+                                      scratch_pool));
+              (*dirent)->has_props = (apr_hash_count(props) != 0);
+
+              (*dirent)->created_rev = revision;
+
+              SVN_ERR(svn_ra_rev_proplist(session, revision, &props,
+                                          scratch_pool));
+
+              val = svn_hash_gets(props, SVN_PROP_REVISION_DATE);
+              if (val)
+                SVN_ERR(svn_time_from_cstring(&(*dirent)->time, val->data,
+                                              scratch_pool));
+
+              val = svn_hash_gets(props, SVN_PROP_REVISION_AUTHOR);
+              (*dirent)->last_author = val ? apr_pstrdup(pool, val->data)
+                                           : NULL;
+            }
+        }
+      else
+        *dirent = NULL;
+
+      svn_pool_clear(scratch_pool);
+    }
+  else
+    SVN_ERR(err);
+
+  return SVN_NO_ERROR;
 }
 
 svn_error_t *svn_ra_get_uuid2(svn_ra_session_t *session,