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/02/14 14:25:19 UTC

svn commit: r1446169 - in /subversion/trunk/subversion: include/svn_dav.h include/svn_ra.h include/svn_ra_svn.h libsvn_ra_local/ra_plugin.c libsvn_ra_serf/options.c libsvn_ra_svn/client.c mod_dav_svn/version.c svnserve/serve.c

Author: rhuijben
Date: Thu Feb 14 13:25:19 2013
New Revision: 1446169

URL: http://svn.apache.org/r1446169
Log:
Following up on r1446118, make the knowledge whether reversed obtaining of
file revisions is available visible by adding an ra capability.

This to allow a future blame improvement to decide whether it can use an
improved algorithm instead of the current one without waiting for an error
on old servers.

* subversion/include/svn_dav.h
  (SVN_DAV_NS_DAV_SVN_ATOMIC_REVPROPS): Move new in 1.7 define below one that
    exists in 1.6.
  (SVN_DAV_NS_DAV_SVN_INHERITED_PROPS): Mark new in 1.8.
  (SVN_DAV_NS_DAV_SVN_EPHEMERAL_TXNPROPS): Mark new in 1.8.
  (SVN_DAV_NS_DAV_SVN_INLINE_PROPS): Mark new in 1.8.
  (SVN_DAV_NS_DAV_SVN_GET_FILE_REVS_REVERSE): New macro.

* subversion/include/svn_ra.h
  (SVN_RA_CAPABILITY_GET_FILE_REVS_REVERSE): New macro.

* subversion/include/svn_ra_svn.h
  (SVN_RA_SVN_CAP_GET_FILE_REVS_REVERSE): New macro.

* subversion/libsvn_ra_local/ra_plugin.c
  (svn_ra_local__has_capability): Declare support for reversed file
    revisions *and* ephemeral txnprops.

* subversion/libsvn_ra_serf/options.c
  (capabilities_headers_iterator_callback): Forward
    SVN_RA_SVN_CAP_GET_FILE_REVS_REVERSE support.

* subversion/libsvn_ra_svn/client.c
  (ra_svn_has_capability): Make function table driven. Add
     SVN_RA_SVN_CAP_GET_FILE_REVS_REVERSE support.

* subversion/mod_dav_svn/version.c
  (get_vsn_options): Write SVN_DAV_NS_DAV_SVN_GET_FILE_REVS_REVERSE.

* subversion/svnserve/serve.c
  (serve): Send SVN_RA_SVN_CAP_GET_FILE_REVS_REVERSE support.

Modified:
    subversion/trunk/subversion/include/svn_dav.h
    subversion/trunk/subversion/include/svn_ra.h
    subversion/trunk/subversion/include/svn_ra_svn.h
    subversion/trunk/subversion/libsvn_ra_local/ra_plugin.c
    subversion/trunk/subversion/libsvn_ra_serf/options.c
    subversion/trunk/subversion/libsvn_ra_svn/client.c
    subversion/trunk/subversion/mod_dav_svn/version.c
    subversion/trunk/subversion/svnserve/serve.c

