Author: kotkov
Date: Thu Mar  2 11:09:48 2023
New Revision: 1907964

URL: http://svn.apache.org/viewvc?rev=1907964&view=rev
Log:
Add a new `compatible-version` config option.

This option sets the default working copy format version, allowing users to
configure the default wc compatibility level globally.  Newly created and
upgraded working copies will by default be compatible with the specified
Subversion version.

In the test suite, use the new config option for the customized runs with the
--wc-format-version argument, instead of manually inserting the corresponding
--compatible-version argument during `svn checkout` and `svn upgrade` calls.

* subversion/include/svn_config.h
  (SVN_CONFIG_OPTION_COMPATIBLE_VERSION): New.

* subversion/libsvn_subr/config_file.c
  (svn_config_ensure): Add new config option.

* subversion/include/svn_client.h
  (svn_client_default_wc_version): Now accepts an svn_client_ctx_t.
  (svn_client_checkout4,
   svn_client_checkout3,
   svn_client_upgrade2,
   svn_client_upgrade): Tweak the docstrings so that they would lead to
   the svn_client_default_wc_version(), as opposed to providing a custom
   description of the same concept.

* subversion/libsvn_client/upgrade.c
  (): Include svn_hash.h and svn_subr_private.h.
  (svn_client_default_wc_version): Check if we have a specific version in
   the config or use the default.
  (svn_client_upgrade2): Call svn_client_default_wc_version().

* subversion/libsvn_client/checkout.c
  (svn_client__checkout_internal):
   Adjust calling site of svn_client_default_wc_version().

* subversion/svn/upgrade-cmd.c
  (svn_cl__upgrade): Adjust calling site of svn_client_default_wc_version().

* subversion/tests/cmdline/svntest/main.py
  (create_config_dir): Accept the wc_format_version and translate it into
   an appropriate config value.
  (execute_tests): Adjust call to create_config_dir().
  (_with_wc_format_version): Remove.
  (run_svn): Don't use the _with_wc_format_version() function.

* subversion/tests/cmdline/checkout_tests.py
  (checkout_compatible_version_arg,
   checkout_compatible_version_config): New tests.
  (test_list): Run new tests.

* subversion/tests/cmdline/upgrade_tests.py
  (upgrade_compatible_version_arg,
   upgrade_compatible_version_config): New tests.
  (test_list): Run new tests.

Modified:
    subversion/trunk/subversion/include/svn_client.h
    subversion/trunk/subversion/include/svn_config.h
    subversion/trunk/subversion/libsvn_client/checkout.c
    subversion/trunk/subversion/libsvn_client/upgrade.c
    subversion/trunk/subversion/libsvn_subr/config_file.c
    subversion/trunk/subversion/svn/upgrade-cmd.c
    subversion/trunk/subversion/tests/cmdline/checkout_tests.py
    subversion/trunk/subversion/tests/cmdline/svntest/main.py
    subversion/trunk/subversion/tests/cmdline/upgrade_tests.py

