Author: brane
Date: Wed Jan 14 13:36:52 2026
New Revision: 1931314

Log:
On the better-pristines branch: Move all knowledge of mapping between
working copy formats and Subversion versions into libsvn_wc. Having them
in two places was slightly unmaintainable if the format numberw changed.

* subversion/include/private/svn_wc_private.h: Include svn_version.h.
  (svn_wc__version_string_from_format): Update the docstring.
  (svn_wc__version_info_t,
   svn_wc__version_info_from_format): New.

* subversion/libsvn_wc/wc.h
  (SVN_WC__VERSION): Note dependents in the docstring.
  (SVN_WC__SUPPORTED_VERSION): Likewise.
  (SVN_WC__VERSIONS_ALSO_RAN): New; list of other supported format versions.

* subversion/libsvn_wc/upgrade.c
  (version_info_null..version_info_1_16): New constants with version
   strings and related version numbers.
  (svn_wc__version_info_from_format): This is the single format->version
   mapping, using the new version_info_* static data.
  (svn_wc__version_string_from_format): Use the info returned by
   svn_wc__version_info_from_format().

* subversion/libsvn_client/upgrade.c
  (svn_client_wc_version_from_format): Delete the local version mapping
   and use svn_wc__version_info_from_format() instead.
  (svn_client_get_wc_formats_supported): Extend the versions array with
   SVN_WC__VERSIONS_ALSO_RAN because we need more than two format versions.
  (svn_client_oldest_wc_version,
   svn_client_default_wc_version,
   svn_client_latest_wc_version,
   svn_client__compatible_wc_version_optional_pristine): Use the data
   returned by svn_wc__version_info_from_format(), instead of hard-
   coded, copy-pasted versions. This eliminates the need to update
   these functions when supported format numbers change.

* subversion/tests/cmdline/svntest/main.py
  (wc_format): Reorder the version number checks and support format 33.

Modified:
   
subversion/branches/better-pristines/subversion/include/private/svn_wc_private.h
   subversion/branches/better-pristines/subversion/libsvn_client/upgrade.c
   subversion/branches/better-pristines/subversion/libsvn_wc/upgrade.c
   subversion/branches/better-pristines/subversion/libsvn_wc/wc.h
   subversion/branches/better-pristines/subversion/tests/cmdline/svntest/main.py

Modified: 
subversion/branches/better-pristines/subversion/include/private/svn_wc_private.h
==============================================================================
--- 
subversion/branches/better-pristines/subversion/include/private/svn_wc_private.h
    Wed Jan 14 12:30:22 2026        (r1931313)
+++ 
subversion/branches/better-pristines/subversion/include/private/svn_wc_private.h
    Wed Jan 14 13:36:52 2026        (r1931314)
@@ -39,6 +39,7 @@
 
 #include "svn_subst.h"
 #include "svn_types.h"
+#include "svn_version.h"
 #include "svn_wc.h"
 #include "private/svn_diff_tree.h"
 
@@ -2200,10 +2201,27 @@ svn_wc__format_from_version(int *format,
  *
  * ### It's not ideal to encode this sort of knowledge in this low-level
  * library.  On the other hand, it doesn't need to be updated often and
- * should be easily found when it does need to be updated.  */
+ * should be easily found when it does need to be updated.
+ *
+ * ### However, it's even less ideal to have this sort of knowledge
+ * in two places, both libsvn_wc and libsvn_client. Therefores, since
+ * libsvn_wc needs this info, we'll keep it there.
+ */
 const char *
 svn_wc__version_string_from_format(int wc_format);
 
+/* As above, but return a tuple containing the string and an
+   svn_version_t. If the returned tuple has a NULL string, the
+   format is not known. */
+typedef struct svn_wc__version_info svn_wc__version_info_t;
+struct svn_wc__version_info
+{
+  const char *text;
+  svn_version_t version;
+};
+const svn_wc__version_info_t *
+svn_wc__version_info_from_format(int wc_format);
+
 /**
  * Return true iff @a format is a supported format.
  */

Modified: 
subversion/branches/better-pristines/subversion/libsvn_client/upgrade.c
==============================================================================
--- subversion/branches/better-pristines/subversion/libsvn_client/upgrade.c     
Wed Jan 14 12:30:22 2026        (r1931313)
+++ subversion/branches/better-pristines/subversion/libsvn_client/upgrade.c     
Wed Jan 14 13:36:52 2026        (r1931314)
@@ -251,25 +251,12 @@ 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 };
+  const svn_wc__version_info_t *const version_info =
+    svn_wc__version_info_from_format(wc_format);
+
+  if (version_info->text != NULL)
+    return &version_info->version;
 
