Finish the working copy version compatibility work started in r7661:
* subversion/libsvn_wc/lock.c
(maybe_upgrade_format): Renamed from upgrade_format, filled in.
(create_lock): Don't call upgrade_format, we don't have the
lock->wc_format yet. Instead, callers of create_lock will have
to call maybe_upgrade_format.
(do_open, svn_wc__adm_steal_write_lock): Call maybe_upgrade_format.
* subversion/include/svn_error_codes.h
(SVN_ERR_WC_FORMAT_UPGRADE): New error code.
git-svn-id: https://svn.apache.org/repos/asf/subversion/branches/partial-authz-dev@847746 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/subversion/include/svn_error_codes.h b/subversion/include/svn_error_codes.h
index b25052b..f7895bc 100644
--- a/subversion/include/svn_error_codes.h
+++ b/subversion/include/svn_error_codes.h
@@ -345,6 +345,10 @@
SVN_ERR_WC_CATEGORY_START + 19,
"Invalid operation on the current working directory")
+ SVN_ERRDEF (SVN_ERR_WC_FORMAT_UPGRADE,
+ SVN_ERR_WC_CATEGORY_START + 20,
+ "Unable to upgrade working administrative format")
+
/* fs errors */
SVN_ERRDEF (SVN_ERR_FS_GENERAL,
diff --git a/subversion/libsvn_wc/lock.c b/subversion/libsvn_wc/lock.c
index 608865b..841dd5f 100644
--- a/subversion/libsvn_wc/lock.c
+++ b/subversion/libsvn_wc/lock.c
@@ -85,14 +85,44 @@
do_close (svn_wc_adm_access_t *adm_access, svn_boolean_t preserve_lock);
+/* Maybe upgrade the working copy directory represented by ADM_ACCESS
+ to the latest 'SVN_WC__VERSION'. This may involve renaming some
+ administrative files, therefore ADM_ACCESS must contain a write
+ lock. Use POOL for all temporary allocation.
+
+ Not all upgrade paths are necessarily supported. For example,
+ upgrading a version 1 working copy results in an error.
+
+ Sometimes the format file can contain "0" while the administrative
+ directory is being constructed; calling this on a format 0 working
+ copy has no effect and returns no error. */
static svn_error_t *
-upgrade_format (svn_wc_adm_access_t *adm_access, apr_pool_t *pool)
+maybe_upgrade_format (svn_wc_adm_access_t *adm_access, apr_pool_t *pool)
{
- /* ### We'll write the upgrade code later. For now, punt. */
- return svn_error_createf
- (SVN_ERR_WC_CORRUPT, NULL,
- "TODO: '%s' needs a format upgrade, but we haven't written the code yet",
- adm_access->path);
+ if (adm_access->wc_format == 1)
+ {
+ return svn_error_createf
+ (SVN_ERR_WC_FORMAT_UPGRADE, NULL,
+ "working copy format 1 is too old to upgrade, in '%s';\n"
+ "please check out your working copy again",
+ adm_access->path);
+ }
+ else if (adm_access->wc_format == 2)
+ {
+ const char *path = svn_wc__adm_path (adm_access->path, FALSE, pool,
+ SVN_WC__ADM_FORMAT, NULL);
+
+ SVN_ERR (svn_io_write_version_file (path, SVN_WC__VERSION, pool));
+ adm_access->wc_format = SVN_WC__VERSION;
+ }
+ else if (adm_access->wc_format > SVN_WC__VERSION)
+ {
+ return svn_error_createf
+ (SVN_ERR_WC_FORMAT_UPGRADE, NULL,
+ "this client is much too old to work with working copy '%s';\n"
+ "please get a newer Subversion client",
+ adm_access->path);
+ }
return SVN_NO_ERROR;
}
@@ -100,7 +130,12 @@
/* Create a physical lock file in the admin directory for ADM_ACCESS. Wait
up to WAIT_FOR seconds if the lock already exists retrying every
- second. */
+ second.
+
+ Note: most callers of this function determine the wc_format for the
+ lock soon afterwards. We recommend calling maybe_upgrade_format()
+ as soon as you have the wc_format for a lock, since that's a good
+ opportunity to drag old working directories into the modern era. */
static svn_error_t *
create_lock (svn_wc_adm_access_t *adm_access, int wait_for, apr_pool_t *pool)
{
@@ -124,17 +159,7 @@
return err;
}
else
- {
- /* We have a write lock. If the working copy has an old
- format, this is the time to upgrade it. */
- if ((adm_access->wc_format > 0)
- && (adm_access->wc_format < SVN_WC__VERSION))
- {
- SVN_ERR (upgrade_format (adm_access, pool));
- }
-
- return SVN_NO_ERROR;
- }
+ return SVN_NO_ERROR;
}
return svn_error_createf (SVN_ERR_WC_LOCKED, NULL,
@@ -279,8 +304,11 @@
apr_hash_set (lock->set, lock->path, APR_HASH_KEY_STRING, lock);
}
+ /* We have a write lock. If the working copy has an old
+ format, this is the time to upgrade it. */
SVN_ERR (svn_wc_check_wc (path, &lock->wc_format, pool));
-
+ SVN_ERR (maybe_upgrade_format (lock, pool));
+
lock->lock_exists = TRUE;
*adm_access = lock;
return SVN_NO_ERROR;
@@ -350,8 +378,12 @@
{
lock = adm_access_alloc (svn_wc__adm_access_unlocked, path, pool);
}
+
if (! under_construction)
- lock->wc_format = wc_format;
+ {
+ lock->wc_format = wc_format;
+ SVN_ERR (maybe_upgrade_format (lock, pool));
+ }
if (tree_lock)
{