Modified: subversion/trunk/subversion/include/svn_client.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_client.h?rev=1907964&r1=1907963&r2=1907964&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_client.h (original)
+++ subversion/trunk/subversion/include/svn_client.h Thu Mar  2 11:09:48 2023
@@ -1242,7 +1242,7 @@ svn_client_args_to_target_array(apr_arra
  *              obstructing items.
  * @param[in] wc_format_version is the version number of the oldest Subversion
  *              client with which the created working copy should be 
compatible;
- *              @c NULL means the library's version.
+ *              @c NULL means the default version.
  *              See svn_client_default_wc_version(),
  *              svn_client_get_wc_formats_supported().
  * @param[in] store_pristine  If #svn_tristate_true, the pristine contents of
@@ -1284,8 +1284,8 @@ svn_client_checkout4(svn_revnum_t *resul
                      apr_pool_t *pool);
 
 /**
- * Similar to svn_client_checkout4() but always creates the newest
- * supported working copy format.
+ * Similar to svn_client_checkout4() but with @a wc_format_version set
+ * to @c NULL.
  *
  * @since New in 1.5.
  * @deprecated Provided for backward compatibility with the 1.10 API.
@@ -4405,7 +4405,7 @@ svn_client_cleanup(const char *dir,
  * copies from any older format to a WC metadata storage
  * format supported by Subversion @a wc_format_version.
  *
- * If @a wc_format_version is @c NULL, the library's version is used.
+ * If @a wc_format_version is @c NULL, the default version is used.
  *
  * @a wcroot_dir is the path to the WC root.
  *
@@ -4423,8 +4423,7 @@ svn_client_upgrade2(const char *wcroot_d
                     apr_pool_t *scratch_pool);
 
 /**
- * Like svn_client_upgrade2(), but always upgrades to the newest
- * supported format.
+ * Like svn_client_upgrade2(), but with @a wc_format_version set to @c NULL.
  *
  * @since New in 1.7.
  * @deprecated Provided for backward compatibility with the 1.14 API.
@@ -4445,13 +4444,17 @@ 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.
+ * Set @a *version_p to the version of a working copy format that should
+ * be used by default for @a ctx, according to its configuration.
+ * Allocate the result in @a result_pool.
  *
  * @since New in 1.15.
  */
-const svn_version_t *
-svn_client_default_wc_version(apr_pool_t *result_pool);
+svn_error_t *
+svn_client_default_wc_version(const svn_version_t **version_p,
+                              svn_client_ctx_t *ctx,
+                              apr_pool_t *result_pool,
+                              apr_pool_t *scratch_pool);
 
 /**
  * Returns the first version that supported the library's latest

Modified: subversion/trunk/subversion/include/svn_config.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_config.h?rev=1907964&r1=1907963&r2=1907964&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_config.h (original)
+++ subversion/trunk/subversion/include/svn_config.h Thu Mar  2 11:09:48 2023
@@ -171,6 +171,8 @@ typedef struct svn_config_t svn_config_t
 #define SVN_CONFIG_OPTION_SQLITE_EXCLUSIVE_CLIENTS  "exclusive-locking-clients"
 /** @since New in 1.9. */
 #define SVN_CONFIG_OPTION_SQLITE_BUSY_TIMEOUT       "busy-timeout"
+/** @since New in 1.15. */
+#define SVN_CONFIG_OPTION_COMPATIBLE_VERSION        "compatible-version"
 /** @} */
 
 /** @name Repository conf directory configuration files strings

Modified: subversion/trunk/subversion/libsvn_client/checkout.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/checkout.c?rev=1907964&r1=1907963&r2=1907964&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/checkout.c (original)
+++ subversion/trunk/subversion/libsvn_client/checkout.c Thu Mar  2 11:09:48 
2023
@@ -130,7 +130,8 @@ svn_client__checkout_internal(svn_revnum
         {
           /* A NULL wc_format_version translates to the minimum compatible
              version. */
-          target_format_version = svn_client_default_wc_version(scratch_pool);
+          SVN_ERR(svn_client_default_wc_version(&target_format_version, ctx,
+                                                scratch_pool, scratch_pool));
 
           if (!target_store_pristine)
             {

Modified: subversion/trunk/subversion/libsvn_client/upgrade.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/upgrade.c?rev=1907964&r1=1907963&r2=1907964&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/upgrade.c (original)
+++ subversion/trunk/subversion/libsvn_client/upgrade.c Thu Mar  2 11:09:48 2023
@@ -36,11 +36,13 @@
 #include "svn_pools.h"
 #include "svn_props.h"
 #include "svn_version.h"
+#include "svn_hash.h"
 
 #include "client.h"
 
 #include "svn_private_config.h"
 #include "private/svn_wc_private.h"
+#include "private/svn_subr_private.h"
 #include "../libsvn_wc/wc.h"
 
 
@@ -197,6 +199,12 @@ svn_client_upgrade2(const char *path,
 {
   int wc_format;
 
+  if (!wc_format_version)
+    {
+      SVN_ERR(svn_client_default_wc_version(&wc_format_version, ctx,
+                                            scratch_pool, scratch_pool));
+    }
+
   SVN_ERR(svn_wc__format_from_version(&wc_format,
                                       wc_format_version,
                                       scratch_pool));
@@ -251,13 +259,42 @@ svn_client_oldest_wc_version(apr_pool_t
   return &version;
 }
 
-const svn_version_t *
-svn_client_default_wc_version(apr_pool_t *result_pool)
+svn_error_t *
+svn_client_default_wc_version(const svn_version_t **version_p,
+                              svn_client_ctx_t *ctx,
+                              apr_pool_t *result_pool,
+                              apr_pool_t *scratch_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;
+  svn_config_t *config;
+  const char *value;
+  svn_version_t *version;
+
+  if (ctx->config)
+    config = svn_hash_gets(ctx->config, SVN_CONFIG_CATEGORY_CONFIG);
+  else
+    config = NULL;
+
+  svn_config_get(config, &value,
+                 SVN_CONFIG_SECTION_WORKING_COPY,
+                 SVN_CONFIG_OPTION_COMPATIBLE_VERSION,
+                 NULL);
+  if (value)
+    {
+      SVN_ERR(svn_version__parse_version_string(&version, value, result_pool));
+    }
+  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;
+    }
+
+  *version_p = version;
+  return SVN_NO_ERROR;
 }
 
 const svn_version_t *

Modified: subversion/trunk/subversion/libsvn_subr/config_file.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/config_file.c?rev=1907964&r1=1907963&r2=1907964&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/config_file.c (original)
+++ subversion/trunk/subversion/libsvn_subr/config_file.c Thu Mar  2 11:09:48 
2023
@@ -1553,6 +1553,10 @@ svn_config_ensure(const char *config_dir
         "### returning an error.  The default is 10000, i.e. 10 seconds."    NL
         "### Longer values may be useful when exclusive locking is enabled." NL
         "# busy-timeout = 10000"                                             NL
+        "### Set the default working copy format version.  Newly created"    NL
+        "### and upgraded working copies will by default be compatible with" NL
+        "### the specified Subversion version."                              NL
+        "# compatible-version = 1.8"                                         NL
         ;
 
       err = svn_io_file_open(&f, path,

Modified: subversion/trunk/subversion/svn/upgrade-cmd.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/upgrade-cmd.c?rev=1907964&r1=1907963&r2=1907964&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/upgrade-cmd.c (original)
+++ subversion/trunk/subversion/svn/upgrade-cmd.c Thu Mar  2 11:09:48 2023
@@ -52,10 +52,12 @@ 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);
+  const svn_version_t *default_version;
+  const svn_version_t *latest_version;
+
+  SVN_ERR(svn_client_default_wc_version(&default_version, ctx,
+                                        scratch_pool, scratch_pool));
+  latest_version = svn_client_latest_wc_version(scratch_pool);
 
   SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
                                                       opt_state->targets,

Modified: subversion/trunk/subversion/tests/cmdline/checkout_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/checkout_tests.py?rev=1907964&r1=1907963&r2=1907964&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/checkout_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/checkout_tests.py Thu Mar  2 
11:09:48 2023
@@ -1185,6 +1185,36 @@ def checkout_wc_from_drive(sbox):
     # cleanup the virtual drive
     subprocess.call(['subst', '/D', drive +':'])
 
+def checkout_compatible_version_arg(sbox):
+  "checkout with compatible-version from arg"
+
+  sbox.build(empty=True, create_wc=False)
+  expected_output = svntest.wc.State(sbox.wc_dir, {})
+  expected_disk = svntest.wc.State('', {})
+  svntest.actions.run_and_verify_checkout(
+    sbox.repo_url, sbox.wc_dir, expected_output, expected_disk, [],
+    '--compatible-version', '1.15')
+
+  svntest.actions.run_and_verify_svn(
+    ['1.15'], [],
+    'info', '--show-item=wc-compatible-version', '--no-newline',
+    sbox.wc_dir)
+
+def checkout_compatible_version_config(sbox):
+  "checkout with compatible-version from config"
+
+  sbox.build(empty=True, create_wc=False)
+  expected_output = svntest.wc.State(sbox.wc_dir, {})
+  expected_disk = svntest.wc.State('', {})
+  svntest.actions.run_and_verify_checkout(
+    sbox.repo_url, sbox.wc_dir, expected_output, expected_disk, [],
+    '--config-option', 'config:working-copy:compatible-version=1.15')
+
+  svntest.actions.run_and_verify_svn(
+    ['1.15'], [],
+    'info', '--show-item=wc-compatible-version', '--no-newline',
+    sbox.wc_dir)
+
 #----------------------------------------------------------------------
 
 # list all tests here, starting with None:
@@ -1202,7 +1232,9 @@ test_list = [ None,
               checkout_peg_rev,
               checkout_peg_rev_date,
               co_with_obstructing_local_adds,
-              checkout_wc_from_drive
+              checkout_wc_from_drive,
+              checkout_compatible_version_arg,
+              checkout_compatible_version_config
             ]
 
 if __name__ == "__main__":

Modified: subversion/trunk/subversion/tests/cmdline/svntest/main.py
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/svntest/main.py?rev=1907964&r1=1907963&r2=1907964&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/trunk/subversion/tests/cmdline/svntest/main.py Thu Mar  2 
11:09:48 2023
@@ -691,7 +691,7 @@ def run_command_stdin(command, error_exp
 
 def create_config_dir(cfgdir, config_contents=None, server_contents=None,
                       ssl_cert=None, ssl_url=None, http_proxy=None,
-                      exclusive_wc_locks=None):
+                      exclusive_wc_locks=None, wc_format_version=None):
   "Create config directories and files"
 
   # config file names
@@ -711,12 +711,14 @@ password-stores =
 
 [miscellany]
 interactive-conflicts = false
-"""
-    if exclusive_wc_locks:
-      config_contents += """
+
 [working-copy]
-exclusive-locking = true
 """
+    if exclusive_wc_locks:
+      config_contents += "exclusive-locking = true\n"
+    if wc_format_version:
+      config_contents += ("compatible-version = %s\n" % wc_format_version)
+
   # define default server file contents if none provided
   if server_contents is None:
     http_library_str = ""
@@ -812,18 +814,6 @@ def _with_store_pristine(args):
       return args + ('--store-pristine', options.store_pristine)
   return args
 
-def _with_wc_format_version(args):
-  if '--compatible-version' in args \
-      or any(str(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:
-    subcommand = non_opt_args[0]
-    if subcommand in ['co', 'checkout', 'upgrade']:
-      return args + ('--compatible-version', options.wc_format_version)
-  return args
-
 def _with_config_dir(args):
   if '--config-dir' in args:
     return args
@@ -859,8 +849,8 @@ def run_svn(error_expected, *varargs):
   you're just checking that something does/doesn't come out of
   stdout/stderr, you might want to use actions.run_and_verify_svn()."""
   return run_command(svn_binary, error_expected, False,
-                     *(_with_store_pristine(_with_wc_format_version(
-                       _with_auth(_with_config_dir(varargs))))))
+                     *(_with_store_pristine(
+                       _with_auth(_with_config_dir(varargs)))))
 
 # For running svnadmin.  Ignores the output.
 def run_svnadmin(*varargs):
@@ -2671,7 +2661,8 @@ def execute_tests(test_list, serial_only
                         ssl_cert=options.ssl_cert,
                         ssl_url=options.test_area_url,
                         http_proxy=options.http_proxy,
-                        exclusive_wc_locks=options.exclusive_wc_locks)
+                        exclusive_wc_locks=options.exclusive_wc_locks,
+                        wc_format_version=options.wc_format_version)
 
       # Setup the pristine repositories
       svntest.actions.setup_pristine_repositories()

Modified: subversion/trunk/subversion/tests/cmdline/upgrade_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/upgrade_tests.py?rev=1907964&r1=1907963&r2=1907964&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/upgrade_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/upgrade_tests.py Thu Mar  2 
11:09:48 2023
@@ -1604,6 +1604,52 @@ def upgrade_latest_format(sbox):
   # and cannot be downgraded to version 1.8 (format 31)
   svntest.actions.run_and_verify_svn(None, [], 'upgrade', sbox.wc_dir)
 
+def upgrade_compatible_version_arg(sbox):
+  "upgrade with compatible-version from arg"
+
+  sbox.build(empty=True, create_wc=False)
+  expected_output = svntest.wc.State(sbox.wc_dir, {})
+  expected_disk = svntest.wc.State('', {})
+  svntest.actions.run_and_verify_checkout(
+    sbox.repo_url, sbox.wc_dir, expected_output, expected_disk, [],
+    '--compatible-version', '1.8', '--store-pristine=yes')
+  svntest.actions.run_and_verify_svn(
+    ['1.8'], [],
+    'info', '--show-item=wc-compatible-version', '--no-newline',
+    sbox.wc_dir)
+
+  svntest.actions.run_and_verify_svn(
+    None, [], 'upgrade',
+    '--compatible-version', '1.15',
+    sbox.wc_dir)
+  svntest.actions.run_and_verify_svn(
+    ['1.15'], [],
+    'info', '--show-item=wc-compatible-version', '--no-newline',
+    sbox.wc_dir)
+
+def upgrade_compatible_version_config(sbox):
+  "upgrade with compatible-version from config"
+
+  sbox.build(empty=True, create_wc=False)
+  expected_output = svntest.wc.State(sbox.wc_dir, {})
+  expected_disk = svntest.wc.State('', {})
+  svntest.actions.run_and_verify_checkout(
+    sbox.repo_url, sbox.wc_dir, expected_output, expected_disk, [],
+    '--compatible-version', '1.8', '--store-pristine=yes')
+  svntest.actions.run_and_verify_svn(
+    ['1.8'], [],
+    'info', '--show-item=wc-compatible-version', '--no-newline',
+    sbox.wc_dir)
+
+  svntest.actions.run_and_verify_svn(
+    None, [], 'upgrade',
+    '--config-option', 'config:working-copy:compatible-version=1.15',
+    sbox.wc_dir)
+  svntest.actions.run_and_verify_svn(
+    ['1.15'], [],
+    'info', '--show-item=wc-compatible-version', '--no-newline',
+    sbox.wc_dir)
+
 ########################################################################
 # Run the tests
 
@@ -1661,6 +1707,8 @@ test_list = [ None,
               auto_analyze,
               upgrade_1_0_with_externals,
               upgrade_latest_format,
+              upgrade_compatible_version_arg,
+              upgrade_compatible_version_config,
              ]
 
 


Reply via email to