One of the problems with single-db upgrade is that write_entry, called
from svn_wc__write_upgraded_entries, want's to be able to query the
new database using things like svn_wc__db_scan_addition. This fails
because svn_wc__db_pdh_parse_local_abspath encounters old .svn dirs
and creates pdhs with the wrong wcroot.
One way to fix this would be to revamp write_entry so that it doesn't
need to query the existing database, but that would involve caching in
memory some of the stuff we write to the database.
An alternative is to use two svn_wc__db_t handles and arrange for one
of them to ignore the old .svn directories. The following patch does
this and passes the upgrade regression tests (admittedly not much of a
test). Does this sound like a good approach?
Index: ../src/subversion/libsvn_wc/wc_db_pdh.c
===================================================================
--- ../src/subversion/libsvn_wc/wc_db_pdh.c (revision 989677)
+++ ../src/subversion/libsvn_wc/wc_db_pdh.c (working copy)
@@ -214,6 +214,7 @@
(*db)->mode = mode;
(*db)->config = config;
(*db)->auto_upgrade = auto_upgrade;
+ (*db)->ignore_1_6 = FALSE;
(*db)->enforce_empty_wq = enforce_empty_wq;
(*db)->dir_data = apr_hash_make(result_pool);
(*db)->state_pool = result_pool;
@@ -222,6 +223,13 @@
}
+void
+svn_wc__db_ignore_1_6(svn_wc__db_t *db)
+{
+ SVN_ERR_ASSERT_NO_RETURN(!apr_hash_count(db->dir_data));
+ db->ignore_1_6 = TRUE;
+}
+
svn_error_t *
svn_wc__db_close(svn_wc__db_t *db)
{
@@ -526,7 +534,7 @@
five ancetors higher. We don't test for directory presence (just
for the presence of subdirs/files), so we don't know when we can
stop checking ... so just check always. */
- if (!moved_upwards || always_check)
+ if (!db->ignore_1_6 && (!moved_upwards || always_check))
{
SVN_ERR(get_old_version(&wc_format, local_abspath, scratch_pool));
if (wc_format != 0)
Index: ../src/subversion/libsvn_wc/wc_db_private.h
===================================================================
--- ../src/subversion/libsvn_wc/wc_db_private.h (revision 989677)
+++ ../src/subversion/libsvn_wc/wc_db_private.h (working copy)
@@ -45,6 +45,8 @@
opened, and found to be not-current? */
svn_boolean_t auto_upgrade;
+ svn_boolean_t ignore_1_6;
+
/* Should we ensure the WORK_QUEUE is empty when a WCROOT is opened? */
svn_boolean_t enforce_empty_wq;
Index: ../src/subversion/libsvn_wc/wc_db.h
===================================================================
--- ../src/subversion/libsvn_wc/wc_db.h (revision 989677)
+++ ../src/subversion/libsvn_wc/wc_db.h (working copy)
@@ -2500,6 +2500,8 @@
const char *local_abspath,
apr_pool_t *scratch_pool);
+void svn_wc__db_ignore_1_6(svn_wc__db_t *db);
+
/* Internal version of svn_wc__node_get_copyfrom_info */
svn_error_t *
svn_wc__internal_get_copyfrom_info(const char **copyfrom_root_url,
Index: ../src/subversion/libsvn_wc/upgrade.c
===================================================================
--- ../src/subversion/libsvn_wc/upgrade.c (revision 989677)
+++ ../src/subversion/libsvn_wc/upgrade.c (working copy)
@@ -1198,6 +1198,7 @@
Uses SCRATCH_POOL for all temporary allocation. */
static svn_error_t *
upgrade_to_wcng(svn_wc__db_t *db,
+ svn_wc__db_t *db2,
const char *dir_abspath,
int old_format,
svn_wc_upgrade_get_repos_info_t repos_info_func,
@@ -1284,14 +1285,14 @@
entries_write_new() writes in current format rather than
f12. Thus, this function bumps a working copy all the way to
current. */
- SVN_ERR(svn_wc__db_temp_reset_format(SVN_WC__VERSION, db, dir_abspath,
+ SVN_ERR(svn_wc__db_temp_reset_format(SVN_WC__VERSION, db2, dir_abspath,
scratch_pool));
- SVN_ERR(svn_wc__db_wclock_obtain(db, dir_abspath, 0, FALSE,
+ SVN_ERR(svn_wc__db_wclock_obtain(db2, dir_abspath, 0, FALSE,
scratch_pool));
data->root_abspath = apr_pstrdup(result_pool, dir_abspath);
}
- SVN_ERR(svn_wc__write_upgraded_entries(db, data->sdb,
+ SVN_ERR(svn_wc__write_upgraded_entries(db2, data->sdb,
data->repos_id, data->wc_id,
dir_abspath, data->root_abspath,
entries,
@@ -1500,6 +1501,7 @@
/* */
static svn_error_t *
upgrade_working_copy(svn_wc__db_t *db,
+ svn_wc__db_t *db2,
const char *dir_abspath,
svn_wc_upgrade_get_repos_info_t repos_info_func,
void *repos_info_baton,
@@ -1528,7 +1530,7 @@
/* Upgrade this directory first. */
if (old_format < SVN_WC__WC_NG_VERSION)
- SVN_ERR(upgrade_to_wcng(db, dir_abspath, old_format,
+ SVN_ERR(upgrade_to_wcng(db, db2, dir_abspath, old_format,
repos_info_func, repos_info_baton,
repos_cache, data, scratch_pool, iterpool));
@@ -1545,7 +1547,7 @@
svn_pool_clear(iterpool);
- SVN_ERR(upgrade_working_copy(db, child_abspath,
+ SVN_ERR(upgrade_working_copy(db, db2, child_abspath,
repos_info_func, repos_info_baton,
repos_cache, data,
cancel_func, cancel_baton,
@@ -1570,7 +1572,7 @@
void *notify_baton,
apr_pool_t *scratch_pool)
{
- svn_wc__db_t *db;
+ svn_wc__db_t *db, *db2;
struct upgrade_data_t data = { NULL };
#if 0
svn_boolean_t is_wcroot;
@@ -1582,6 +1584,15 @@
NULL /* ### config */, FALSE, FALSE,
scratch_pool, scratch_pool));
+#ifdef SVN_WC__SINGLE_DB
+ SVN_ERR(svn_wc__db_open(&db2, svn_wc__db_openmode_readwrite,
+ NULL /* ### config */, FALSE, FALSE,
+ scratch_pool, scratch_pool));
+ svn_wc__db_ignore_1_6(db2);
+#else
+ db2 = db;
+#endif
+
/* ### this expects a wc-ng working copy. sigh. fix up soonish... */
#if 0
SVN_ERR(svn_wc__strictly_is_wc_root(&is_wcroot, wc_ctx, local_abspath,
@@ -1593,7 +1604,7 @@
#endif
/* Upgrade this directory and/or its subdirectories. */
- SVN_ERR(upgrade_working_copy(db, local_abspath,
+ SVN_ERR(upgrade_working_copy(db, db2, local_abspath,
repos_info_func, repos_info_baton,
apr_hash_make(scratch_pool), &data,
cancel_func, cancel_baton,
@@ -1601,7 +1612,8 @@
scratch_pool));
#ifdef SVN_WC__SINGLE_DB
- SVN_ERR(svn_wc__db_wclock_release(db, local_abspath, scratch_pool));
+ SVN_ERR(svn_wc__db_wclock_release(db2, local_abspath, scratch_pool));
+ SVN_ERR(svn_wc__db_close(db2));
#endif
SVN_ERR(svn_wc__db_close(db));
--
Philip
Received on 2010-08-26 16:35:19 CEST