-  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;
 }
 
@@ -278,6 +265,7 @@ svn_client_get_wc_formats_supported(apr_
 {
   static const int versions[] = {
     SVN_WC__SUPPORTED_VERSION,
+    SVN_WC__VERSIONS_ALSO_RAN,
     SVN_WC__VERSION,
     0
   };
@@ -288,10 +276,14 @@ svn_client_get_wc_formats_supported(apr_
 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_wc__version_info_t *const version_info =
+    svn_wc__version_info_from_format(SVN_WC__SUPPORTED_VERSION);
+
+  /* NOTE: This can be the "null" version "0.0.0" and that's an
+           unrecoverable programming error. */
+  SVN_ERR_ASSERT_NO_RETURN(version_info->text != NULL);
+
+  return &version_info->version;
 }
 
 svn_error_t *
@@ -302,7 +294,7 @@ svn_client_default_wc_version(const svn_
 {
   svn_config_t *config;
   const char *value;
-  svn_version_t *version;
+  const svn_version_t *version;
 
   if (ctx->config)
     config = svn_hash_gets(ctx->config, SVN_CONFIG_CATEGORY_CONFIG);
@@ -315,17 +307,19 @@ svn_client_default_wc_version(const svn_
                  NULL);
   if (value)
     {
-      SVN_ERR(svn_version__parse_version_string(&version, value, result_pool));
+      svn_version_t *mutable;
+      SVN_ERR(svn_version__parse_version_string(&mutable, value, result_pool));
+      version = mutable;
     }
   else
     {
-      /* NOTE: For consistency, always return the version of the client
-         that first introduced the format. */
-      version = apr_pcalloc(result_pool, sizeof(*version));
-      version->major = 1;
-      version->minor = 8;
-      version->patch = 0;
-      version->tag = NULL;
+      const svn_wc__version_info_t *const version_info =
+        svn_wc__version_info_from_format(SVN_WC__SUPPORTED_VERSION);
+
+      /* See note in svn_client_oldest_wc_version(), above. */
+      SVN_ERR_ASSERT(version_info->text != NULL);
+
+      version = &version_info->version;
     }
 
   *version_p = version;
@@ -335,19 +329,25 @@ svn_client_default_wc_version(const svn_
 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;
+  const svn_wc__version_info_t *const version_info =
+    svn_wc__version_info_from_format(SVN_WC__VERSION);
+
+  /* See note in svn_client_oldest_wc_version(), above. */
+  SVN_ERR_ASSERT_NO_RETURN(version_info->text != NULL);
+
+  return &version_info->version;
 }
 
 const svn_version_t *
 svn_client__compatible_wc_version_optional_pristine(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;
+  const svn_wc__version_info_t *const version_info =
+    svn_wc__version_info_from_format(SVN_WC__HAS_OPTIONAL_PRISTINE);
+
+  /* See note in svn_client_oldest_wc_version(), above. */
+  SVN_ERR_ASSERT_NO_RETURN(version_info->text != NULL);
+
+  return &version_info->version;
 }
 
 /* Helper for upgrade_externals_from_properties: upgrades one external ITEM

Modified: subversion/branches/better-pristines/subversion/libsvn_wc/upgrade.c
==============================================================================
--- subversion/branches/better-pristines/subversion/libsvn_wc/upgrade.c Wed Jan 
14 12:30:22 2026        (r1931313)
+++ subversion/branches/better-pristines/subversion/libsvn_wc/upgrade.c Wed Jan 
14 13:36:52 2026        (r1931314)
@@ -1633,24 +1633,49 @@ upgrade_to_wcng(void **dir_baton,
   return SVN_NO_ERROR;
 }
 
-const char *
-svn_wc__version_string_from_format(int wc_format)
+static const svn_wc__version_info_t
+  version_info_null = {   NULL , { 0, 0,  0, NULL }},
+  version_info_1_0  = {"<=1.3",  { 1, 0,  0, NULL }},
+  version_info_1_4  = {  "1.4",  { 1, 4,  0, NULL }},
+  version_info_1_5  = {  "1.5",  { 1, 5,  0, NULL }},
+  version_info_1_6  = {  "1.6",  { 1, 6,  0, NULL }},
+  version_info_1_7  = {  "1.7",  { 1, 7,  0, NULL }},
+  version_info_1_8  = {  "1.8",  { 1, 8,  0, NULL }},
+  version_info_1_15 = {  "1.15", { 1, 15, 0, NULL }},
+  version_info_1_16 = {  "1.16", { 1, 16, 0, NULL }};
+
+const svn_wc__version_info_t *
+svn_wc__version_info_from_format(int wc_format)
 {
+
   switch (wc_format)
     {
-      case 4: return "<=1.3";
-      case 8: return "1.4";
-      case 9: return "1.5";
-      case 10: return "1.6";
-      case SVN_WC__WC_NG_VERSION: return "1.7";
-      case 29: return "1.7";
-      case 31: return "1.8";
-      case 32: return "1.15";
-      case 33: return "1.16";
+      case 4: return &version_info_1_0;
+      case 8: return &version_info_1_4;
+      case 9: return &version_info_1_5;
+      case 10: return &version_info_1_6;
+      case SVN_WC__WC_NG_VERSION: return &version_info_1_7;
+      case 29: return &version_info_1_7;
+      case 31: return &version_info_1_8;
+      case 32: return &version_info_1_15;
+      case 33: return &version_info_1_16;
     }
+  return &version_info_null;
+}
+
+const char *
+svn_wc__version_string_from_format(int wc_format)
+{
+  const svn_wc__version_info_t *const version_info =
+    svn_wc__version_info_from_format(wc_format);
+
+  if (version_info->text != NULL)
+    return version_info->text;
+
   return _("(unreleased development version)");
 }
 
+
 svn_error_t *
 svn_wc__format_from_version(int *format,
                             const svn_version_t* version,

Modified: subversion/branches/better-pristines/subversion/libsvn_wc/wc.h
==============================================================================
--- subversion/branches/better-pristines/subversion/libsvn_wc/wc.h      Wed Jan 
14 12:30:22 2026        (r1931313)
+++ subversion/branches/better-pristines/subversion/libsvn_wc/wc.h      Wed Jan 
14 13:36:52 2026        (r1931314)
@@ -176,18 +176,25 @@ extern "C" {
  *
  * @see svn_wc__max_supported_format()
  */
+/* IMPORTANT: Update SVN_WC__VERSIONS_ALSO_RAN (below)
+              and svntest.main.wc_format()
+              whenever you change this value! */
 #define SVN_WC__VERSION 33
 
 /* The minimum WC version supported by the client.
  *
  * @see svn_wc__min_supported_format()
  */
-/* IMPORTANT: Update the implementation of svn_client_default_wc_version()
-              and svn_client_get_wc_formats_supported()
-              and svntest.main.wc_format()
-              whenever you change this value! */
+/* IMPORTANT: See IMPORTANT at SVN_WC__VERSION (above). */
 #define SVN_WC__SUPPORTED_VERSION 31
 
+/* All the WC formats between SVN_WC__SUPPORTED_VERSION and SVN_WC__VERSION
+ * that we also support, rendered as a list that can be used as a constant
+ * array initializer. Must not include the lower and upper bounds. Sort the
+ * format numbers ascending by value.
+ */
+#define SVN_WC__VERSIONS_ALSO_RAN 32  /* 33, 34, 35 [no trailing comma] */
+
 /* The default WC version that the Subversion library should create
  * (or upgrade to) when not otherwise specified. */
 #define SVN_WC__DEFAULT_VERSION SVN_WC__SUPPORTED_VERSION

Modified: 
subversion/branches/better-pristines/subversion/tests/cmdline/svntest/main.py
==============================================================================
--- 
subversion/branches/better-pristines/subversion/tests/cmdline/svntest/main.py   
    Wed Jan 14 12:30:22 2026        (r1931313)
+++ 
subversion/branches/better-pristines/subversion/tests/cmdline/svntest/main.py   
    Wed Jan 14 13:36:52 2026        (r1931314)
@@ -1774,10 +1774,13 @@ def wc_format(ver=None):
   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:
+
+  if 8 <= minor and minor <= 14:
     return 31
+  if minor == 15:
+    return 32
+  if minor <= SVN_VER_MINOR:
+    return 33
   raise Exception("Unrecognized version number '%s'" % (ver,))
 
 ######################################################################

Reply via email to