You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2022/03/02 14:30:23 UTC

svn commit: r1898530 - in /subversion/branches/pristines-on-demand-on-mwf: ./ subversion/include/ subversion/libsvn_client/ subversion/libsvn_wc/ subversion/svn/ subversion/tests/cmdline/ subversion/tests/cmdline/getopt_tests_data/ subversion/tests/cmd...

Author: julianfoad
Date: Wed Mar  2 14:30:22 2022
New Revision: 1898530

URL: http://svn.apache.org/viewvc?rev=1898530&view=rev
Log:
On the 'pristines-on-demand-on-mwf' branch: sync with trunk@1898529.

Modified:
    subversion/branches/pristines-on-demand-on-mwf/   (props changed)
    subversion/branches/pristines-on-demand-on-mwf/subversion/include/svn_client.h
    subversion/branches/pristines-on-demand-on-mwf/subversion/include/svn_wc.h
    subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/upgrade.c
    subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/info.c
    subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc-metadata.sql
    subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc.h
    subversion/branches/pristines-on-demand-on-mwf/subversion/svn/cl.h
    subversion/branches/pristines-on-demand-on-mwf/subversion/svn/help-cmd.c
    subversion/branches/pristines-on-demand-on-mwf/subversion/svn/info-cmd.c
    subversion/branches/pristines-on-demand-on-mwf/subversion/svn/notify.c
    subversion/branches/pristines-on-demand-on-mwf/subversion/svn/svn.c
    subversion/branches/pristines-on-demand-on-mwf/subversion/svn/upgrade-cmd.c
    subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/getopt_tests_data/svn--version--verbose_stdout
    subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/getopt_tests_data/svn--version_stdout
    subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/svntest/main.py
    subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/upgrade_tests.py

