Author: kotkov
Date: Thu Mar 2 11:10:34 2023
New Revision: 1907965
URL: http://svn.apache.org/viewvc?rev=1907965&view=rev
Log:
Fix an issue where calling `svn upgrade` without arguments for a 1.15-format
working copy resulted in an error:
$ svn checkout --compatible-version=1.15 wc
$ svn upgrade wc
$ svn: E155021: Working copy '…' is already at version 1.15 (format 32)
and cannot be downgraded to version 1.8 (format 31)
To fix it, we start to distinguish cases where the `--compatible-version`
argument (or the corresponding API parameter) have or have not been specified
explicitly. If the working copy already has a supported format newer than
the resolved target format, the behavior is as follows:
- If the format version wasn't specified explicitly, meaning the default
version should be used, the upgrade is no-op and the working copy is left
at its current format.
- If the format version was specified explicitly, meaning that a concrete
format version should be used, the upgrade results in an error.
* subversion/include/svn_client.h
(svn_client_upgrade2): Add the `result_format_version_p` out parameter.
Rename `wc_format_version` to `target_format_version`. Adjust docstring.
(svn_client_upgrade): Adjust docstring.
* subversion/include/private/svn_wc_private.h
(svn_wc__upgrade): Add the `result_format_p` out parameter. Adjust docstring.
* subversion/libsvn_client/upgrade.c
(upgrade_internal): Add the `result_format_p` out parameter.
Rename `wc_format` to `target_format`.
(upgrade_external_item): Adjust calling site of upgrade_internal().
(svn_client_upgrade2): Fill in the resulting format version.
Fail on downgrade attempts if a format version was passed explicitly.
* subversion/libsvn_client/deprecated.c
(svn_client_upgrade): Adjust calling site of svn_client_upgrade2().
* subversion/libsvn_wc/upgrade.c
(svn_wc__upgrade_sdb): Don't check for downgrade attempts here.
Allow the upgrade to be a no-op by removing corresponding assertions from
this function and also …
(svn_wc__update_schema): …here, …
(svn_wc__upgrade): …and here. Fill in the resulting format value.
* subversion/libsvn_wc/deprecated.c
(svn_wc_upgrade): Adjust calling site of svn_wc__upgrade().
* subversion/svn/upgrade-cmd.c
(svn_cl__upgrade): Use the information about the resulting format version
to re-implement the "working copy may be upgraded further" message, and
issue it on a per-wc basis.
* subversion/tests/cmdline/upgrade_tests.py
(upgrade_latest_format): No longer fails. Check the resulting format of
the working copy.
* subversion/tests/cmdline/externals_tests.py
(switch_relative_externals): Remove Wimp() marker, because the corresponding
issue is now solved.
Modified:
subversion/trunk/subversion/include/private/svn_wc_private.h
subversion/trunk/subversion/include/svn_client.h
subversion/trunk/subversion/libsvn_client/deprecated.c
subversion/trunk/subversion/libsvn_client/upgrade.c
subversion/trunk/subversion/libsvn_wc/deprecated.c
subversion/trunk/subversion/libsvn_wc/upgrade.c
subversion/trunk/subversion/svn/upgrade-cmd.c
subversion/trunk/subversion/tests/cmdline/externals_tests.py
subversion/trunk/subversion/tests/cmdline/upgrade_tests.py
Modified: subversion/trunk/subversion/include/private/svn_wc_private.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_wc_private.h?rev=1907965&r1=1907964&r2=1907965&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_wc_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_wc_private.h Thu Mar 2
11:10:34 2023
@@ -2290,6 +2290,9 @@ svn_wc__ensure_adm(svn_wc_context_t *wc_
* format indicated by @a target_format. @a local_abspath should be
* an absolute path to the root of the working copy.
*
+ * If @a result_format_p is non-NULL, it will be set to the resulting
+ * format of the working copy after the upgrade.
+ *
* If @a cancel_func is non-NULL, invoke it with @a cancel_baton at
* various points during the operation. If it returns an error
* (typically #SVN_ERR_CANCELLED), return that error immediately.
@@ -2306,7 +2309,8 @@ svn_wc__ensure_adm(svn_wc_context_t *wc_
* @since New in 1.15.
*/
svn_error_t *
-svn_wc__upgrade(svn_wc_context_t *wc_ctx,
+svn_wc__upgrade(int *result_format_p,
+ svn_wc_context_t *wc_ctx,
const char *local_abspath,
int target_format,
svn_wc_upgrade_get_repos_info_t repos_info_func,
Modified: subversion/trunk/subversion/include/svn_client.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_client.h?rev=1907965&r1=1907964&r2=1907965&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_client.h (original)
+++ subversion/trunk/subversion/include/svn_client.h Thu Mar 2 11:10:34 2023
@@ -4403,12 +4403,27 @@ svn_client_cleanup(const char *dir,
/**
* Recursively upgrade a working copy and nested externals working
* copies from any older format to a WC metadata storage
- * format supported by Subversion @a wc_format_version.
+ * format supported by Subversion @a target_format_version.
*
- * If @a wc_format_version is @c NULL, the default version is used.
+ * If @a target_format_version is @c NULL, the default version is used.
+ *
+ * If the working copy already has a supported format newer than
+ * @a target_format_version, the behavior is as follows:
+ *
+ * - If @a target_format_version is @c NULL, meaning the default version
+ * should be used, the upgrade is no-op and the working copy is left
+ * at its current format.
+ *
+ * - If @a target_format_version is not @c NULL, meaning that a specific
+ * format version should be used, the upgrade results in an error.
*
* @a wcroot_dir is the path to the WC root.
*
+ * If @a result_format_version_p is not @c NULL, it will be set to the
+ * resulting format version of the upgraded working copy, allocated from
+ * @a result_pool. If this information is not required, @a result_pool
+ * may be passed as @c NULL.
+ *
* @see svn_client_default_wc_version(),
* svn_client_get_wc_formats_supported().
*
@@ -4417,13 +4432,16 @@ svn_client_cleanup(const char *dir,
* @since New in 1.15.
*/
svn_error_t *
-svn_client_upgrade2(const char *wcroot_dir,
- const svn_version_t *wc_format_version,
+svn_client_upgrade2(const svn_version_t **result_format_version_p,
+ const char *wcroot_dir,
+ const svn_version_t *target_format_version,
svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
/**
- * Like svn_client_upgrade2(), but with @a wc_format_version set to @c NULL.
+ * Like svn_client_upgrade2(), but with @a result_format_version_p,
+ * @a target_format_version and @a result_pool set to @c NULL.
*
* @since New in 1.7.
* @deprecated Provided for backward compatibility with the 1.14 API.
Modified: subversion/trunk/subversion/libsvn_client/deprecated.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/deprecated.c?rev=1907965&r1=1907964&r2=1907965&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/deprecated.c (original)
+++ subversion/trunk/subversion/libsvn_client/deprecated.c Thu Mar 2 11:10:34
2023
@@ -3287,5 +3287,6 @@ svn_client_upgrade(const char *path,
svn_client_ctx_t *ctx,
apr_pool_t *scratch_pool)
{
- return svn_error_trace(svn_client_upgrade2(path, NULL, ctx, scratch_pool));
+ return svn_error_trace(svn_client_upgrade2(NULL, path, NULL, ctx,
+ NULL, scratch_pool));
}
Modified: subversion/trunk/subversion/libsvn_client/upgrade.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/upgrade.c?rev=1907965&r1=1907964&r2=1907965&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/upgrade.c (original)
+++ subversion/trunk/subversion/libsvn_client/upgrade.c Thu Mar 2 11:10:34 2023
@@ -99,8 +99,9 @@ upgrade_externals_from_properties(svn_cl
apr_pool_t *scratch_pool);
static svn_error_t *
-upgrade_internal(const char *path,
- int wc_format,
+upgrade_internal(int *result_format_p,
+ const char *path,
+ int target_format,
svn_client_ctx_t *ctx,
apr_pool_t *scratch_pool)
{
@@ -118,7 +119,8 @@ upgrade_internal(const char *path,
_("'%s' is not a local path"), path);
SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
- SVN_ERR(svn_wc__upgrade(ctx->wc_ctx, local_abspath, wc_format,
+ SVN_ERR(svn_wc__upgrade(result_format_p, ctx->wc_ctx,
+ local_abspath, target_format,
fetch_repos_info, &info_baton,
ctx->cancel_func, ctx->cancel_baton,
ctx->notify_func2, ctx->notify_baton2,
@@ -156,8 +158,9 @@ upgrade_internal(const char *path,
if (kind == svn_node_dir)
{
- svn_error_t *err = upgrade_internal(ext_abspath, wc_format,
- ctx, iterpool);
+ svn_error_t *err = upgrade_internal(NULL, ext_abspath,
+ target_format, ctx,
+ iterpool);
if (err)
{
@@ -181,8 +184,9 @@ upgrade_internal(const char *path,
/* Upgrading from <= 1.6, or no svn:properties defined.
(There is no way to detect the difference from libsvn_client :( ) */
- SVN_ERR(upgrade_externals_from_properties(ctx, local_abspath, wc_format,
- &info_baton, scratch_pool));
+ SVN_ERR(upgrade_externals_from_properties(ctx, local_abspath,
+ target_format, &info_baton,
+ scratch_pool));
}
SVN_ERR(svn_client__textbase_sync(NULL, local_abspath, FALSE, TRUE, ctx,
@@ -192,23 +196,54 @@ upgrade_internal(const char *path,
}
svn_error_t *
-svn_client_upgrade2(const char *path,
- const svn_version_t *wc_format_version,
+svn_client_upgrade2(const svn_version_t **result_format_version_p,
+ const char *path,
+ const svn_version_t *target_format_version,
svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- int wc_format;
+ int result_format;
+ int target_format;
+ svn_boolean_t fail_on_downgrade;
- if (!wc_format_version)
+ if (target_format_version)
{
- SVN_ERR(svn_client_default_wc_version(&wc_format_version, ctx,
+ SVN_ERR(svn_wc__format_from_version(&target_format,
+ target_format_version,
+ scratch_pool));
+ /* Fail on downgrade attempts if format version was passed explicitly. */
+ fail_on_downgrade = TRUE;
+ }
+ else
+ {
+ const svn_version_t *default_version;
+
+ SVN_ERR(svn_client_default_wc_version(&default_version, ctx,
scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__format_from_version(&target_format, default_version,
+ scratch_pool));
+ fail_on_downgrade = FALSE;
}
- SVN_ERR(svn_wc__format_from_version(&wc_format,
- wc_format_version,
- scratch_pool));
- SVN_ERR(upgrade_internal(path, wc_format, ctx, scratch_pool));
+ SVN_ERR(upgrade_internal(&result_format, path, target_format,
+ ctx, scratch_pool));
+
+ if (fail_on_downgrade && result_format > target_format)
+ return svn_error_createf(SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL,
+ _("Working copy '%s' is already at version %s "
+ "(format %d) and cannot be downgraded to "
+ "version %s (format %d)"),
+ svn_dirent_local_style(path, scratch_pool),
+ svn_wc__version_string_from_format(result_format),
+ result_format,
+ svn_wc__version_string_from_format(target_format),
+ target_format);
+
+ if (result_format_version_p)
+ *result_format_version_p = svn_client_wc_version_from_format(
+ result_format, result_pool);
+
return SVN_NO_ERROR;
}
@@ -362,7 +397,8 @@ upgrade_external_item(svn_client_ctx_t *
{
svn_error_clear(err);
- SVN_ERR(upgrade_internal(external_abspath, wc_format, ctx,
scratch_pool));
+ SVN_ERR(upgrade_internal(NULL, external_abspath, wc_format, ctx,
+ scratch_pool));
}
else if (err)
return svn_error_trace(err);
Modified: subversion/trunk/subversion/libsvn_wc/deprecated.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/deprecated.c?rev=1907965&r1=1907964&r2=1907965&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/trunk/subversion/libsvn_wc/deprecated.c Thu Mar 2 11:10:34 2023
@@ -5179,7 +5179,8 @@ svn_wc_upgrade(svn_wc_context_t *wc_ctx,
void *notify_baton,
apr_pool_t *scratch_pool)
{
- return svn_wc__upgrade(wc_ctx, local_abspath, SVN_WC__DEFAULT_VERSION,
+ return svn_wc__upgrade(NULL, wc_ctx, local_abspath,
+ SVN_WC__DEFAULT_VERSION,
repos_info_func, repos_info_baton,
cancel_func, cancel_baton,
notify_func, notify_baton,
Modified: subversion/trunk/subversion/libsvn_wc/upgrade.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/upgrade.c?rev=1907965&r1=1907964&r2=1907965&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/trunk/subversion/libsvn_wc/upgrade.c Thu Mar 2 11:10:34 2023
@@ -1765,18 +1765,6 @@ svn_wc__upgrade_sdb(int *result_format,
scratch_pool),
start_format);
- if (start_format > target_format)
- return svn_error_createf(SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL,
- _("Working copy '%s' is already at version %s "
- "(format %d) and cannot be downgraded to "
- "version %s (format %d)"),
- svn_dirent_local_style(wcroot_abspath,
- scratch_pool),
- svn_wc__version_string_from_format(start_format),
- start_format,
- svn_wc__version_string_from_format(target_format),
- target_format);
-
if (target_format < SVN_WC__SUPPORTED_VERSION)
return svn_error_createf(SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL,
_("Working copy version %s (format %d) "
@@ -1802,17 +1790,6 @@ svn_wc__upgrade_sdb(int *result_format,
svn_wc__db_install_schema_statistics(sdb, scratch_pool),
sdb);
-#ifdef SVN_DEBUG
- if (*result_format != start_format)
- {
- int schema_version;
- SVN_ERR(svn_sqlite__read_schema_version(&schema_version, sdb,
scratch_pool));
-
- /* If this assertion fails the schema isn't updated correctly */
- SVN_ERR_ASSERT(schema_version == *result_format);
- }
-#endif
-
/* Zap anything that might be remaining or escaped our notice. */
wipe_obsolete_files(wcroot_abspath, scratch_pool);
@@ -1855,7 +1832,6 @@ svn_wc__update_schema(int *result_format
#undef UPDATE_TO_FORMAT
}
- SVN_ERR_ASSERT(*result_format == target_format);
return SVN_NO_ERROR;
}
@@ -2023,7 +1999,8 @@ is_old_wcroot(const char *local_abspath,
}
svn_error_t *
-svn_wc__upgrade(svn_wc_context_t *wc_ctx,
+svn_wc__upgrade(int *result_format_p,
+ svn_wc_context_t *wc_ctx,
const char *local_abspath,
int target_format,
svn_wc_upgrade_get_repos_info_t repos_info_func,
@@ -2072,8 +2049,6 @@ svn_wc__upgrade(svn_wc_context_t *wc_ctx
/* Auto-upgrade worked! */
SVN_ERR(svn_wc__db_close(db));
- SVN_ERR_ASSERT(result_format == target_format);
-
if (bumped_format && notify_func)
{
svn_wc_notify_t *notify;
@@ -2085,6 +2060,8 @@ svn_wc__upgrade(svn_wc_context_t *wc_ctx
notify_func(notify_baton, notify, scratch_pool);
}
+ if (result_format_p)
+ *result_format_p = result_format;
return SVN_NO_ERROR;
}
@@ -2183,6 +2160,8 @@ svn_wc__upgrade(svn_wc_context_t *wc_ctx
SVN_ERR(svn_io_remove_dir2(data.root_abspath, FALSE, NULL, NULL,
scratch_pool));
+ if (result_format_p)
+ *result_format_p = target_format;
return SVN_NO_ERROR;
}
Modified: subversion/trunk/subversion/svn/upgrade-cmd.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/upgrade-cmd.c?rev=1907965&r1=1907964&r2=1907965&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/upgrade-cmd.c (original)
+++ subversion/trunk/subversion/svn/upgrade-cmd.c Thu Mar 2 11:10:34 2023
@@ -52,11 +52,8 @@ svn_cl__upgrade(apr_getopt_t *os,
apr_array_header_t *targets;
apr_pool_t *iterpool;
int i;
- 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,
@@ -75,31 +72,34 @@ svn_cl__upgrade(apr_getopt_t *os,
for (i = 0; i < targets->nelts; i++)
{
const char *target = APR_ARRAY_IDX(targets, i, const char *);
+ const svn_version_t *result_format_version;
svn_pool_clear(iterpool);
SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton));
- SVN_ERR(svn_client_upgrade2(target,
+ SVN_ERR(svn_client_upgrade2(&result_format_version, target,
opt_state->compatible_version,
- ctx, scratch_pool));
- }
- svn_pool_destroy(iterpool);
+ ctx, iterpool, iterpool));
- /* Remind the user they can upgrade further if:
- * - the user did not specify compatible-version explicitly
- * - a higher version is available. */
- if (! opt_state->compatible_version
- && ! svn_version__at_least(default_version,
- latest_version->major, latest_version->minor,
0)
- && ! opt_state->quiet)
- {
- const char *msg
- = _("svn: The target working copies are 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));
+ /* Remind the user they can upgrade further if:
+ * - the user did not specify compatible-version explicitly
+ * - a higher version is available. */
+ if (! opt_state->compatible_version
+ && ! svn_version__at_least(result_format_version,
+ latest_version->major,
+ latest_version->minor, 0)
+ && ! opt_state->quiet)
+ {
+ SVN_ERR(svn_cmdline_printf(
+ iterpool,
+ _("svn: The target working copy '%s' is at version %d.%d; "
+ "the highest version supported by this client can be "
+ "specified with '--compatible-version=%d.%d'.\n"),
+ svn_dirent_local_style(target, iterpool),
+ result_format_version->major, result_format_version->minor,
+ latest_version->major, latest_version->minor));
+ }
}
+ svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
Modified: subversion/trunk/subversion/tests/cmdline/externals_tests.py
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/externals_tests.py?rev=1907965&r1=1907964&r2=1907965&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/externals_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/externals_tests.py Thu Mar 2
11:10:34 2023
@@ -3431,7 +3431,6 @@ def update_deletes_file_external(sbox):
@Issue(4519)
-@Wimp("May trigger an existing issue, see
upgrade_tests.py:upgrade_latest_format()")
def switch_relative_externals(sbox):
"switch relative externals"
Modified: subversion/trunk/subversion/tests/cmdline/upgrade_tests.py
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/upgrade_tests.py?rev=1907965&r1=1907964&r2=1907965&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/upgrade_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/upgrade_tests.py Thu Mar 2
11:10:34 2023
@@ -1583,7 +1583,6 @@ def upgrade_1_0_with_externals(sbox):
})
run_and_verify_status_no_server(sbox.wc_dir, expected_status)
-@XFail()
@SkipUnless(lambda: svntest.main.options.wc_format_version is None)
def upgrade_latest_format(sbox):
"upgrade latest format without arguments"
@@ -1599,11 +1598,13 @@ def upgrade_latest_format(sbox):
[],
'--compatible-version',
latest_ver)
- # XFAIL:
+ # This used to fail with the following error:
# svn: E155021: Working copy '...' is already at version 1.15 (format 32)
# and cannot be downgraded to version 1.8 (format 31)
svntest.actions.run_and_verify_svn(None, [], 'upgrade', sbox.wc_dir)
+ check_format(sbox, svntest.main.wc_format(latest_ver))
+
def upgrade_compatible_version_arg(sbox):
"upgrade with compatible-version from arg"