Modified: subversion/trunk/subversion/include/svn_dav.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_dav.h?rev=1446169&r1=1446168&r2=1446169&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_dav.h (original)
+++ subversion/trunk/subversion/include/svn_dav.h Thu Feb 14 13:25:19 2013
@@ -300,33 +300,37 @@ extern "C" {
 #define SVN_DAV_NS_DAV_SVN_LOG_REVPROPS SVN_DAV_PROP_NS_DAV "svn/log-revprops"
 
 /** Presence of this in a DAV header in an OPTIONS response indicates
- * that the transmitter (in this case, the server) knows how to enforce
- * old-value atomicity in PROPPATCH (for editing revprops). */
-#define SVN_DAV_NS_DAV_SVN_ATOMIC_REVPROPS\
-            SVN_DAV_PROP_NS_DAV "svn/atomic-revprops"
-
-/** Presence of this in a DAV header in an OPTIONS response indicates
  * that the transmitter (in this case, the server) knows how to handle
  * a replay of a directory in the repository (not root). */
 #define SVN_DAV_NS_DAV_SVN_PARTIAL_REPLAY\
             SVN_DAV_PROP_NS_DAV "svn/partial-replay"
 
 /** Presence of this in a DAV header in an OPTIONS response indicates
+ * that the transmitter (in this case, the server) knows how to enforce
+ * old-value atomicity in PROPPATCH (for editing revprops).
+ * @since New in 1.7 */
+#define SVN_DAV_NS_DAV_SVN_ATOMIC_REVPROPS\
+            SVN_DAV_PROP_NS_DAV "svn/atomic-revprops"
+
+/** Presence of this in a DAV header in an OPTIONS response indicates
  * that the transmitter (in this case, the server) knows how to get
- * inherited properties. */
+ * inherited properties. 
+ * @since New in 1.8. */
 #define SVN_DAV_NS_DAV_SVN_INHERITED_PROPS \
   SVN_DAV_PROP_NS_DAV "svn/inherited-props"
 
 /** Presence of this in a DAV header in an OPTIONS response indicates
  * that the transmitter (in this case, the server) knows how to
  * properly handle ephemeral (that is, deleted-just-before-commit) FS
- * transaction properties. */
+ * transaction properties.
+ * @since New in 1.8. */
 #define SVN_DAV_NS_DAV_SVN_EPHEMERAL_TXNPROPS\
             SVN_DAV_PROP_NS_DAV "svn/ephemeral-txnprops"
 
 /** Presence of this in a DAV header in an OPTIONS response indicates
  * that the transmitter (in this case, the server) supports serving properties
- * inline in update editor when 'send-all' is 'false'. */
+ * inline in update editor when 'send-all' is 'false'.
+ * @since New in 1.8. */
 #define SVN_DAV_NS_DAV_SVN_INLINE_PROPS\
             SVN_DAV_PROP_NS_DAV "svn/inline-props"
 
@@ -337,6 +341,13 @@ extern "C" {
 #define SVN_DAV_NS_DAV_SVN_REPLAY_REV_RESOURCE\
             SVN_DAV_PROP_NS_DAV "svn/replay-rev-resource"
 
+/** Presence of this in a DAV header in an OPTIONS response indicates
+ * that the transmitter (in this case, the server) knows how to handle
+ * a reversed fetch of file versions.
+ * @since New in 1.8. */
+#define SVN_DAV_NS_DAV_SVN_GET_FILE_REVS_REVERSE\
+            SVN_DAV_PROP_NS_DAV "svn/get-file-revs-rvrs"
+
 
 /** @} */
 

Modified: subversion/trunk/subversion/include/svn_ra.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_ra.h?rev=1446169&r1=1446168&r2=1446169&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_ra.h (original)
+++ subversion/trunk/subversion/include/svn_ra.h Thu Feb 14 13:25:19 2013
@@ -2039,6 +2039,15 @@ svn_ra_has_capability(svn_ra_session_t *
  */
 #define SVN_RA_CAPABILITY_EPHEMERAL_TXNPROPS "ephemeral-txnprops"
 
+/**
+ * The capability of a server to walk revisions backwards in
+ * svn_ra_get_file_revs2
+ *
+ * @since New in 1.8.
+ */
+#define SVN_RA_CAPABILITY_GET_FILE_REVS_REVERSE "get-file-revs-reversed"
+
+
 /*       *** PLEASE READ THIS IF YOU ADD A NEW CAPABILITY ***
  *
  * RA layers generally fetch all capabilities when asked about any

Modified: subversion/trunk/subversion/include/svn_ra_svn.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_ra_svn.h?rev=1446169&r1=1446168&r2=1446169&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_ra_svn.h (original)
+++ subversion/trunk/subversion/include/svn_ra_svn.h Thu Feb 14 13:25:19 2013
@@ -66,6 +66,9 @@ extern "C" {
 #define SVN_RA_SVN_CAP_INHERITED_PROPS "inherited-props"
 /* maps to SVN_RA_CAPABILITY_EPHEMERAL_TXNPROPS */
 #define SVN_RA_SVN_CAP_EPHEMERAL_TXNPROPS "ephemeral-txnprops"
+/* maps to SVN_RA_CAPABILITY_GET_FILE_REVS_REVERSE */
+#define SVN_RA_SVN_CAP_GET_FILE_REVS_REVERSE "file-revs-reverse"
+
 
 /** ra_svn passes @c svn_dirent_t fields over the wire as a list of
  * words, these are the values used to represent each field.

Modified: subversion/trunk/subversion/libsvn_ra_local/ra_plugin.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_local/ra_plugin.c?rev=1446169&r1=1446168&r2=1446169&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_local/ra_plugin.c (original)
+++ subversion/trunk/subversion/libsvn_ra_local/ra_plugin.c Thu Feb 14 13:25:19 2013
@@ -1513,7 +1513,10 @@ svn_ra_local__has_capability(svn_ra_sess
       || strcmp(capability, SVN_RA_CAPABILITY_PARTIAL_REPLAY) == 0
       || strcmp(capability, SVN_RA_CAPABILITY_COMMIT_REVPROPS) == 0
       || strcmp(capability, SVN_RA_CAPABILITY_ATOMIC_REVPROPS) == 0
-      || strcmp(capability, SVN_RA_CAPABILITY_INHERITED_PROPS) == 0)
+      || strcmp(capability, SVN_RA_CAPABILITY_INHERITED_PROPS) == 0
+      || strcmp(capability, SVN_RA_CAPABILITY_EPHEMERAL_TXNPROPS) == 0
+      || strcmp(capability, SVN_RA_CAPABILITY_GET_FILE_REVS_REVERSE) == 0
+      )
     {
       *has = TRUE;
     }

Modified: subversion/trunk/subversion/libsvn_ra_serf/options.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/options.c?rev=1446169&r1=1446168&r2=1446169&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/options.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/options.c Thu Feb 14 13:25:19 2013
@@ -203,6 +203,13 @@ capabilities_headers_iterator_callback(v
           svn_hash_sets(session->capabilities,
                         SVN_RA_CAPABILITY_INHERITED_PROPS, capability_yes);
         }
+      if (svn_cstring_match_list(SVN_DAV_NS_DAV_SVN_GET_FILE_REVS_REVERSE,
+                                 vals))
+        {
+          svn_hash_sets(session->capabilities,
+                        SVN_RA_CAPABILITY_GET_FILE_REVS_REVERSE,
+                        capability_yes);
+        }
       if (svn_cstring_match_list(SVN_DAV_NS_DAV_SVN_EPHEMERAL_TXNPROPS, vals))
         {
           svn_hash_sets(session->capabilities,

Modified: subversion/trunk/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_svn/client.c?rev=1446169&r1=1446168&r2=1446169&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/trunk/subversion/libsvn_ra_svn/client.c Thu Feb 14 13:25:19 2013
@@ -2589,43 +2589,46 @@ ra_svn_replay_range(svn_ra_session_t *se
 }
 
 
-static svn_error_t *ra_svn_has_capability(svn_ra_session_t *session,
-                                          svn_boolean_t *has,
-                                          const char *capability,
-                                          apr_pool_t *pool)
+static svn_error_t *
+ra_svn_has_capability(svn_ra_session_t *session,
+                      svn_boolean_t *has,
+                      const char *capability,
+                      apr_pool_t *pool)
 {
   svn_ra_svn__session_baton_t *sess = session->priv;
+  static const char* capabilities[][2] =
+  {
+      /* { ra capability string, svn:// wire capability string} */
+      {SVN_RA_CAPABILITY_DEPTH, SVN_RA_SVN_CAP_DEPTH},
+      {SVN_RA_CAPABILITY_MERGEINFO, SVN_RA_SVN_CAP_MERGEINFO},
+      {SVN_RA_CAPABILITY_LOG_REVPROPS, SVN_RA_SVN_CAP_LOG_REVPROPS},
+      {SVN_RA_CAPABILITY_PARTIAL_REPLAY, SVN_RA_SVN_CAP_PARTIAL_REPLAY},
+      {SVN_RA_CAPABILITY_COMMIT_REVPROPS, SVN_RA_SVN_CAP_COMMIT_REVPROPS},
+      {SVN_RA_CAPABILITY_ATOMIC_REVPROPS, SVN_RA_SVN_CAP_ATOMIC_REVPROPS},
+      {SVN_RA_CAPABILITY_INHERITED_PROPS, SVN_RA_SVN_CAP_INHERITED_PROPS},
+      {SVN_RA_CAPABILITY_EPHEMERAL_TXNPROPS,
+                                          SVN_RA_SVN_CAP_EPHEMERAL_TXNPROPS},
+      {SVN_RA_CAPABILITY_GET_FILE_REVS_REVERSE,
+                                       SVN_RA_SVN_CAP_GET_FILE_REVS_REVERSE},
+
+      {NULL, NULL} /* End of list marker */
+  };
+  int i;
 
   *has = FALSE;
 
-  if (strcmp(capability, SVN_RA_CAPABILITY_DEPTH) == 0)
-    *has = svn_ra_svn_has_capability(sess->conn, SVN_RA_SVN_CAP_DEPTH);
-  else if (strcmp(capability, SVN_RA_CAPABILITY_MERGEINFO) == 0)
-    *has = svn_ra_svn_has_capability(sess->conn, SVN_RA_SVN_CAP_MERGEINFO);
-  else if (strcmp(capability, SVN_RA_CAPABILITY_LOG_REVPROPS) == 0)
-    *has = svn_ra_svn_has_capability(sess->conn, SVN_RA_SVN_CAP_LOG_REVPROPS);
-  else if (strcmp(capability, SVN_RA_CAPABILITY_PARTIAL_REPLAY) == 0)
-    *has = svn_ra_svn_has_capability(sess->conn, SVN_RA_SVN_CAP_PARTIAL_REPLAY);
-  else if (strcmp(capability, SVN_RA_CAPABILITY_COMMIT_REVPROPS) == 0)
-    *has = svn_ra_svn_has_capability(sess->conn,
-                                     SVN_RA_SVN_CAP_COMMIT_REVPROPS);
-  else if (strcmp(capability, SVN_RA_CAPABILITY_ATOMIC_REVPROPS) == 0)
-    *has = svn_ra_svn_has_capability(sess->conn,
-                                     SVN_RA_SVN_CAP_ATOMIC_REVPROPS);
-  else if (strcmp(capability, SVN_RA_CAPABILITY_INHERITED_PROPS) == 0)
-    *has = svn_ra_svn_has_capability(sess->conn,
-                                     SVN_RA_SVN_CAP_INHERITED_PROPS);
-  else if (strcmp(capability, SVN_RA_CAPABILITY_EPHEMERAL_TXNPROPS) == 0)
-    *has = svn_ra_svn_has_capability(sess->conn,
-                                     SVN_RA_SVN_CAP_EPHEMERAL_TXNPROPS);
-  else  /* Don't know any other capabilities, so error. */
+  for (i = 0; capabilities[i][0]; i++)
     {
-      return svn_error_createf
-        (SVN_ERR_UNKNOWN_CAPABILITY, NULL,
-         _("Don't know anything about capability '%s'"), capability);
+      if (strcmp(capability, capabilities[i][0]))
+        {
+          *has = svn_ra_svn_has_capability(sess->conn, capabilities[i][1]);
+          return SVN_NO_ERROR;
+        }
     }
 
-  return SVN_NO_ERROR;
+  return svn_error_createf(SVN_ERR_UNKNOWN_CAPABILITY, NULL,
+                           _("Don't know anything about capability '%s'"),
+                           capability);
 }
 
 static svn_error_t *

Modified: subversion/trunk/subversion/mod_dav_svn/version.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/mod_dav_svn/version.c?rev=1446169&r1=1446168&r2=1446169&view=diff
==============================================================================
--- subversion/trunk/subversion/mod_dav_svn/version.c (original)
+++ subversion/trunk/subversion/mod_dav_svn/version.c Thu Feb 14 13:25:19 2013
@@ -150,6 +150,7 @@ get_vsn_options(apr_pool_t *p, apr_text_
   apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_PARTIAL_REPLAY);
   apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_INHERITED_PROPS);
   apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_INLINE_PROPS);
