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/06/09 20:02:42 UTC

svn commit: r953101 - in /subversion/trunk/subversion: libsvn_wc/wc_db.c tests/cmdline/switch_tests.py

Author: philip
Date: Wed Jun  9 18:02:41 2010
New Revision: 953101

URL: http://svn.apache.org/viewvc?rev=953101&view=rev
Log:
Make switch --relocate handle more node types.  This also reverts
r952728 which is no longer needed.

* subversion/libsvn_wc/wc_db.c
  (svn_wc__db_global_relocate): Handle copied/deleted/excluded nodes.
  (svn_wc__db_scan_addition): Don't expect excluded (reverts r952728).

* subversion/tests/cmdline/switch_tests.py
  (relocate_deleted_missing_copied): Extend to include a delete within
   a copy.

Modified:
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/tests/cmdline/switch_tests.py

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=953101&r1=953100&r2=953101&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Wed Jun  9 18:02:41 2010
@@ -4834,8 +4834,9 @@ svn_wc__db_global_relocate(svn_wc__db_t 
                            apr_pool_t *scratch_pool)
 {
   svn_wc__db_pdh_t *pdh;
+  svn_wc__db_status_t status;
   struct relocate_baton rb;
-  svn_sqlite__stmt_t *stmt;
+  const char *old_repos_root_url, *stored_local_dir_abspath;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_dir_abspath));
   /* ### assert that we were passed a directory?  */
@@ -4845,32 +4846,98 @@ svn_wc__db_global_relocate(svn_wc__db_t 
                               scratch_pool, scratch_pool));
   VERIFY_USABLE_PDH(pdh);
 
-  /* Get the existing repos_id of the base node, since we'll need it to
-     update a potential lock. */
-  /* ### is it faster to fetch fewer columns? */
-  SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
-                                    STMT_SELECT_BASE_NODE));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id,
-                            rb.local_relpath));
-  SVN_ERR(svn_sqlite__step(&rb.have_base_node, stmt));
-  if (rb.have_base_node)
-    {
-      rb.old_repos_id = svn_sqlite__column_int64(stmt, 0);
-      rb.repos_relpath = svn_sqlite__column_text(stmt, 1, scratch_pool);
-      SVN_ERR(svn_sqlite__reset(stmt));
+  SVN_ERR(svn_wc__db_read_info(&status,
+                               NULL, NULL,
+                               &rb.repos_relpath, &old_repos_root_url,
+                               &rb.repos_uuid,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL,
+                               db, local_dir_abspath,
+                               scratch_pool, scratch_pool));
 
-      SVN_ERR(fetch_repos_info(NULL, &rb.repos_uuid, pdh->wcroot->sdb,
-                               rb.old_repos_id, scratch_pool));
+  if (status == svn_wc__db_status_excluded)
+    {
+      /* The parent cannot be excluded, so look at the parent and then
+         adjust the relpath */
+      const char *parent_abspath = svn_dirent_dirname(local_dir_abspath,
+                                                      scratch_pool);
+      SVN_ERR(svn_wc__db_read_info(&status,
+                                   NULL, NULL,
+                                   &rb.repos_relpath, &old_repos_root_url,
+                                   &rb.repos_uuid,
+                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                   NULL, NULL, NULL, NULL,
+                                   db, parent_abspath,
+                                   scratch_pool, scratch_pool));
+      stored_local_dir_abspath = local_dir_abspath;
+      local_dir_abspath = parent_abspath;
     }
   else
+    stored_local_dir_abspath = NULL;
+
+  if (!rb.repos_relpath || !old_repos_root_url || !rb.repos_uuid)
     {
-      SVN_ERR(svn_sqlite__reset(stmt));
-      SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, &rb.repos_uuid,
-                                       NULL, NULL, NULL, NULL,
-                                       db, local_dir_abspath, scratch_pool,
-                                       scratch_pool));
+      /* Do we need to support relocating something that is
+         added/deleted/excluded without relocating the parent?  If not
+         then perhaps relpath, root_url and uuid should be passed down
+         to the children so that they don't have to scan? */
+
+      if (status == svn_wc__db_status_deleted)
+        {
+          const char *work_del_abspath;
+          SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL, NULL,
+                                           &work_del_abspath,
+                                           db, local_dir_abspath,
+                                           scratch_pool, scratch_pool));
+          if (work_del_abspath)
+            {
+              /* Deleted within a copy/move */
+              SVN_ERR_ASSERT(!stored_local_dir_abspath);
+              stored_local_dir_abspath = local_dir_abspath;
+
+              /* The parent of the delete is added. */
+              status = svn_wc__db_status_added;
+              local_dir_abspath = svn_dirent_dirname(work_del_abspath,
+                                                     scratch_pool);
+            }
+        }
+
+      if (status == svn_wc__db_status_added
+          || status == svn_wc__db_status_obstructed_add)
+        {
+          SVN_ERR(svn_wc__db_scan_addition(NULL, NULL,
+                                           &rb.repos_relpath,
+                                           &old_repos_root_url, &rb.repos_uuid,
+                                           NULL, NULL, NULL, NULL,
+                                           db, local_dir_abspath,
+                                           scratch_pool, scratch_pool));
+        }
+      else
+        SVN_ERR(svn_wc__db_scan_base_repos(&rb.repos_relpath,
+                                           &old_repos_root_url, &rb.repos_uuid,
+                                           db, local_dir_abspath,
+                                           scratch_pool, scratch_pool));
+    }
+
+  SVN_ERR_ASSERT(rb.repos_relpath && old_repos_root_url && rb.repos_uuid);
+
+  if (stored_local_dir_abspath)
+    {
+      /* Adjust to get value suitable for local_dir_abspath */
+      const char *part = svn_dirent_is_child(local_dir_abspath,
+                                             stored_local_dir_abspath,
+                                             scratch_pool);
+      rb.repos_relpath = svn_relpath_join(rb.repos_relpath, part,
+                                          scratch_pool);
+      local_dir_abspath = stored_local_dir_abspath;
     }
 