Propchange: subversion/branches/pristines-on-demand-on-mwf/
------------------------------------------------------------------------------
  Merged /subversion/trunk:r1898379-1898529

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/include/svn_client.h?rev=1898530&r1=1898529&r2=1898530&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/include/svn_client.h (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/include/svn_client.h Wed Mar  2 14:30:22 2022
@@ -1244,7 +1244,7 @@ svn_client_args_to_target_array(apr_arra
  *              client that supports the metadata format of the
  *              created working copy; @c NULL means the library's default
  *              format. See svn_client_default_wc_version(),
- *              svn_client_supported_wc_formats().
+ *              svn_client_get_wc_formats_supported().
  * @param[in] ctx   The standard client context, used for authentication and
  *              notification.
  * @param[in] pool  Used for any temporary allocation.
@@ -4402,7 +4402,7 @@ svn_client_cleanup(const char *dir,
  * @a wc_format_version is the version number of the Subversion client
  * that supports a given WC metadata format; @c NULL means the library's
  * default format. See svn_client_default_wc_version(),
- * svn_client_supported_wc_formats().
+ * svn_client_get_wc_formats_supported().
  *
  * Use @a scratch_pool for any temporary allocations.
  *
@@ -4428,7 +4428,16 @@ svn_client_upgrade(const char *wcroot_di
                    apr_pool_t *scratch_pool);
 
 /**
- * Returns the version related to the library's default
+ * Returns the first version that supported the library's oldest
+ * working copy metadata format.
+ *
+ * @since New in 1.15.
+ */
+const svn_version_t *
+svn_client_oldest_wc_version(apr_pool_t *result_pool);
+
+/**
+ * Returns the first version that supported the library's default
  * working copy metadata format.
  *
  * @since New in 1.15.
@@ -4437,31 +4446,34 @@ const svn_version_t *
 svn_client_default_wc_version(apr_pool_t *result_pool);
 
 /**
- * Information about a WC version.
+ * Returns the first version that supported the library's latest
+ * working copy metadata format.
  *
- * Only the @c .major and @c .minor version fields are significant: so a
- * version_max value of 1.15.0 for example means "up to 1.15.x".
+ * @since New in 1.15.
  */
-typedef struct svn_client_wc_format_t {
-    /* Oldest version of svn libraries known to support this WC version */
-    const svn_version_t *version_min;
-    /* Newest version of svn libraries known to support this WC version. */
-    const svn_version_t *version_max;
-    /* The WC format number of this format, as defined by libsvn_wc. */
-    int wc_format;
-} svn_client_wc_format_t;
+const svn_version_t *
+svn_client_latest_wc_version(apr_pool_t *result_pool);
 
 /**
  * Returns a list of the WC formats supported by the client library.
  *
- * The list is sorted from oldest to newest, and terminated by an entry
- * containing all null/zero fields.
+ * The list is sorted from oldest to newest, and terminated by a zero entry.
+ *
+ * The result is allocated in @a result_pool and/or statically.
+ *
+ * @since New in 1.15.
+ */
+const int *
+svn_client_get_wc_formats_supported(apr_pool_t *result_pool);
+
+/** Return the version of the Subversion library that first supported
+ * the given WC format, @a wc_format.
  *
- * The returned data are allocated in @a result_pool and/or statically.
+ * @since New in 1.15.
  */
-const svn_client_wc_format_t *
-svn_client_supported_wc_formats(apr_pool_t *result_pool,
-                                apr_pool_t *scratch_pool);
+const svn_version_t *
+svn_client_wc_version_from_format(int wc_format,
+                                  apr_pool_t *result_pool);
 
 /** @} */
 

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/include/svn_wc.h?rev=1898530&r1=1898529&r2=1898530&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/include/svn_wc.h (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/include/svn_wc.h Wed Mar  2 14:30:22 2022
@@ -3298,18 +3298,6 @@ typedef struct svn_wc_info_t
    * @since New in 1.15.
    */
   int wc_format;
-
-  /**
-   * The oldest supported working copy format, #SVN_WC__SUPPORTED_VERSION.
-   * @since New in 1.15.
-   */
-  int wc_format_min;
-
-  /**
-   * The newest supported working copy format, #SVN_WC__VERSION.
-   * @since New in 1.15.
-   */
-  int wc_format_max;
 } svn_wc_info_t;
 
 /**

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/upgrade.c?rev=1898530&r1=1898529&r2=1898530&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/upgrade.c (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/upgrade.c Wed Mar  2 14:30:22 2022
@@ -204,21 +204,54 @@ svn_client_upgrade2(const char *path,
   return SVN_NO_ERROR;
 }
 
-const svn_client_wc_format_t *
-svn_client_supported_wc_formats(apr_pool_t *result_pool,
-                                apr_pool_t *scratch_pool)
+const svn_version_t *
+svn_client_wc_version_from_format(int wc_format,
+                                  apr_pool_t *result_pool)
+{
+  static const svn_version_t
+    version_1_0  = { 1, 0, 0, NULL },
+    version_1_4  = { 1, 4, 0, NULL },
+    version_1_5  = { 1, 5, 0, NULL },
+    version_1_6  = { 1, 6, 0, NULL },
+    version_1_7  = { 1, 7, 0, NULL },
+    version_1_8  = { 1, 8, 0, NULL },
+    version_1_15 = { 1, 15, 0, NULL };
+
+  switch (wc_format)
+    {
+      case  4: return &version_1_0;
+      case  8: return &version_1_4;
+      case  9: return &version_1_5;
+      case 10: return &version_1_6;
+      case 29: return &version_1_7;
+      case 31: return &version_1_8;
+      case 32: return &version_1_15;
+    }
+  return NULL;
+}
+
+const int *
+svn_client_get_wc_formats_supported(apr_pool_t *result_pool)
 {
-  static const svn_version_t version_1_8 = { 1, 8, 0, NULL };
-  static const svn_version_t version_1_15 = { 1, 15, 0, NULL };
-  static const svn_client_wc_format_t versions[] = {
-    { &version_1_8,   &version_1_15,  SVN_WC__SUPPORTED_VERSION },
-    { &version_1_15,  &version_1_15,  SVN_WC__VERSION           },
-    { NULL,           NULL,           0 }
+  static const int versions[] = {
+    SVN_WC__SUPPORTED_VERSION,
+    SVN_WC__VERSION,
+    0
   };
+
   return versions;
 }
 
 const svn_version_t *
+svn_client_oldest_wc_version(apr_pool_t *result_pool)
+{
+  /* NOTE: For consistency, always return the version of the client
+     that first introduced the format. */
+  static const svn_version_t version = { 1, 8, 0, NULL };
+  return &version;
+}
+
+const svn_version_t *
 svn_client_default_wc_version(apr_pool_t *result_pool)
 {
   /* NOTE: For consistency, always return the version of the client
@@ -227,6 +260,15 @@ svn_client_default_wc_version(apr_pool_t
   return &version;
 }
 
+const svn_version_t *
+svn_client_latest_wc_version(apr_pool_t *result_pool)
+{
+  /* NOTE: For consistency, always return the version of the client
+     that first introduced the format. */
+  static const svn_version_t version = { 1, 15, 0, NULL };
+  return &version;
+}
+
 /* Helper for upgrade_externals_from_properties: upgrades one external ITEM
    in EXTERNALS_PARENT. Uses SCRATCH_POOL for temporary allocations. */
 static svn_error_t *

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/info.c
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/info.c?rev=1898530&r1=1898529&r2=1898530&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/info.c (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/info.c Wed Mar  2 14:30:22 2022
@@ -105,8 +105,6 @@ build_info_for_node(svn_wc__info2_t **in
   tmpinfo->wc_info = wc_info;
 
   wc_info->copyfrom_rev = SVN_INVALID_REVNUM;
-  wc_info->wc_format_min = SVN_WC__SUPPORTED_VERSION;
-  wc_info->wc_format_max = SVN_WC__VERSION;
 
   SVN_ERR(svn_wc__db_get_format(&wc_info->wc_format,
                                 db, local_abspath, scratch_pool));

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc-metadata.sql
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc-metadata.sql?rev=1898530&r1=1898529&r2=1898530&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc-metadata.sql (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc-metadata.sql Wed Mar  2 14:30:22 2022
@@ -790,6 +790,7 @@ PRAGMA user_version = 33; */
  *
  *   * subversion/tests/libsvn_wc/wc-queries-test.c
  *     (schema_statements, create_memory_db)
+ *   * The implementation of svn_client_latest_wc_version()
  */
 
 

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc.h?rev=1898530&r1=1898529&r2=1898530&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc.h (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc.h Wed Mar  2 14:30:22 2022
@@ -170,7 +170,7 @@ extern "C" {
 
 /* The minimum WC version supported by the client.
    IMPORTANT: Update the implementation of svn_client_default_wc_version()
-              and svn_client_supported_wc_formats()
+              and svn_client_get_wc_formats_supported()
               whenever you change this value! */
 #define SVN_WC__SUPPORTED_VERSION 31
 

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/svn/cl.h?rev=1898530&r1=1898529&r2=1898530&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/svn/cl.h (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/svn/cl.h Wed Mar  2 14:30:22 2022
@@ -733,6 +733,10 @@ svn_cl__check_externals_failed_notify_wr
 svn_error_t *
 svn_cl__notifier_print_conflict_stats(void *baton, apr_pool_t *scratch_pool);
 
+/* Get whether a WC upgrade notification was received. */
+svn_boolean_t
+svn_cl__notifier_get_wc_was_upgraded(void *baton);
+
 
 /*** Log message callback stuffs. ***/
 

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/svn/help-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/svn/help-cmd.c?rev=1898530&r1=1898529&r2=1898530&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/svn/help-cmd.c (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/svn/help-cmd.c Wed Mar  2 14:30:22 2022
@@ -47,35 +47,18 @@ print_supported_wc_formats(svn_stringbuf
                            const char *prefix,
                            apr_pool_t *pool)
 {
-  const svn_client_wc_format_t *wc_formats
-    = svn_client_supported_wc_formats(pool, pool);
+  const int *wc_formats = svn_client_get_wc_formats_supported(pool);
   int i;
 
-  for (i = 0; wc_formats[i].version_min; i++)
+  for (i = 0; wc_formats[i]; i++)
     {
-      const svn_client_wc_format_t *v = &wc_formats[i];
-      const char *s;
-
-      if (v->version_min->major == v->version_min->major &&
-          v->version_min->minor == v->version_max->minor)
-        {
-          s = apr_psprintf(
-                pool,
-                _("%scompatible with Subversion v%d.%d (WC format %d)\n"),
-                prefix,
-                v->version_min->major, v->version_min->minor,
-                v->wc_format);
-        }
-      else
-        {
-          s = apr_psprintf(
-                pool,
-                _("%scompatible with Subversion v%d.%d to v%d.%d (WC format %d)\n"),
-                prefix,
-                v->version_min->major, v->version_min->minor,
-                v->version_max->major, v->version_max->minor,
-                v->wc_format);
-        }
+      const svn_version_t *ver
+        = svn_client_wc_version_from_format(wc_formats[i], pool);
+      const char *s
+        = apr_psprintf(
+            pool,
+            _("%sWC format %d, compatible with Subversion v%d.%d and newer\n"),
+            prefix, wc_formats[i], ver->major, ver->minor);
 
       svn_stringbuf_appendcstr(output, s);
     }

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/svn/info-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/svn/info-cmd.c?rev=1898530&r1=1898529&r2=1898530&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/svn/info-cmd.c (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/svn/info-cmd.c Wed Mar  2 14:30:22 2022
@@ -40,6 +40,7 @@
 #include "svn_dirent_uri.h"
 #include "svn_path.h"
 #include "svn_time.h"
+#include "svn_version.h"
 #include "svn_xml.h"
 #include "cl.h"
 
@@ -370,8 +371,7 @@ typedef enum
   info_item_depth,
   info_item_changelist,
   info_item_wc_format,
-  info_item_wc_format_min,
-  info_item_wc_format_max
+  info_item_wc_compatible_version
 } info_item_t;
 
 /* Mapping between option keywords and info_item_t. */
@@ -399,8 +399,8 @@ static const info_item_map_t info_item_m
     { SVN__STATIC_STRING("depth"),               info_item_depth },
     { SVN__STATIC_STRING("changelist"),          info_item_changelist },
     { SVN__STATIC_STRING("wc-format"),           info_item_wc_format },
-    { SVN__STATIC_STRING("wc-format-min"),       info_item_wc_format_min },
-    { SVN__STATIC_STRING("wc-format-max"),       info_item_wc_format_max },
+    { SVN__STATIC_STRING("wc-compatible-version"),
+                                                 info_item_wc_compatible_version },
   };
 
 static const apr_size_t info_item_map_len =
@@ -1251,16 +1251,15 @@ print_info_item(void *baton,
                                   target_path, pool));
       break;
 
-    case info_item_wc_format_min:
-      SVN_ERR(print_info_item_int((info->wc_info
-                                   ? info->wc_info->wc_format_min : -1),
-                                  target_path, pool));
-      break;
-
-    case info_item_wc_format_max:
-      SVN_ERR(print_info_item_int((info->wc_info
-                                   ? info->wc_info->wc_format_max : -1),
-                                  target_path, pool));
+    case info_item_wc_compatible_version:
+      {
+        const svn_version_t *wc_ver
+          = svn_client_wc_version_from_format(info->wc_info->wc_format, pool);
+        const char *s = apr_psprintf(pool, "%d.%d",
+                                     wc_ver->major,
+                                     wc_ver->minor);
+        SVN_ERR(print_info_item_string(s, target_path, pool));
+      }
       break;
 
     case info_item_changelist:

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/svn/notify.c
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/svn/notify.c?rev=1898530&r1=1898529&r2=1898530&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/svn/notify.c (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/svn/notify.c Wed Mar  2 14:30:22 2022
@@ -57,6 +57,7 @@ struct notify_baton
   svn_revnum_t progress_revision;
   svn_boolean_t had_print_error; /* Used to not keep printing error messages
                                     when we've already had one print error. */
+  svn_boolean_t wc_was_upgraded;
 
   svn_cl__conflict_stats_t *conflict_stats;
 
@@ -284,6 +285,14 @@ svn_cl__notifier_print_conflict_stats(vo
   return SVN_NO_ERROR;
 }
 
+svn_boolean_t
+svn_cl__notifier_get_wc_was_upgraded(void *baton)
+{
+  struct notify_baton *nb = baton;
+
+  return nb->wc_was_upgraded;
+}
+
 /* The body for notify() function with standard error handling semantic.
  * Handling of errors implemented at caller side. */
 static svn_error_t *
@@ -1145,6 +1154,7 @@ notify_body(struct notify_baton *nb,
 
     case svn_wc_notify_upgraded_path:
       SVN_ERR(svn_cmdline_printf(pool, _("Upgraded '%s'\n"), path_local));
+      nb->wc_was_upgraded = TRUE;
       break;
 
     case svn_wc_notify_url_redirect:

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/svn/svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/svn/svn.c?rev=1898530&r1=1898529&r2=1898530&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/svn/svn.c (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/svn/svn.c Wed Mar  2 14:30:22 2022
@@ -514,6 +514,12 @@ svn_cl__cmd_table_main[] =
      "Check out a working copy from a repository.\n"
      "usage: checkout URL[@REV]... [PATH]\n"
      "\n"), N_(
+     "  By default Subversion will create a WC format compatible with\n"
+     "  Subversion 1.8 and newer. To create a different WC format,\n"
+     "  use an option such as '--compatible-version=1.15'.\n"
+     "  The versions available are the same as in the 'upgrade' command.\n"
+     "  Use 'svn --version' to see the compatible versions supported.\n"
+     "\n"), N_(
      "  If specified, REV determines in which revision the URL is first\n"
      "  looked up.\n"
      "\n"), N_(
@@ -790,9 +796,9 @@ svn_cl__cmd_table_main[] =
                         "                             "
                         "   'wc-format'  TARGET's working copy format\n"
                         "                             "
-                        "   'wc-format-min'   oldest supported WC format\n"
+                        "   'wc-compatible-version'\n"
                         "                             "
-                        "   'wc-format-min'   newest supported WC format\n"
+                        "                first version supporting TARGET WC\n"
                         "                             "
                         "   'changelist' changelist of TARGET in WC")}},
   },
@@ -1909,6 +1915,14 @@ svn_cl__cmd_table_main[] =
      "Upgrade the metadata storage format for a working copy.\n"
      "usage: upgrade [WCPATH...]\n"
      "\n"), N_(
+     "  By default Subversion will upgrade the working copy to a version\n"
+     "  compatible with Subversion 1.8 and newer. To upgrade to a different\n"
+     "  version, use an option such as '--compatible-version=1.15'.\n"
+     "  The versions available are the same as in the 'checkout' command.\n"
+     "  Use 'svn --version' to see the compatible versions supported.\n"
+     "\n"), N_(
+     "  Only upgrades are supported, not downgrades.\n"
+     "\n"), N_(
      "  Local modifications are preserved.\n"
     )},
     { 'q', opt_compatible_version } },
@@ -2023,6 +2037,14 @@ add_commands(const svn_opt_subcommand_de
   svn_cl__cmd_table = cmds_new;
 }
 
+/* Parse OPT_ARG as a version number, into OPT_STATE->compatible_version.
+ *
+ * Ensure it is between the oldest and newest supported WC formats.
+ *
+ * WC formats are always defined by a X.Y.0 release. Quietly ignore any
+ * 'patch' and 'tag' fields in the requested version number, and set them to
+ * zero/null in the output.
+ */
 static svn_error_t *
 parse_compatible_version(svn_cl__opt_state_t* opt_state,
                          const char *opt_arg,
@@ -2031,71 +2053,45 @@ parse_compatible_version(svn_cl__opt_sta
   const char *utf8_opt_arg;
   svn_version_t *target;
 
-  /* Get the supported WC formats.  WC formats are always defined by a X.Y.0
-     release, and svn_client_supported_wc_formats() should return such
-     a value. */
-  const svn_client_wc_format_t *formats_supported
-    = svn_client_supported_wc_formats(result_pool, result_pool);
-  const svn_version_t *supported = formats_supported[0].version_min;
-  const svn_version_t *current = svn_client_version();
-  const svn_version_t latest = {current->major, current->minor, 0, NULL};
-
-  /* Double check that the oldest supported version is sane. */
-  SVN_ERR_ASSERT(supported->patch == 0);
-  SVN_ERR_ASSERT(svn_version__at_least(&latest,
-                                       supported->major,
-                                       supported->minor,
-                                       supported->patch));
+  const svn_version_t *oldest = svn_client_oldest_wc_version(result_pool);
+  const svn_version_t *latest = svn_client_latest_wc_version(result_pool);
+
+  /* Double check that the oldest and latest versions are sane. */
+  SVN_ERR_ASSERT(oldest->patch == 0);
+  SVN_ERR_ASSERT(latest->patch == 0);
+  SVN_ERR_ASSERT(svn_version__at_least(latest,
+                                       oldest->major, oldest->minor, 0));
 
   /* Parse the requested version. */
   SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, result_pool));
   SVN_ERR(svn_version__parse_version_string(&target, utf8_opt_arg,
                                             result_pool));
+  /* Quietly ignore 'patch' and 'tag' fields. */
+  target->patch = 0;
+  target->tag = NULL;
 
-  /* Check the earliest supported version. */
+  /* Check the oldest supported version. */
   if (!svn_version__at_least(target,
-                             supported->major,
-                             supported->minor,
-                             supported->patch))
+                             oldest->major, oldest->minor, 0))
     {
       return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-                               _("Cannot create working copies older "
-                                 "than version %d.%d.%d"),
-                               supported->major,
-                               supported->minor,
-                               supported->patch);
+                               _("Cannot make working copies compatible "
+                                 "with the requested version %d.%d; "
+                                 "the oldest supported version is %d.%d"),
+                               target->major, target->minor,
+                               oldest->major, oldest->minor);
     }
 
   /* Check the latest supported version. */