+  apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_GET_FILE_REVS_REVERSE);
   /* Mergeinfo is a special case: here we merely say that the server
    * knows how to handle mergeinfo -- whether the repository does too
    * is a separate matter.

Modified: subversion/trunk/subversion/svnserve/serve.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnserve/serve.c?rev=1446169&r1=1446168&r2=1446169&view=diff
==============================================================================
--- subversion/trunk/subversion/svnserve/serve.c (original)
+++ subversion/trunk/subversion/svnserve/serve.c Thu Feb 14 13:25:19 2013
@@ -3403,7 +3403,7 @@ svn_error_t *serve(svn_ra_svn_conn_t *co
   /* Send greeting.  We don't support version 1 any more, so we can
    * send an empty mechlist. */
   if (params->compression_level > 0)
-    SVN_ERR(svn_ra_svn_write_cmd_response(conn, pool, "nn()(wwwwwwwwww)",
+    SVN_ERR(svn_ra_svn_write_cmd_response(conn, pool, "nn()(wwwwwwwwwww)",
                                           (apr_uint64_t) 2, (apr_uint64_t) 2,
                                           SVN_RA_SVN_CAP_EDIT_PIPELINE,
                                           SVN_RA_SVN_CAP_SVNDIFF1,
@@ -3414,9 +3414,11 @@ svn_error_t *serve(svn_ra_svn_conn_t *co
                                           SVN_RA_SVN_CAP_ATOMIC_REVPROPS,
                                           SVN_RA_SVN_CAP_PARTIAL_REPLAY,
                                           SVN_RA_SVN_CAP_INHERITED_PROPS,
-                                          SVN_RA_SVN_CAP_EPHEMERAL_TXNPROPS));
+                                          SVN_RA_SVN_CAP_EPHEMERAL_TXNPROPS,
+                                          SVN_RA_SVN_CAP_GET_FILE_REVS_REVERSE
+                                          ));
   else
-    SVN_ERR(svn_ra_svn_write_cmd_response(conn, pool, "nn()(wwwwwwwww)",
+    SVN_ERR(svn_ra_svn_write_cmd_response(conn, pool, "nn()(wwwwwwwwww)",
                                           (apr_uint64_t) 2, (apr_uint64_t) 2,
                                           SVN_RA_SVN_CAP_EDIT_PIPELINE,
                                           SVN_RA_SVN_CAP_ABSENT_ENTRIES,
@@ -3426,7 +3428,9 @@ svn_error_t *serve(svn_ra_svn_conn_t *co
                                           SVN_RA_SVN_CAP_ATOMIC_REVPROPS,
                                           SVN_RA_SVN_CAP_PARTIAL_REPLAY,
                                           SVN_RA_SVN_CAP_INHERITED_PROPS,
-                                          SVN_RA_SVN_CAP_EPHEMERAL_TXNPROPS));
+                                          SVN_RA_SVN_CAP_EPHEMERAL_TXNPROPS,
+                                          SVN_RA_SVN_CAP_GET_FILE_REVS_REVERSE
+                                          ));
 
   /* Read client response, which we assume to be in version 2 format:
    * version, capability list, and client URL; then we do an auth



Re: r1446169 - obtaining file-revs in reverse order

Posted by Julian Foad <ju...@btopenworld.com>.
> URL: http://svn.apache.org/r1446169
> Log:
> Following up on r1446118, make the knowledge whether reversed obtaining of
> file revisions is available visible by adding an ra capability.
> 
> This to allow a future blame improvement to decide whether it can use an
> improved algorithm instead of the current one without waiting for an error
> on old servers.

Nice.

A few questions.

When you first added this "reverse order" functionality in <http://svn.apache.org/r1445973>, you documented for svn_ra_get_file_revs2() and svn_repos_get_file_revs2():

+ * On subversion 1.8 and newer servers this function has been enabled
+ * to support reversion of the revision range for @a include_merged_revision
+ * @c FALSE reporting by switching  @a end with @a start.

Is that still the case or do those functions now support a backwards range with merged revisions included?

Reference the capability string in those doc strings.

There's still a big comment on the definition (rather than declaration) of svn_repos_get_file_revs2() which says reverse ranges are not supported; that should go away or be updated.

For testing, in r1445973:

* subversion/tests/libsvn_repos/repos-test.c
  (test_get_file_revs): Extend test to also walk the revisions backwards.

Would it be true to say that the results of a reverse range should always be the reversal of the results from the equivalent forward range?  If so, that would be a useful test.  The current test doesn't appear to verify that the results are in any particular order.

More below...

> * subversion/include/svn_dav.h
>   (SVN_DAV_NS_DAV_SVN_ATOMIC_REVPROPS): Move new in 1.7 define below one that
>     exists in 1.6.
>   (SVN_DAV_NS_DAV_SVN_INHERITED_PROPS): Mark new in 1.8.
>   (SVN_DAV_NS_DAV_SVN_EPHEMERAL_TXNPROPS): Mark new in 1.8.
>   (SVN_DAV_NS_DAV_SVN_INLINE_PROPS): Mark new in 1.8.
>   (SVN_DAV_NS_DAV_SVN_GET_FILE_REVS_REVERSE): New macro.
> 
> * subversion/include/svn_ra.h
>   (SVN_RA_CAPABILITY_GET_FILE_REVS_REVERSE): New macro.
> 
> * subversion/include/svn_ra_svn.h
>   (SVN_RA_SVN_CAP_GET_FILE_REVS_REVERSE): New macro.
> 
> * subversion/libsvn_ra_local/ra_plugin.c
>   (svn_ra_local__has_capability): Declare support for reversed file
>     revisions *and* ephemeral txnprops.

That's an unrelated change, fixing ra-local to advertise ephemeral txnprops.  That's worth drawing attention to, as it indicates we aren't testing that feature.  (It would have been better as a separate commit.)

> * subversion/libsvn_ra_serf/options.c
>   (capabilities_headers_iterator_callback): Forward
>     SVN_RA_SVN_CAP_GET_FILE_REVS_REVERSE support.
> 
> * subversion/libsvn_ra_svn/client.c
>   (ra_svn_has_capability): Make function table driven. Add
>      SVN_RA_SVN_CAP_GET_FILE_REVS_REVERSE support.
> 
> * subversion/mod_dav_svn/version.c
>   (get_vsn_options): Write SVN_DAV_NS_DAV_SVN_GET_FILE_REVS_REVERSE.
> 
> * subversion/svnserve/serve.c
>   (serve): Send SVN_RA_SVN_CAP_GET_FILE_REVS_REVERSE support.


> +/**
> + * The capability of a server to walk revisions backwards in
> + * svn_ra_get_file_revs2

Doxygen will make this a hyperlink if you add '()' after the function name.

> + *
> + * @since New in 1.8.
> + */
> +#define SVN_RA_CAPABILITY_GET_FILE_REVS_REVERSE "get-file-revs-reversed"

> +/** Presence of this in a DAV header in an OPTIONS response indicates
> + * that the transmitter (in this case, the server) knows how to handle
> + * a reversed fetch of file versions.
> + * @since New in 1.8. */
> +#define SVN_DAV_NS_DAV_SVN_GET_FILE_REVS_REVERSE\
> +            SVN_DAV_PROP_NS_DAV "svn/get-file-revs-rvrs"

> +/* maps to SVN_RA_CAPABILITY_GET_FILE_REVS_REVERSE */
> +#define SVN_RA_SVN_CAP_GET_FILE_REVS_REVERSE "file-revs-reverse"

Would it be useful to refer to the relevant DAV/svnserve API functions from these two doc strings?

In the doc string of svn_ra_get_file_revs2(), detail what the presence or absence of this capability really means to a caller.  Something like:

[[[
    With a forward range, svn_ra_get_file_revs2() calculates the list
    of revisions before starting to send them to the caller.

    When a backward range is requested, with the 'reverse' capability
    (#SVN_RA_CAPABILITY_GET_FILE_REVS_REVERSE) svn_ra_get_file_revs2()
    returns the revisions streamily in backward order, but a request
    for merged revisions throws an error; without the capability, it
    either throws an error or returns an incomplete result.
]]]

- Julian