[prev in list] [next in list] [prev in thread] [next in thread] 

List:       subversion-cvs
Subject:    svn commit: r9238 - in trunk/subversion: libsvn_wc tests/clients/cmdline
From:       philip () tigris ! org
Date:       2004-03-30 20:52:35
Message-ID: 200403302052.i2UKqOv27051 () svn ! collab ! net
[Download RAW message or body]

Author: philip
Date: Tue Mar 30 14:52:03 2004
New Revision: 9238

Modified:
   trunk/subversion/libsvn_wc/relocate.c
   trunk/subversion/tests/clients/cmdline/switch_tests.py
Log:
Fix Debian bug 240448, make switch --relocate handle copyfrom URLs.

* subversion/libsvn_wc/relocate.c
  (relocate_entry): New function.
  (svn_wc_relocate): Call relocate_entry, use svn_wc_entry intead of
  svn_io_check_path, don't generate SVN_ERR_ENTRY_MISSING_URL.

* subversion/tests/clients/cmdline/switch_tests.py
  (relocate_deleted_missing_copied): Renamed was relocate_deleted_and_missing,
  add testing of relocate when copied directories are present.


Modified: trunk/subversion/libsvn_wc/relocate.c
==============================================================================
--- trunk/subversion/libsvn_wc/relocate.c	(original)
+++ trunk/subversion/libsvn_wc/relocate.c	Tue Mar 30 14:52:03 2004
@@ -31,6 +31,51 @@
 #include "props.h"
 
 
+/* Relocate the main URL and the copyfrom URL for ENTRY by changing FROM to
+ * TO.  ADM_ACCESS is the access baton for ENTRY.  If DO_SYNC is set then
+ * the new entry will be written to disk immediately, otherwise only the
+ * entries cache will be affected.  Calls VALIDATOR passing VALIDATOR_BATON
+ * to validate new URLs.
+ */
+static svn_error_t *
+relocate_entry (svn_wc_adm_access_t *adm_access,
+                const svn_wc_entry_t *entry,
+                const char *from,
+                const char *to,
+                svn_wc_relocation_validator_t validator,
+                void *validator_baton,
+                svn_boolean_t do_sync,
+                apr_pool_t *pool)
+{
+  svn_wc_entry_t entry2;
+  apr_uint32_t flags = 0;
+  int from_len = strlen (from);
+
+  if (entry->url && ! strncmp (entry->url, from, from_len))
+    {
+      entry2.url = apr_psprintf (svn_wc_adm_access_pool (adm_access),
+                                 "%s%s", to, entry->url + from_len);
+      if (entry->uuid)
+        SVN_ERR (validator (validator_baton, entry->uuid, entry2.url));
+      flags |= SVN_WC__ENTRY_MODIFY_URL;
+    }
+
+  if (entry->copyfrom_url && ! strncmp (entry->copyfrom_url, from, from_len))
+    {
+      entry2.copyfrom_url = apr_psprintf (svn_wc_adm_access_pool (adm_access),
+                                          "%s%s", to,
+                                          entry->copyfrom_url + from_len);
+      if (entry->uuid)
+        SVN_ERR (validator (validator_baton, entry->uuid, entry2.copyfrom_url));
+      flags |= SVN_WC__ENTRY_MODIFY_COPYFROM_URL;
+    }
+
+  if (flags)
+    SVN_ERR (svn_wc__entry_modify (adm_access, entry->name,
+                                   &entry2, flags, do_sync, pool));
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_wc_relocate (const char *path,
                  svn_wc_adm_access_t *adm_access,
@@ -41,55 +86,31 @@
                  void *validator_baton,
                  apr_pool_t *pool)
 {
-  svn_node_kind_t kind;
-  apr_hash_t *entries = NULL;
+  apr_hash_t *entries;
   apr_hash_index_t *hi;
-  int from_len;
-  svn_wc_entry_t *entry;
-
-  SVN_ERR (svn_io_check_path (path, &kind, pool));
-
-  from_len = strlen (from);
+  const svn_wc_entry_t *entry;
 
-  SVN_ERR (svn_wc_entries_read (&entries, adm_access, TRUE, pool));
+  SVN_ERR (svn_wc_entry (&entry, path, adm_access, TRUE, pool));
+  if (! entry)
+    return svn_error_create (SVN_ERR_ENTRY_NOT_FOUND, NULL, NULL);
 
-  if (kind == svn_node_file)
+  if (entry->kind == svn_node_file)
     {
-      const char *base = svn_path_basename (path, pool);
-
-      entry = apr_hash_get (entries, base, APR_HASH_KEY_STRING);
-      if (! entry)
-        return svn_error_create (SVN_ERR_ENTRY_NOT_FOUND, NULL, NULL);
-      if (! entry->url)
-        return svn_error_createf (SVN_ERR_ENTRY_MISSING_URL, NULL,
-                                  "Entry '%s' has no URL", path);
-
-      if (! strncmp (entry->url, from, from_len))
-        {
-          const char *url = apr_psprintf (svn_wc_adm_access_pool (adm_access),
-                                          "%s%s", to, entry->url + from_len);
-          if (entry->uuid)
-            SVN_ERR (validator (validator_baton, entry->uuid, url));
-          entry->url = url;
-          SVN_ERR (svn_wc__entries_write (entries, adm_access, pool));
-        }
-
+      SVN_ERR (relocate_entry (adm_access, entry, from, to,
+                               validator, validator_baton, TRUE /* sync */,
+                               pool));
       return SVN_NO_ERROR;
     }
 
   /* Relocate THIS_DIR first, in order to pre-validate the relocated URL
-     of all of the other entries.  This is technically cheating, but it
+     of all of the other entries.  This is technically cheating because
+     it relies on knowledge of the libsvn_client implementation, but it
      significantly cuts down on the number of expensive validations the
-     validator has to do. */
+     validator has to do.  ### Should svn_wc.h document the ordering? */
+  SVN_ERR (svn_wc_entries_read (&entries, adm_access, TRUE, pool));
   entry = apr_hash_get (entries, SVN_WC_ENTRY_THIS_DIR, APR_HASH_KEY_STRING);
-  if (entry->url && (strncmp (entry->url, from, from_len) == 0)) 
-    {
-      const char *url = apr_psprintf (svn_wc_adm_access_pool (adm_access),
-                                      "%s%s", to, entry->url + from_len);
-      if (entry->uuid)
-        SVN_ERR (validator (validator_baton, entry->uuid, url));
-      entry->url = url;
-    }
+  SVN_ERR (relocate_entry (adm_access, entry, from, to,
+                           validator, validator_baton, FALSE, pool));
 
   for (hi = apr_hash_first (pool, entries); hi; hi = apr_hash_next (hi))
     {
@@ -114,15 +135,8 @@
                                     recurse, validator, 
                                     validator_baton, pool));
         }