-  /* FIXME: ### Should we return an error here instead? It seems
-            ### more friendly to issue a warning and continue with
-            ### the latest supported format. */
-  if (svn_version__at_least(target,
-                            latest.major,
-                            latest.minor,
-                            latest.patch)
-      && (target->major != latest.major
-          || target->minor != latest.minor
-          || target->patch != latest.patch))
+  if (!svn_version__at_least(latest,
+                             target->major, target->minor, 0))
     {
-      svn_error_t *w1 = svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-                                          _("Cannot create working copies "
-                                            "for version %s"),
-                                          opt_arg);
-      svn_error_t *w2 = svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-                                          _("Creating working copy version "
-                                            "%d.%d instead"),
-                                          latest.major,
-                                          latest.minor);
-
-      svn_handle_warning2(stderr, w1, "svn: ");
-      svn_handle_warning2(stderr, w2, "svn: ");
-      svn_error_clear(w1);
-      svn_error_clear(w2);
-
-      target->major = latest.major;
-      target->minor = latest.minor;
-      target->patch = latest.patch;
+      return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+                               _("Cannot guarantee working copy compatibility "
+                                 "with the requested version %d.%d; "
+                                 "the latest supported version is %d.%d"),
+                               target->major, target->minor,
+                               latest->major, latest->minor);
     }
 
   opt_state->compatible_version = target;

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/svn/upgrade-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/svn/upgrade-cmd.c?rev=1898530&r1=1898529&r2=1898530&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/svn/upgrade-cmd.c (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/svn/upgrade-cmd.c Wed Mar  2 14:30:22 2022
@@ -32,6 +32,8 @@
 #include "svn_error_codes.h"
 #include "svn_error.h"
 #include "svn_path.h"
+#include "svn_version.h"
+#include "private/svn_subr_private.h"
 #include "cl.h"
 #include "svn_private_config.h"
 
@@ -50,6 +52,10 @@ svn_cl__upgrade(apr_getopt_t *os,
   apr_array_header_t *targets;
   apr_pool_t *iterpool;
   int i;
+  const svn_version_t *default_version
+    = svn_client_default_wc_version(scratch_pool);
+  const svn_version_t *latest_version
+    = svn_client_latest_wc_version(scratch_pool);
 
   SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
                                                       opt_state->targets,
@@ -76,5 +82,24 @@ svn_cl__upgrade(apr_getopt_t *os,
     }
   svn_pool_destroy(iterpool);
 
+  /* Remind the user they can upgrade further if:
+   *   - no upgrade was performed
+   *   - the user did not specify compatible-version explicitly
+   *   - a higher version is available. */
+  if (! svn_cl__notifier_get_wc_was_upgraded(ctx->notify_baton2)
+      && ! opt_state->compatible_version
+      && ! svn_version__at_least(default_version,
+                                 latest_version->major, latest_version->minor, 0)
+      && ! opt_state->quiet)
+    {
+      const char *msg
+        = _("Working copy is already at version %d.%d. "
+            "The highest version supported by this client can be "
+            "specified with '--compatible-version=%d.%d'.\n");
+      SVN_ERR(svn_cmdline_printf(scratch_pool, msg,
+                                 default_version->major, default_version->minor,
+                                 latest_version->major, latest_version->minor));
+    }
+
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/getopt_tests_data/svn--version--verbose_stdout
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/getopt_tests_data/svn--version--verbose_stdout?rev=1898530&r1=1898529&r2=1898530&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/getopt_tests_data/svn--version--verbose_stdout (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/getopt_tests_data/svn--version--verbose_stdout Wed Mar  2 14:30:22 2022
@@ -8,8 +8,8 @@ Subversion is open source software, see
 
 Supported working copy (WC) formats:
 
-* compatible with Subversion v1.8 to v1.15 (WC format 31)
-* compatible with Subversion v1.15 (WC format 32)
+* WC format 31, compatible with Subversion v1.8 and newer
+* WC format 32, compatible with Subversion v1.15 and newer
 
 The following repository access (RA) modules are available:
 

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/getopt_tests_data/svn--version_stdout
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/getopt_tests_data/svn--version_stdout?rev=1898530&r1=1898529&r2=1898530&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/getopt_tests_data/svn--version_stdout (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/getopt_tests_data/svn--version_stdout Wed Mar  2 14:30:22 2022
@@ -1,15 +1,15 @@
 svn, version 1.9.0-dev (under development)
    compiled Feb 26 2014, 15:15:42 on x86_64-unknown-openbsd5.5
 
-Copyright (C) 2014 The Apache Software Foundation.
+Copyright (C) 2012 The Apache Software Foundation.
 This software consists of contributions made by many people;
 see the NOTICE file for more information.
 Subversion is open source software, see http://subversion.apache.org/
 
 Supported working copy (WC) formats:
 
-* compatible with Subversion v1.8 to v1.15 (WC format 31)
-* compatible with Subversion v1.15 (WC format 32)
+* WC format 31, compatible with Subversion v1.8 and newer
+* WC format 32, compatible with Subversion v1.15 and newer
 
 The following repository access (RA) modules are available:
 

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/svntest/main.py
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/svntest/main.py?rev=1898530&r1=1898529&r2=1898530&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/svntest/main.py Wed Mar  2 14:30:22 2022
@@ -801,7 +801,9 @@ def copy_trust(dst_cfgdir, src_cfgdir):
     shutil.copy(os.path.join(src_ssl_dir, f), os.path.join(dst_ssl_dir, f))
 
 def _with_wc_format_version(args):
-  if '--wc-format-version' in args or options.wc_format_version is None:
+  if '--compatible-version' in args \
+      or any(one_arg.startswith('--compatible-version=') for one_arg in args) \
+      or options.wc_format_version is None:
     return args
   non_opt_args = [a for a in args if not str(a).startswith('-')]
   if non_opt_args:
@@ -1746,15 +1748,22 @@ def is_httpd_authz_provider_enabled():
 def is_remote_http_connection_allowed():
   return options.allow_remote_http_connection
 
-def wc_format():
-  ver = (options.wc_format_version or DEFAULT_COMPATIBLE_VERSION)
+def wc_format(ver=None):
+  """Return the WC format number used by Subversion version VER.
+
+  VER should be a version string such as '1.15' or '1.15.0' or '1.15.0-beta2'.
+
+  If omitted, the format number of new working copies, as expected to be
+  created by 'svn checkout' without '--compatible-version', is returned.
+  """
+  if not ver:
+    ver = (options.wc_format_version or DEFAULT_COMPATIBLE_VERSION)
   minor = int(ver.split('.')[1])
   if minor >= 15 and minor <= SVN_VER_MINOR:
     return 32
   if minor >= 8 and minor <= 14:
     return 31
-  raise Exception("Unrecognized wc_format_version '%s'" %
-                  options.wc_format_version)
+  raise Exception("Unrecognized version number '%s'" % (ver,))
 
 
 ######################################################################

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/upgrade_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/upgrade_tests.py?rev=1898530&r1=1898529&r2=1898530&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/upgrade_tests.py (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/upgrade_tests.py Wed Mar  2 14:30:22 2022
@@ -290,10 +290,33 @@ def basic_upgrade(sbox):
   check_format(sbox, get_current_format())
 
   # Now check the contents of the working copy
+  # This verification is repeated below.
   expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 1)
   run_and_verify_status_no_server(sbox.wc_dir, expected_status)
   check_pristine(sbox, ['iota', 'A/mu'])
 
+  # Upgrade again to the latest format.
+  #
+  # This may or may not be a no-op, depending on whether the test suite was
+  # launched with --wc-format-version / WC_FORMAT_VERSION set a version that
+  # uses the same format as SVN_VER_MAJOR.SVN_VER_MINOR.
+  to_version = svntest.main.svn_wc__max_supported_format_version()
+  if svntest.main.wc_format() == svntest.main.wc_format(to_version):
+    # Upgrade is a no-op
+    expected_stdout = []
+  else:
+    # Upgrade is not a no-op
+    expected_stdout = "Upgraded '.*'"
+  svntest.actions.run_and_verify_svn(expected_stdout, [],
+                                     'upgrade',
+                                     '--compatible-version',
+                                     to_version, sbox.wc_dir)
+  check_format(sbox, svntest.main.wc_format(to_version))
+
+  # Repeat the same verification as above
+  run_and_verify_status_no_server(sbox.wc_dir, expected_status)
+  check_pristine(sbox, ['iota', 'A/mu'])
+
 def upgrade_with_externals(sbox):
   "upgrade with externals"