+
+  SVN_ERR(create_repos_id(&rb.old_repos_id, old_repos_root_url, rb.repos_uuid,
+                          pdh->wcroot->sdb, scratch_pool));
+
   rb.wc_id = pdh->wcroot->wc_id;
   rb.repos_root_url = repos_root_url;
 
@@ -5660,8 +5727,8 @@ svn_wc__db_scan_addition(svn_wc__db_stat
       /* Record information from the starting node.  */
       if (current_abspath == local_abspath)
         {
-          if (presence != svn_wc__db_status_normal
-              && presence != svn_wc__db_status_excluded)
+          /* The starting node should exist normally.  */
+          if (presence != svn_wc__db_status_normal)
             return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS,
                                      svn_sqlite__reset(stmt),
                                      _("Expected node '%s' to be added."),

Modified: subversion/trunk/subversion/tests/cmdline/switch_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/switch_tests.py?rev=953101&r1=953100&r2=953101&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/switch_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/switch_tests.py Wed Jun  9 18:02:41 2010
@@ -543,16 +543,26 @@ def relocate_deleted_missing_copied(sbox
   # Remove A/B/F to create a missing entry
   svntest.main.safe_rmtree(os.path.join(wc_dir, 'A', 'B', 'F'))
 
-  # Copy A/D/H to A/D/H2
-  H_path = os.path.join(wc_dir, 'A', 'D', 'H')
-  H2_path = os.path.join(wc_dir, 'A', 'D', 'H2')
+  # Copy A/D to A/D2
+  D_path = os.path.join(wc_dir, 'A', 'D')
+  D2_path = os.path.join(wc_dir, 'A', 'D2')
   svntest.actions.run_and_verify_svn(None, None, [], 'copy',
-                                     H_path, H2_path)
+                                     D_path, D2_path)
+  # Delete within the copy
+  D2G_path = os.path.join(wc_dir, 'A', 'D2', 'G')
+  svntest.actions.run_and_verify_svn(None, None, [], 'rm', D2G_path)
+
   expected_status.add({
-    'A/D/H2'       : Item(status='A ', wc_rev='-', copied='+'),
-    'A/D/H2/chi'   : Item(status='  ', wc_rev='-', copied='+'),
-    'A/D/H2/omega' : Item(status='  ', wc_rev='-', copied='+'),
-    'A/D/H2/psi'   : Item(status='  ', wc_rev='-', copied='+'),
+    'A/D2'         : Item(status='A ', wc_rev='-', copied='+'),
+    'A/D2/gamma'   : Item(status='  ', wc_rev='-', copied='+'),
+    'A/D2/G'       : Item(status='D ', wc_rev='?'),
+    'A/D2/G/pi'    : Item(status='D ', wc_rev='?'),
+    'A/D2/G/rho'   : Item(status='D ', wc_rev='?'),
+    'A/D2/G/tau'   : Item(status='D ', wc_rev='?'),
+    'A/D2/H'       : Item(status='  ', wc_rev='-', copied='+'),
+    'A/D2/H/chi'   : Item(status='  ', wc_rev='-', copied='+'),
+    'A/D2/H/omega' : Item(status='  ', wc_rev='-', copied='+'),
+    'A/D2/H/psi'   : Item(status='  ', wc_rev='-', copied='+'),
     })
   expected_status.tweak('A/B/F', status='! ', wc_rev='?')
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
@@ -574,17 +584,23 @@ def relocate_deleted_missing_copied(sbox
   expected_disk = svntest.main.greek_state.copy()
   expected_disk.remove('A/mu')
   expected_disk.add({
-    'A/D/H2'       : Item(),
-    'A/D/H2/chi'   : Item("This is the file 'chi'.\n"),
-    'A/D/H2/omega' : Item("This is the file 'omega'.\n"),
-    'A/D/H2/psi'   : Item("This is the file 'psi'.\n"),
+    'A/D2'       : Item(),
+    'A/D2/gamma'   : Item("This is the file 'gamma'.\n"),
+    'A/D2/G'       : Item(),
+    'A/D2/H'       : Item(),
+    'A/D2/H/chi'   : Item("This is the file 'chi'.\n"),
+    'A/D2/H/omega' : Item("This is the file 'omega'.\n"),
+    'A/D2/H/psi'   : Item("This is the file 'psi'.\n"),
     })
   expected_status.add({
     'A/B/F'       : Item(status='  ', wc_rev='2'),
     })
   expected_status.tweak(wc_rev=2)
-  expected_status.tweak('A/D/H2', 'A/D/H2/chi', 'A/D/H2/omega', 'A/D/H2/psi',
+  expected_status.tweak('A/D2', 'A/D2/gamma',
+                        'A/D2/H', 'A/D2/H/chi', 'A/D2/H/omega', 'A/D2/H/psi',
                         wc_rev='-')
+  expected_status.tweak('A/D2/G', 'A/D2/G/pi', 'A/D2/G/rho', 'A/D2/G/tau',
+                        wc_rev='?')
   svntest.actions.run_and_verify_update(wc_dir,
                                         expected_output,
                                         expected_disk,
@@ -592,10 +608,13 @@ def relocate_deleted_missing_copied(sbox
 
   # Commit to verify that copyfrom URLs have been relocated
   expected_output = svntest.wc.State(wc_dir, {
-    'A/D/H2'       : Item(verb='Adding'),
+    'A/D2'       : Item(verb='Adding'),
+    'A/D2/G'     : Item(verb='Deleting'),
     })
-  expected_status.tweak('A/D/H2', 'A/D/H2/chi', 'A/D/H2/omega', 'A/D/H2/psi',
+  expected_status.tweak('A/D2', 'A/D2/gamma',
+                        'A/D2/H', 'A/D2/H/chi', 'A/D2/H/omega', 'A/D2/H/psi',
                         status='  ', wc_rev='3', copied=None)
+  expected_status.remove('A/D2/G', 'A/D2/G/pi', 'A/D2/G/rho', 'A/D2/G/tau')
   svntest.actions.run_and_verify_commit(wc_dir,
                                         expected_output, expected_status,
                                         None, wc_dir)