You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ph...@apache.org on 2010/08/31 13:50:01 UTC

svn commit: r991160 - in /subversion/trunk/subversion/libsvn_wc: entries.c entries.h upgrade.c

Author: philip
Date: Tue Aug 31 11:50:01 2010
New Revision: 991160

URL: http://svn.apache.org/viewvc?rev=991160&view=rev
Log:
Make single-db upgrades write to a temporary admin directory.  This is
a work-in-progress and the code is ugly, but it passes the tests.

* subversion/libsvn_wc/entries.h
  (svn_wc__write_upgraded_entries): Rename two parameters.

* subversion/libsvn_wc/entries.c
  (entries_write_baton): Rename two members.
  (entries_write_new_cb): Adjust relpath calculation to handle
   temporary admin dir.
  (svn_wc__write_upgraded_entries): Rename two parameters.


* subversion/libsvn_wc/upgrade.c
  (migrate_node_props, migrate_props): Rename a parameter, adjust relpath
   calculation.
  (migrate_text_bases): Rename a parameter for consistency with other
   functions.
  (upgrade_to_wcng): Construct db in temporary dir.
  (svn_wc_upgrade): Move db and pristine to final location.

Modified:
    subversion/trunk/subversion/libsvn_wc/entries.c
    subversion/trunk/subversion/libsvn_wc/entries.h
    subversion/trunk/subversion/libsvn_wc/upgrade.c

Modified: subversion/trunk/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/entries.c?rev=991160&r1=991159&r2=991160&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/entries.c (original)
+++ subversion/trunk/subversion/libsvn_wc/entries.c Tue Aug 31 11:50:01 2010
@@ -2402,8 +2402,8 @@ struct entries_write_baton
   svn_wc__db_t *db;
   apr_int64_t repos_id;
   apr_int64_t wc_id;
-  const char *local_abspath;
-  const char *root_abspath;
+  const char *dir_abspath;
+  const char *new_root_abspath;
   apr_hash_t *entries;
 };
 
@@ -2416,12 +2416,12 @@ entries_write_new_cb(void *baton,
 {
   struct entries_write_baton *ewb = baton;
   svn_wc__db_t *db = ewb->db;
-  const char *local_abspath = ewb->local_abspath;
-  const char *root_abspath = ewb->root_abspath;
+  const char *dir_abspath = ewb->dir_abspath;
+  const char *new_root_abspath = ewb->new_root_abspath;
   const svn_wc_entry_t *this_dir;
   apr_hash_index_t *hi;
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-  const char *repos_root;
+  const char *repos_root, *old_root_abspath, *dir_relpath;
 
   /* Get a copy of the "this dir" entry for comparison purposes. */
   this_dir = apr_hash_get(ewb->entries, SVN_WC_ENTRY_THIS_DIR,
@@ -2431,15 +2431,24 @@ entries_write_new_cb(void *baton,
   if (! this_dir)
     return svn_error_createf(SVN_ERR_ENTRY_NOT_FOUND, NULL,
                              _("No default entry in directory '%s'"),
-                             svn_dirent_local_style(local_abspath,
+                             svn_dirent_local_style(dir_abspath,
                                                     iterpool));
   repos_root = this_dir->repos;
 
+  old_root_abspath = svn_dirent_get_longest_ancestor(dir_abspath,
+                                                     new_root_abspath,
+                                                     scratch_pool);
+
+  SVN_ERR_ASSERT(old_root_abspath[0]);
+
+  dir_relpath = svn_dirent_skip_ancestor(old_root_abspath, dir_abspath);
+
   /* Write out "this dir" */
   SVN_ERR(write_entry(db, sdb, ewb->wc_id, ewb->repos_id, repos_root,
                       this_dir,
-                      svn_dirent_skip_ancestor(root_abspath, local_abspath),
-                      local_abspath,
+                      dir_relpath,
+                      svn_dirent_join(new_root_abspath, dir_relpath,
+                                      scratch_pool),
                       this_dir, FALSE, FALSE, iterpool));
 
   for (hi = apr_hash_first(scratch_pool, ewb->entries); hi;
@@ -2447,7 +2456,7 @@ entries_write_new_cb(void *baton,
     {
       const char *name = svn__apr_hash_index_key(hi);
       const svn_wc_entry_t *this_entry = svn__apr_hash_index_val(hi);
-      const char *child_abspath;
+      const char *child_abspath, *child_relpath;
 
       svn_pool_clear(iterpool);
 
@@ -2457,11 +2466,14 @@ entries_write_new_cb(void *baton,
 
       /* Write the entry. Pass TRUE for create locks, because we still
          use this function for upgrading old working copies. */
-      child_abspath = svn_dirent_join(local_abspath, name, iterpool);
+      child_abspath = svn_dirent_join(dir_abspath, name, iterpool);
+      child_relpath = svn_dirent_skip_ancestor(old_root_abspath, child_abspath);
       SVN_ERR(write_entry(db, sdb, ewb->wc_id, ewb->repos_id, repos_root,
                           this_entry,
-                          svn_dirent_skip_ancestor(root_abspath, child_abspath),
-                          child_abspath, this_dir,
+                          child_relpath,
+                          svn_dirent_join(new_root_abspath, child_relpath,
+                                          scratch_pool),
+                          this_dir,
                           FALSE, TRUE,
                           iterpool));
     }
@@ -2476,8 +2488,8 @@ svn_wc__write_upgraded_entries(svn_wc__d
                                svn_sqlite__db_t *sdb,
                                apr_int64_t repos_id,
                                apr_int64_t wc_id,
-                               const char *local_abspath,
-                               const char *root_abspath,
+                               const char *dir_abspath,
+                               const char *new_root_abspath,
                                apr_hash_t *entries,
                                apr_pool_t *scratch_pool)
 {
@@ -2486,8 +2498,8 @@ svn_wc__write_upgraded_entries(svn_wc__d
   ewb.db = db;
   ewb.repos_id = repos_id;
   ewb.wc_id = wc_id;
-  ewb.local_abspath = local_abspath;
-  ewb.root_abspath = root_abspath;
+  ewb.dir_abspath = dir_abspath;
+  ewb.new_root_abspath = new_root_abspath;
   ewb.entries = entries;
 
   /* Run this operation in a transaction to speed up SQLite.

Modified: subversion/trunk/subversion/libsvn_wc/entries.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/entries.h?rev=991160&r1=991159&r2=991160&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/entries.h (original)
+++ subversion/trunk/subversion/libsvn_wc/entries.h Tue Aug 31 11:50:01 2010
@@ -105,7 +105,7 @@ svn_wc__write_upgraded_entries(svn_wc__d
                                apr_int64_t repos_id,
                                apr_int64_t wc_id,
                                const char *dir_abspath,
-                               const char *root_abspath,
+                               const char *new_root_abspath,
                                apr_hash_t *entries,
                                apr_pool_t *scratch_pool);
 

Modified: subversion/trunk/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/upgrade.c?rev=991160&r1=991159&r2=991160&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/trunk/subversion/libsvn_wc/upgrade.c Tue Aug 31 11:50:01 2010
@@ -67,6 +67,7 @@
 
 /* New pristine location */
 #define PRISTINE_STORAGE_RELPATH "pristine"
+#define SDB_FILE  "wc.db"
 
 
 /* Read the properties from the file at PROPFILE_ABSPATH, returning them
@@ -914,7 +915,7 @@ bump_to_16(void *baton, svn_sqlite__db_t
 
 /* Migrate the properties for one node (LOCAL_ABSPATH).  */
 static svn_error_t *
-migrate_node_props(const char *old_wcroot_abspath,
+migrate_node_props(const char *dir_abspath,
                    const char *new_wcroot_abspath,
                    const char *name,
                    svn_sqlite__db_t *sdb,
@@ -927,16 +928,19 @@ migrate_node_props(const char *old_wcroo
   apr_hash_t *base_props;
   apr_hash_t *revert_props;
   apr_hash_t *working_props;
-  const char *dir_relpath = svn_dirent_skip_ancestor(new_wcroot_abspath,
-                                                     old_wcroot_abspath);
+  const char *old_wcroot_abspath
+    = svn_dirent_get_longest_ancestor(dir_abspath, new_wcroot_abspath,
+                                      scratch_pool);
+  const char *dir_relpath = svn_dirent_skip_ancestor(old_wcroot_abspath,
+                                                     dir_abspath);
 
   if (*name == '\0')
     {
-      base_abspath = svn_wc__adm_child(old_wcroot_abspath,
+      base_abspath = svn_wc__adm_child(dir_abspath,
                                        PROP_BASE_FOR_DIR, scratch_pool);
-      revert_abspath = svn_wc__adm_child(old_wcroot_abspath,
+      revert_abspath = svn_wc__adm_child(dir_abspath,
                                          PROP_REVERT_FOR_DIR, scratch_pool);
-      working_abspath = svn_wc__adm_child(old_wcroot_abspath,
+      working_abspath = svn_wc__adm_child(dir_abspath,
                                           PROP_WORKING_FOR_DIR, scratch_pool);
     }
   else
@@ -944,9 +948,9 @@ migrate_node_props(const char *old_wcroo
       const char *basedir_abspath;
       const char *propsdir_abspath;
 
-      propsdir_abspath = svn_wc__adm_child(old_wcroot_abspath, PROPS_SUBDIR,
+      propsdir_abspath = svn_wc__adm_child(dir_abspath, PROPS_SUBDIR,
                                            scratch_pool);
-      basedir_abspath = svn_wc__adm_child(old_wcroot_abspath, PROP_BASE_SUBDIR,
+      basedir_abspath = svn_wc__adm_child(dir_abspath, PROP_BASE_SUBDIR,
                                           scratch_pool);
 
       base_abspath = svn_dirent_join(basedir_abspath,
@@ -989,7 +993,7 @@ migrate_node_props(const char *old_wcroo
 
 /* */
 static svn_error_t *
-migrate_props(const char *old_wcroot_abspath,
+migrate_props(const char *dir_abspath,
               const char *new_wcroot_abspath,
               svn_sqlite__db_t *sdb,
               int original_format,
@@ -1017,12 +1021,15 @@ migrate_props(const char *old_wcroot_abs
   */
   const apr_array_header_t *children;
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-  const char *dir_relpath = svn_dirent_skip_ancestor(new_wcroot_abspath,
-                                                     old_wcroot_abspath);
+  const char *old_wcroot_abspath
+    = svn_dirent_get_longest_ancestor(dir_abspath, new_wcroot_abspath,
+                                      scratch_pool);
+  const char *dir_relpath = svn_dirent_skip_ancestor(old_wcroot_abspath,
+                                                     dir_abspath);
   int i;
 
   /* Migrate the props for "this dir".  */
-  SVN_ERR(migrate_node_props(old_wcroot_abspath, new_wcroot_abspath, "", sdb,
+  SVN_ERR(migrate_node_props(dir_abspath, new_wcroot_abspath, "", sdb,
                              original_format, iterpool));
 
   /* Iterate over all the files in this SDB.  */
@@ -1034,7 +1041,7 @@ migrate_props(const char *old_wcroot_abs
 
       svn_pool_clear(iterpool);
 
-      SVN_ERR(migrate_node_props(old_wcroot_abspath, new_wcroot_abspath,
+      SVN_ERR(migrate_node_props(dir_abspath, new_wcroot_abspath,
                                  name, sdb, original_format, iterpool));
     }
 
@@ -1068,7 +1075,7 @@ bump_to_18(void *baton, svn_sqlite__db_t
 
 
 static svn_error_t *
-migrate_text_bases(const char *old_wcroot_abspath,
+migrate_text_bases(const char *dir_abspath,
                    const char *new_wcroot_abspath,
                    svn_sqlite__db_t *sdb,
                    apr_pool_t *scratch_pool)
@@ -1076,7 +1083,7 @@ migrate_text_bases(const char *old_wcroo
   apr_hash_t *dirents;
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   apr_hash_index_t *hi;
-  const char *text_base_dir = svn_wc__adm_child(old_wcroot_abspath,
+  const char *text_base_dir = svn_wc__adm_child(dir_abspath,
                                                 TEXT_BASE_SUBDIR,
                                                 scratch_pool);
 
@@ -1271,10 +1278,25 @@ upgrade_to_wcng(svn_wc__db_t *db,
 
   if (!data->sdb)
     {
+#ifdef SVN_WC__SINGLE_DB
+      const char *root_adm_abspath;
+
+      /* In root wc construst path to temporary root wc/.svn/wcng/.svn
+
+         ### This should really be in tmp so that 1.6 can cleanup if
+             interrupted, i.e. wc/.svn/tmp/wcng/.svn */
+      data->root_abspath = svn_wc__adm_child(dir_abspath, "wcng", result_pool);
+      root_adm_abspath = svn_wc__adm_child(data->root_abspath, "",
+                                           scratch_pool);
+      SVN_ERR(svn_wc__ensure_directory(root_adm_abspath, scratch_pool));
+#else
+      data->root_abspath = apr_pstrdup(result_pool, dir_abspath);
+#endif
+
       /* Create an empty sqlite database for this directory. */
       SVN_ERR(svn_wc__db_upgrade_begin(&data->sdb,
                                        &data->repos_id, &data->wc_id,
-                                       dir_abspath,
+                                       data->root_abspath,
                                        this_dir->repos, this_dir->uuid,
                                        result_pool, scratch_pool));
 
@@ -1284,11 +1306,10 @@ upgrade_to_wcng(svn_wc__db_t *db,
          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,
-                                           scratch_pool));
-      SVN_ERR(svn_wc__db_wclock_obtain(db, dir_abspath, 0, FALSE,
+      SVN_ERR(svn_wc__db_temp_reset_format(SVN_WC__VERSION, db,
+                                           data->root_abspath, scratch_pool));
+      SVN_ERR(svn_wc__db_wclock_obtain(db, data->root_abspath, 0, FALSE,
                                        scratch_pool));
-      data->root_abspath = apr_pstrdup(result_pool, dir_abspath);
     }
  
   SVN_ERR(svn_wc__write_upgraded_entries(db, data->sdb,
@@ -1303,7 +1324,10 @@ upgrade_to_wcng(svn_wc__db_t *db,
   if (old_format != SVN_WC__WCPROPS_LOST)
     {
       apr_hash_t *all_wcprops;
-      const char *dir_relpath = svn_dirent_skip_ancestor(data->root_abspath,
+      const char *old_wcroot_abspath
+        = svn_dirent_get_longest_ancestor(dir_abspath, data->root_abspath,
+                                          scratch_pool);
+      const char *dir_relpath = svn_dirent_skip_ancestor(old_wcroot_abspath,
                                                          dir_abspath);
 
       if (old_format <= SVN_WC__WCPROPS_MANY_FILES_VERSION)
@@ -1351,7 +1375,7 @@ upgrade_to_wcng(svn_wc__db_t *db,
 
 #ifdef SVN_WC__SINGLE_DB
   /* Remove the admin dir in subdirectories of the root. */
-  if (strcmp(data->root_abspath, dir_abspath))
+  if (!svn_dirent_is_ancestor(dir_abspath, data->root_abspath))
     svn_error_clear(svn_io_remove_dir2(svn_wc__adm_child(dir_abspath, NULL,
                                                          scratch_pool),
                                        FALSE, NULL, NULL, scratch_pool));
@@ -1601,7 +1625,28 @@ svn_wc_upgrade(svn_wc_context_t *wc_ctx,
                                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(db, data.root_abspath, scratch_pool));
+  SVN_ERR(svn_wc__db_drop_root(db, data.root_abspath, scratch_pool));
+  {
+    const char *pristine_from = svn_wc__adm_child(data.root_abspath,
+                                                  PRISTINE_STORAGE_RELPATH,
+                                                  scratch_pool);
+    const char *pristine_to = svn_wc__adm_child(local_abspath,
+                                                PRISTINE_STORAGE_RELPATH,
+                                                scratch_pool);
+    SVN_ERR(svn_io_file_rename(pristine_from, pristine_to, scratch_pool));
+  }
+  {
+    const char *db_from = svn_wc__adm_child(data.root_abspath, SDB_FILE,
+                                            scratch_pool);
+    const char *db_to = svn_wc__adm_child(local_abspath, SDB_FILE,
+                                          scratch_pool);
+    SVN_ERR(svn_io_file_rename(db_from, db_to, scratch_pool));
+  }
+  {
+    SVN_ERR(svn_io_remove_dir2(data.root_abspath, FALSE, NULL, NULL,
+                               scratch_pool));
+  }
 #endif
 
   SVN_ERR(svn_wc__db_close(db));