-
-      if (entry->url && (strncmp (entry->url, from, from_len) == 0)) 
-        {
-          char *url = apr_psprintf (svn_wc_adm_access_pool (adm_access),
-                                    "%s%s", to, entry->url + from_len);
-          if (entry->uuid)
-            SVN_ERR (validator (validator_baton, entry->uuid, url));
-          entry->url = url;
-        }
+      SVN_ERR (relocate_entry (adm_access, entry, from, to,
+                               validator, validator_baton, FALSE, pool));
     }
 
   SVN_ERR (svn_wc__remove_wcprops (adm_access, FALSE, pool));

Modified: trunk/subversion/tests/clients/cmdline/switch_tests.py
==============================================================================
--- trunk/subversion/tests/clients/cmdline/switch_tests.py	(original)
+++ trunk/subversion/tests/clients/cmdline/switch_tests.py	Tue Mar 30 14:52:03 2004
@@ -516,8 +516,8 @@
 
 #----------------------------------------------------------------------
 
-def relocate_deleted_and_missing(sbox):
-  "switch --relocate with deleted and missing entries"
+def relocate_deleted_missing_copied(sbox):
+  "relocate with deleted, missing and copied entries"
   sbox.build()
   wc_dir = sbox.wc_dir
 
@@ -538,6 +538,20 @@
 
   # 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')
+  svntest.actions.run_and_verify_svn(None, None, [], 'copy',
+                                     H_path, H2_path)
+  expected_status.add({
+    'A/D/H2'       : Item(status='A ', wc_rev='-', copied='+', repos_rev=2),
+    'A/D/H2/chi'   : Item(status='  ', wc_rev='-', copied='+', repos_rev=2),
+    'A/D/H2/omega' : Item(status='  ', wc_rev='-', copied='+', repos_rev=2),
+    'A/D/H2/psi'   : Item(status='  ', wc_rev='-', copied='+', repos_rev=2),
+    })
+  expected_status.remove('A/B/F')
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
                                          
   # Relocate
   repo_dir = sbox.repo_dir
@@ -555,12 +569,39 @@
     })
   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'."),
+    'A/D/H2/omega' : Item("This is the file 'omega'."),
+    'A/D/H2/psi'   : Item("This is the file 'psi'."),
+    })
+  expected_status.add({
+    'A/B/F'       : Item(status='  ', wc_rev='2', repos_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',
+                        wc_rev='-')
   svntest.actions.run_and_verify_update(wc_dir,
                                         expected_output,
                                         expected_disk,
                                         expected_status)  
 
+  # Commit to verify that copyfrom URLs have been relocated
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/D/H2'       : Item(verb='Adding'),
+    'A/D/H2/chi'   : Item(verb='Adding'),
+    'A/D/H2/omega' : Item(verb='Adding'),
+    'A/D/H2/psi'   : Item(verb='Adding'),
+    })
+  expected_status.tweak('A/D/H2', 'A/D/H2/chi', 'A/D/H2/omega', 'A/D/H2/psi',
+                        status='  ', wc_rev='3', copied=None)
+  expected_status.tweak(repos_rev=3)
+  svntest.actions.run_and_verify_commit (wc_dir,
+                                         expected_output, expected_status,
+                                         None, None, None, None, None,
+                                         wc_dir)
+
+
 #----------------------------------------------------------------------
 
 def delete_subdir(sbox):
@@ -763,7 +804,7 @@
               update_switched_things,
               rev_update_switched_things,
               log_switched_file,
-              relocate_deleted_and_missing,
+              relocate_deleted_missing_copied,
               delete_subdir,
               XFail(file_dir_file),
               nonrecursive_switching,

---------------------------------------------------------------------
To unsubscribe, e-mail: svn-unsubscribe@subversion.tigris.org
For additional commands, e-mail: svn-help@subversion.tigris.org

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic