Author: stsp
Date: Fri Nov 2 01:53:23 2012
New Revision: 1404856
URL: http://svn.apache.org/viewvc?rev=1404856&view=rev
Log:
Disable automatic working copy upgrades. This has been discussed over and
over, with many people in the community indicating they prefer manual upgrades.
For now, this is a hard-coded default. There is no way to enable auto-upgrade.
And unfortunately there is no single knob to globally switch auto-upgrade on
and off in the code. Rather, function parameters have to be tweaked in various
places where a working copy database is opened.
Some parts of the upgrade code were written and tested exclusively for
upgrading from 1.6 and earlier working copy formats to wc-ng, and thus
needed small fixes to allow 'svn upgrade' to run wc-ng -> wn-ng format
bumps without crashing.
* subversion/libsvn_wc/adm_files.c
(svn_wc_create_tmp_file2): Don't auto-upgrade working copies.
* subversion/libsvn_wc/adm_ops.c
(svn_wc_get_pristine_copy_path): Don't auto-upgrade working copies.
* subversion/libsvn_wc/cleanup.c
(svn_wc_cleanup3): Don't auto-upgrade working copies.
* subversion/libsvn_wc/context.c
(svn_wc_context_create): Don't auto-upgrade working copies.
* subversion/libsvn_wc/lock.c
(pool_cleanup_locked, svn_wc_adm_open3, svn_wc_adm_probe_open3,
open_anchor): Don't auto-upgrade working copies.
* subversion/libsvn_wc/upgrade.c
(svn_wc__upgrade_sdb): Initialise *result_format before use if the
working copy is already at format SVN_WC__VERSION to prevent an assertion
during no-op upgrades of wc-ng working copies.
(is_old_wcroot): Remove Subversion version numbers from error messages.
It is now misleading to say that an upgrade is not possible because a
pre-1.7 working copy was found since 'svn upgrade' now runs on any format.
(svn_wc_upgrade): Handle upgrades from wc-ng-style working copies.
Enable auto-upgrade of the db during upgrades from pre-1.7 WCs to avoid
'svn upgrade' advising users to run 'svn upgrade'.
* subversion/libsvn_wc/wc_db.c
(svn_wc__db_bump_format): New helper function for wc-ng -> wc-ng upgrades.
Ensures that the upgrade target is a working copy root, and performs a
format bump of wcroot->sdb, which isn't exposed outside of the wc_db layer.
* subversion/libsvn_wc/wc_db.h
(svn_wc__db_bump_format): Declare.
* subversion/libsvn_wc/wc_db_wcroot.c
(svn_wc__db_pdh_create_wcroot): Properly handle the case where we do not
auto-upgrade and run into a working copy using an older format.
Previously, we ended up asserting in VERIFY_USABLE_WCROOT() somewhere
because no upgrade happened but no error was returned either. Instead,
return an error advising the user to upgrade the working copy.
* subversion/tests/cmdline/upgrade_tests.py
(wc_is_too_old_regex): The error message matched by this regex has changed
in some cases, so adjust the regex accordingly.
(basic_upgrade): Expect slightly different error messages resulting from
above changes. The error code returned is unchanged, however.
(upgrade_tree_conflict_data, upgrade_from_format_28): These tests were
running 'svn status' and 'svn info' to trigger auto-upgrades. Make them
run 'svn upgrade' instead to keep them passing.
Modified:
subversion/trunk/subversion/libsvn_wc/adm_files.c
subversion/trunk/subversion/libsvn_wc/adm_ops.c
subversion/trunk/subversion/libsvn_wc/cleanup.c
subversion/trunk/subversion/libsvn_wc/context.c
subversion/trunk/subversion/libsvn_wc/lock.c
subversion/trunk/subversion/libsvn_wc/upgrade.c
subversion/trunk/subversion/libsvn_wc/wc_db.c
subversion/trunk/subversion/libsvn_wc/wc_db.h
subversion/trunk/subversion/libsvn_wc/wc_db_wcroot.c
subversion/trunk/subversion/tests/cmdline/upgrade_tests.py
Modified: subversion/trunk/subversion/libsvn_wc/adm_files.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_files.c?rev=1404856&r1=1404855&r2=1404856&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_files.c (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_files.c Fri Nov 2 01:53:23 2012
@@ -592,7 +592,7 @@ svn_wc_create_tmp_file2(apr_file_t **fp,
SVN_ERR(svn_wc__db_open(&db,
NULL /* config */,
- TRUE /* auto_upgrade */,
+ FALSE /* auto_upgrade */,
TRUE /* enforce_empty_wq */,
pool, pool));
Modified: subversion/trunk/subversion/libsvn_wc/adm_ops.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_ops.c?rev=1404856&r1=1404855&r2=1404856&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_ops.c Fri Nov 2 01:53:23 2012
@@ -2211,7 +2211,7 @@ svn_wc_get_pristine_copy_path(const char
SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
- SVN_ERR(svn_wc__db_open(&db, NULL, TRUE, TRUE, pool, pool));
+ SVN_ERR(svn_wc__db_open(&db, NULL, FALSE, TRUE, pool, pool));
/* DB is now open. This is seemingly a "light" function that a caller
may use repeatedly despite error return values. The rest of this
function should aggressively close DB, even in the error case. */
Modified: subversion/trunk/subversion/libsvn_wc/cleanup.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/cleanup.c?rev=1404856&r1=1404855&r2=1404856&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/cleanup.c (original)
+++ subversion/trunk/subversion/libsvn_wc/cleanup.c Fri Nov 2 01:53:23 2012
@@ -206,7 +206,7 @@ svn_wc_cleanup3(svn_wc_context_t *wc_ctx
/* We need a DB that allows a non-empty work queue (though it *will*
auto-upgrade). We'll handle everything manually. */
SVN_ERR(svn_wc__db_open(&db,
- NULL /* ### config */, TRUE, FALSE,
+ NULL /* ### config */, FALSE, FALSE,
scratch_pool, scratch_pool));
SVN_ERR(cleanup_internal(db, local_abspath, cancel_func, cancel_baton,
Modified: subversion/trunk/subversion/libsvn_wc/context.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/context.c?rev=1404856&r1=1404855&r2=1404856&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/context.c (original)
+++ subversion/trunk/subversion/libsvn_wc/context.c Fri Nov 2 01:53:23 2012
@@ -70,7 +70,7 @@ svn_wc_context_create(svn_wc_context_t *
* we need to make it writable */
ctx->state_pool = result_pool;
SVN_ERR(svn_wc__db_open(&ctx->db, (svn_config_t *)config,
- TRUE, TRUE, ctx->state_pool, scratch_pool));
+ FALSE, TRUE, ctx->state_pool, scratch_pool));
ctx->close_db_on_destroy = TRUE;
apr_pool_cleanup_register(result_pool, ctx, close_ctx_apr,
Modified: subversion/trunk/subversion/libsvn_wc/lock.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/lock.c?rev=1404856&r1=1404855&r2=1404856&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/lock.c (original)
+++ subversion/trunk/subversion/libsvn_wc/lock.c Fri Nov 2 01:53:23 2012
@@ -331,7 +331,7 @@ pool_cleanup_locked(void *p)
run, but the subpools will NOT be destroyed) */
scratch_pool = svn_pool_create(lock->pool);
- err = svn_wc__db_open(&db, NULL /* ### config. need! */, TRUE, TRUE,
+ err = svn_wc__db_open(&db, NULL /* ### config. need! */, FALSE, TRUE,
scratch_pool, scratch_pool);
if (!err)
{
@@ -781,7 +781,7 @@ svn_wc_adm_open3(svn_wc_adm_access_t **a
do it here. */
/* ### we could optimize around levels_to_lock==0, but much of this
### is going to be simplified soon anyways. */
- SVN_ERR(svn_wc__db_open(&db, NULL /* ### config. need! */, TRUE, TRUE,
+ SVN_ERR(svn_wc__db_open(&db, NULL /* ### config. need! */, FALSE, TRUE,
pool, pool));
db_provided = FALSE;
}
@@ -811,7 +811,7 @@ svn_wc_adm_probe_open3(svn_wc_adm_access
/* Ugh. Too bad about having to open a DB. */
SVN_ERR(svn_wc__db_open(&db,
- NULL /* ### config */, TRUE, TRUE, pool, pool));
+ NULL /* ### config */, FALSE, TRUE, pool, pool));
err = probe(db, &dir, path, pool);
svn_error_clear(svn_wc__db_close(db));
SVN_ERR(err);
@@ -1157,7 +1157,7 @@ open_anchor(svn_wc_adm_access_t **anchor
### given that we need DB for format detection, may as well keep this.
### in any case, much of this is going to be simplified soon anyways. */
if (!db_provided)
- SVN_ERR(svn_wc__db_open(&db, NULL, /* ### config. need! */ TRUE, TRUE,
+ SVN_ERR(svn_wc__db_open(&db, NULL, /* ### config. need! */ FALSE, TRUE,
pool, pool));
if (svn_path_is_empty(path)
Modified: subversion/trunk/subversion/libsvn_wc/upgrade.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/upgrade.c?rev=1404856&r1=1404855&r2=1404856&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/trunk/subversion/libsvn_wc/upgrade.c Fri Nov 2 01:53:23 2012
@@ -1892,6 +1892,9 @@ svn_wc__upgrade_sdb(int *result_format,
*result_format = XXX;
/* FALLTHROUGH */
#endif
+ case SVN_WC__VERSION:
+ /* already upgraded */
+ *result_format = SVN_WC__VERSION;
}
#ifdef SVN_DEBUG
@@ -2019,7 +2022,7 @@ is_old_wcroot(const char *local_abspath,
{
return svn_error_createf(
SVN_ERR_WC_INVALID_OP_ON_CWD, err,
- _("Can't upgrade '%s' as it is not a pre-1.7 working copy directory"),
+ _("Can't upgrade '%s' as it is not a working copy"),
svn_dirent_local_style(local_abspath, scratch_pool));
}
else if (svn_dirent_is_root(local_abspath, strlen(local_abspath)))
@@ -2068,7 +2071,7 @@ is_old_wcroot(const char *local_abspath,
return svn_error_createf(
SVN_ERR_WC_INVALID_OP_ON_CWD, NULL,
- _("Can't upgrade '%s' as it is not a pre-1.7 working copy root,"
+ _("Can't upgrade '%s' as it is not a working copy root,"
" the root is '%s'"),
svn_dirent_local_style(local_abspath, scratch_pool),
svn_dirent_local_style(parent_abspath, scratch_pool));
@@ -2128,6 +2131,34 @@ svn_wc_upgrade(svn_wc_context_t *wc_ctx,
apr_hash_t *entries;
const char *root_adm_abspath;
upgrade_working_copy_baton_t cb_baton;
+ svn_error_t *err;
+ int result_format;
+
+ /* Try upgrading a wc-ng-style working copy. */
+ SVN_ERR(svn_wc__db_open(&db, NULL /* ### config */, TRUE, FALSE,
+ scratch_pool, scratch_pool));
+
+ err = svn_wc__db_bump_format(&result_format, local_abspath, db,
+ scratch_pool);
+ if (err)
+ {
+ if (err->apr_err == SVN_ERR_WC_UPGRADE_REQUIRED) /* pre-1.7 WC */
+ {
+ svn_error_clear(err);
+ SVN_ERR(svn_wc__db_close(db));
+ }
+ else
+ return svn_error_trace(err);
+ }
+ else
+ {
+ /* Auto-upgrade worked! */
+ SVN_ERR(svn_wc__db_close(db));
+
+ SVN_ERR_ASSERT(result_format == SVN_WC__VERSION);
+
+ return SVN_NO_ERROR;
+ }
SVN_ERR(is_old_wcroot(local_abspath, scratch_pool));
@@ -2141,7 +2172,7 @@ svn_wc_upgrade(svn_wc_context_t *wc_ctx,
upgrade. */
SVN_ERR(svn_wc__db_open(&db,
- NULL /* ### config */, FALSE, FALSE,
+ NULL /* ### config */, TRUE, FALSE,
scratch_pool, scratch_pool));
SVN_ERR(svn_wc__read_entries_old(&entries, local_abspath,
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1404856&r1=1404855&r2=1404856&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Fri Nov 2 01:53:23 2012
@@ -14025,3 +14025,36 @@ svn_wc__db_verify(svn_wc__db_t *db,
SVN_ERR(verify_wcroot(wcroot, scratch_pool));
return SVN_NO_ERROR;
}
+
+svn_error_t *
+svn_wc__db_bump_format(int *result_format,
+ const char *wcroot_abspath,
+ svn_wc__db_t *db,
+ apr_pool_t *scratch_pool)
+{
+
+ svn_wc__db_wcroot_t *wcroot;
+ const char *local_relpath;
+
+ SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath,
+ db, wcroot_abspath,
+ scratch_pool, scratch_pool));
+
+ /* This function is indirectly called from the upgrade code, so we
+ can't verify the wcroot here. Just check that it is not NULL */
+ SVN_ERR_ASSERT(wcroot != NULL);
+
+ /* Reject attempts to upgrade subdirectories of a working copy. */
+ if (strcmp(wcroot_abspath, wcroot->abspath) != 0)
+ return svn_error_createf(
+ SVN_ERR_WC_INVALID_OP_ON_CWD, NULL,
+ _("Can't upgrade '%s' as it is not a working copy root,"
+ " the root is '%s'"),
+ svn_dirent_local_style(wcroot_abspath, scratch_pool),
+ svn_dirent_local_style(wcroot->abspath, scratch_pool));
+
+ SVN_ERR(svn_wc__upgrade_sdb(result_format, wcroot->abspath,
+ wcroot->sdb, wcroot->format,
+ scratch_pool));
+ return SVN_NO_ERROR;
+}
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1404856&r1=1404855&r2=1404856&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Fri Nov 2 01:53:23 2012
@@ -2792,6 +2792,23 @@ svn_wc__db_upgrade_get_repos_id(apr_int6
const char *repos_root_url,
apr_pool_t *scratch_pool);
+/* Upgrade the metadata concerning the WC at WCROOT_ABSPATH, in DB,
+ * to the SVN_WC__VERSION format.
+ *
+ * This function is used for upgrading wc-ng working copies to a newer
+ * wc-ng format. If a pre-1.7 working copy is found, this function
+ * returns SVN_ERR_WC_UPGRADE_REQUIRED.
+ *
+ * Upgrading subdirectories of a working copy is not supported.
+ * If WCROOT_ABSPATH is not a working copy root SVN_ERR_WC_INVALID_OP_ON_CWD
+ * is returned.
+ */
+svn_error_t *
+svn_wc__db_bump_format(int *result_format,
+ const char *wcroot_abspath,
+ svn_wc__db_t *db,
+ apr_pool_t *scratch_pool);
+
/* @} */
Modified: subversion/trunk/subversion/libsvn_wc/wc_db_wcroot.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db_wcroot.c?rev=1404856&r1=1404855&r2=1404856&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db_wcroot.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db_wcroot.c Fri Nov 2 01:53:23
2012
@@ -27,6 +27,7 @@
#include "svn_dirent_uri.h"
#include "svn_path.h"
+#include "svn_version.h"
#include "wc.h"
#include "adm_files.h"
@@ -294,9 +295,24 @@ svn_wc__db_pdh_create_wcroot(svn_wc__db_
}
/* Auto-upgrade the SDB if possible. */
- if (format < SVN_WC__VERSION && auto_upgrade)
- SVN_ERR(svn_wc__upgrade_sdb(&format, wcroot_abspath, sdb, format,
- scratch_pool));
+ if (format < SVN_WC__VERSION)
+ {
+ if (auto_upgrade)
+ {
+ if (format >= SVN_WC__WC_NG_VERSION)
+ SVN_ERR(svn_wc__upgrade_sdb(&format, wcroot_abspath, sdb, format,
+ scratch_pool));
+ }
+ else
+ return svn_error_createf(SVN_ERR_WC_UPGRADE_REQUIRED, NULL,
+ _("The working copy at '%s'\nis too old "
+ "(format %d) to work with client version "
+ "'%s' (expects format %d). You need to "
+ "upgrade the working copy first.\n"),
+ svn_dirent_local_style(wcroot_abspath,
+ scratch_pool), format, SVN_VERSION,
+ SVN_WC__VERSION);
+ }
*wcroot = apr_palloc(result_pool, sizeof(**wcroot));
Modified: subversion/trunk/subversion/tests/cmdline/upgrade_tests.py
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/upgrade_tests.py?rev=1404856&r1=1404855&r2=1404856&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/upgrade_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/upgrade_tests.py Fri Nov 2
01:53:23 2012
@@ -50,7 +50,7 @@ Issues = svntest.testcase.Issues_deco
Issue = svntest.testcase.Issue_deco
Wimp = svntest.testcase.Wimp_deco
-wc_is_too_old_regex = (".*Working copy '.*' is too old \(format \d+.*\).*")
+wc_is_too_old_regex = (".*is too old \(format \d+.*\).*")
def get_current_format():
@@ -258,28 +258,29 @@ def basic_upgrade(sbox):
replace_sbox_with_tarfile(sbox, 'basic_upgrade.tar.bz2')
# Attempt to use the working copy, this should give an error
- expected_stderr = wc_is_too_old_regex
- svntest.actions.run_and_verify_svn(None, None, expected_stderr,
+ svntest.actions.run_and_verify_svn(None, None, wc_is_too_old_regex,
'info', sbox.wc_dir)
-
- # Upgrade on something not a versioned dir gives a 'not directory' error.
- not_dir = ".*E155019.*%s'.*directory"
+ # Upgrade on something anywhere within a versioned subdir gives a
+ # 'not a working copy root' error. Upgrade on something without any
+ # versioned parent gives a 'not a working copy' error.
+ # Both cases use the same error code.
+ not_wc = ".*E155019.*%s'.*not a working copy.*"
os.mkdir(sbox.ospath('X'))
- svntest.actions.run_and_verify_svn(None, None, not_dir % 'X',
+ svntest.actions.run_and_verify_svn(None, None, not_wc % 'X',
'upgrade', sbox.ospath('X'))
- svntest.actions.run_and_verify_svn(None, None, not_dir % 'Y',
+ # Upgrade on a non-existent subdir within an old WC gives a
+ # 'not a working copy' error.
+ svntest.actions.run_and_verify_svn(None, None, not_wc % 'Y',
'upgrade', sbox.ospath('Y'))
-
- svntest.actions.run_and_verify_svn(None, None, not_dir %
- re.escape(sbox.ospath('A/mu')),
+ # Upgrade on a versioned file within an old WC gives a
+ # 'not a working copy' error.
+ svntest.actions.run_and_verify_svn(None, None, not_wc % 'mu',
'upgrade', sbox.ospath('A/mu'))
-
- # Upgrade on a versioned subdir gives a 'not root' error.
- not_root = ".*E155019.*%s'.*root.*%s'"
- svntest.actions.run_and_verify_svn(None, None, not_root %
- ('A', re.escape(sbox.wc_dir)),
+ # Upgrade on a versioned dir within an old WC gives a
+ # 'not a working copy' error.
+ svntest.actions.run_and_verify_svn(None, None, not_wc % 'A',
'upgrade', sbox.ospath('A'))
# Now upgrade the working copy
@@ -794,10 +795,9 @@ def upgrade_tree_conflict_data(sbox):
no_actual_node(sbox, 'A/D/G/tau')
# While the upgrade from f20 to f21 will work the upgrade from f22
- # to f23 will not, since working nodes are present, so the
- # auto-upgrade will fail. If this happens we cannot use the
- # Subversion libraries to query the working copy.
- exit_code, output, errput = svntest.main.run_svn('format 22', 'st', wc_dir)
+ # to f23 will not, since working nodes are present.
+ exit_code, output, errput = svntest.main.run_svn('format 22', 'upgrade',
+ wc_dir)
if not exit_code:
run_and_verify_status_no_server(wc_dir, expected_status)
@@ -984,8 +984,8 @@ def upgrade_from_format_28(sbox):
assert os.path.exists(old_pristine_path)
assert not os.path.exists(new_pristine_path)
- # Touch the WC to auto-upgrade it
- svntest.actions.run_and_verify_svn(None, None, [], 'info', sbox.wc_dir)
+ # Upgrade the WC
+ svntest.actions.run_and_verify_svn(None, None, [], 'upgrade', sbox.wc_dir)
assert not os.path.exists(old_pristine_path)
assert os.path.exists(new_pristine_path)