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/17 18:43:23 UTC

svn commit: r955671 - in /subversion/trunk/subversion: libsvn_wc/wc_db.c tests/cmdline/depth_tests.py

Author: philip
Date: Thu Jun 17 16:43:23 2010
New Revision: 955671

URL: http://svn.apache.org/viewvc?rev=955671&view=rev
Log:
Make copies of copies with excluded nodes work.

* subversion/libsvn_wc/wc_db.c
  (get_info_for_copy): New, based on code from svn_wc__db_op_copy.
  (svn_wc__db_op_copy): Call get_info_for_copy.

* subversion/tests/cmdline/depth_tests.py
  (excluded_path_misc_operation): Copy a copy.

Modified:
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/tests/cmdline/depth_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=955671&r1=955670&r2=955671&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Thu Jun 17 16:43:23 2010
@@ -2521,43 +2521,27 @@ temp_cross_db_copy(svn_wc__db_t *db,
   return SVN_NO_ERROR;
 }
 
-svn_error_t *
-svn_wc__db_op_copy(svn_wc__db_t *db,
-                   const char *src_abspath,
-                   const char *dst_abspath,
-                   const svn_skel_t *work_items,
-                   apr_pool_t *scratch_pool)
+/* Set *COPYFROM_ID, *COPYFROM_RELPATH, *COPYFROM_REV to the values
+   appropriate for the copy. Also return *STATUS, *KIND and *HAVE_WORK
+   since they are available.  This is a helper for
+   svn_wc__db_op_copy. */
+static svn_error_t *
+get_info_for_copy(apr_int64_t *copyfrom_id,
+                  const char **copyfrom_relpath,
+                  svn_revnum_t *copyfrom_rev,
+                  svn_wc__db_status_t *status,
+                  svn_wc__db_kind_t *kind,
+                  svn_boolean_t *have_work,
+                  svn_wc__db_pdh_t *pdh,
+                  svn_wc__db_t *db,
+                  const char *local_abspath,
+                  apr_pool_t *result_pool,
+                  apr_pool_t *scratch_pool)
 {
-  svn_wc__db_pdh_t *src_pdh, *dst_pdh;
-  const char *src_relpath, *dst_relpath;
-  const char *repos_relpath, *repos_root_url, *repos_uuid, *copyfrom_relpath;
-  svn_revnum_t revision, copyfrom_rev;
-  svn_wc__db_status_t status, dst_status;
-  svn_boolean_t have_work;
-  apr_int64_t copyfrom_id;
-  svn_wc__db_kind_t kind;
-  const apr_array_header_t *children;
-
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(src_abspath));
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath));
-
-  /* ### This should all happen in one transaction, but that can't
-     ### happen until we move to a centralised database. */
-
-  SVN_ERR(svn_wc__db_pdh_parse_local_abspath(&src_pdh, &src_relpath, db,
-                                             src_abspath,
-                                             svn_sqlite__mode_readwrite,
-                                             scratch_pool, scratch_pool));
-  VERIFY_USABLE_PDH(src_pdh);
-
-  SVN_ERR(svn_wc__db_pdh_parse_local_abspath(&dst_pdh, &dst_relpath, db,
-                                             dst_abspath,
-                                             svn_sqlite__mode_readwrite,
-                                             scratch_pool, scratch_pool));
-  VERIFY_USABLE_PDH(dst_pdh);
-
+  const char *repos_relpath, *repos_root_url, *repos_uuid;
+  svn_revnum_t revision;
 
-  SVN_ERR(svn_wc__db_read_info(&status, &kind, &revision,
+  SVN_ERR(svn_wc__db_read_info(status, kind, &revision,
                                &repos_relpath, &repos_root_url, &repos_uuid,
                                NULL /* changed_rev */,
                                NULL /* changed_date */,
@@ -2574,20 +2558,37 @@ svn_wc__db_op_copy(svn_wc__db_t *db,
                                NULL /* original_revision */,
                                NULL /* props_mod */,
                                NULL /* have_base */,
-                               &have_work,
+                               have_work,
                                NULL /* conflicted */,
                                NULL /* lock */,
-                               db, src_abspath, scratch_pool, scratch_pool));
+                               db, local_abspath, result_pool, scratch_pool));
 
-  SVN_ERR_ASSERT(kind == svn_wc__db_kind_file || kind == svn_wc__db_kind_dir);
-
-  if (status != svn_wc__db_status_added)
+  if (*status == svn_wc__db_status_excluded)
     {
-      copyfrom_relpath = repos_relpath;
-      copyfrom_rev = revision;
-      SVN_ERR(create_repos_id(&copyfrom_id,
+      /* The parent cannot be excluded, so look at the parent and then
+         adjust the relpath */
+      const char *parent_abspath, *base_name;
+      svn_wc__db_status_t parent_status;
+      svn_wc__db_kind_t parent_kind;
+      svn_boolean_t parent_have_work;
+
+      svn_dirent_split(local_abspath, &parent_abspath, &base_name,
+                       scratch_pool);
+      SVN_ERR(get_info_for_copy(copyfrom_id, copyfrom_relpath, copyfrom_rev,
+                                &parent_status, &parent_kind, &parent_have_work,
+                                pdh, db, parent_abspath,
+                                scratch_pool, scratch_pool));
+      if (*copyfrom_relpath)
+        *copyfrom_relpath = svn_relpath_join(*copyfrom_relpath, base_name,
+                                             result_pool);
+    }
+  else if (*status != svn_wc__db_status_added)
+    {
+      *copyfrom_relpath = repos_relpath;
+      *copyfrom_rev = revision;
+      SVN_ERR(create_repos_id(copyfrom_id,
                               repos_root_url, repos_uuid,
-                              src_pdh->wcroot->sdb, scratch_pool));
+                              pdh->wcroot->sdb, scratch_pool));
     }
   else
     {
@@ -2595,36 +2596,81 @@ svn_wc__db_op_copy(svn_wc__db_t *db,
       const char *original_repos_relpath, *original_root_url, *original_uuid;
       svn_revnum_t original_revision;
 
-      SVN_ERR(svn_wc__db_scan_addition(&status, &op_root_abspath,
+      SVN_ERR(svn_wc__db_scan_addition(status, &op_root_abspath,
                                        NULL /* repos_relpath */,
                                        NULL /* repos_root_url */,
                                        NULL /* repos_uuid */,
                                        &original_repos_relpath,
                                        &original_root_url, &original_uuid,
                                        &original_revision,
-                                       db, src_abspath,
+                                       db, local_abspath,
                                        scratch_pool, scratch_pool));
 
-      if (status == svn_wc__db_status_copied
-          || status == svn_wc__db_status_moved_here)
+      if (*status == svn_wc__db_status_copied
+          || *status == svn_wc__db_status_moved_here)
         {
-          copyfrom_relpath
+          *copyfrom_relpath
             = svn_relpath_join(original_repos_relpath,
                                svn_dirent_skip_ancestor(op_root_abspath,
-                                                        src_abspath),
+                                                        local_abspath),
                                scratch_pool);
-          copyfrom_rev = original_revision;
-          SVN_ERR(create_repos_id(&copyfrom_id,
+          *copyfrom_rev = original_revision;
+          SVN_ERR(create_repos_id(copyfrom_id,
                                   original_root_url, original_uuid,
-                                  src_pdh->wcroot->sdb, scratch_pool));
+                                  pdh->wcroot->sdb, scratch_pool));
         }
       else
         {
-          copyfrom_relpath = NULL;
-          copyfrom_rev = SVN_INVALID_REVNUM;
+          *copyfrom_relpath = NULL;
+          *copyfrom_rev = SVN_INVALID_REVNUM;
+          *copyfrom_id = 0;
         }
     }
 
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__db_op_copy(svn_wc__db_t *db,
+                   const char *src_abspath,
+                   const char *dst_abspath,
+                   const svn_skel_t *work_items,
+                   apr_pool_t *scratch_pool)
+{
+  svn_wc__db_pdh_t *src_pdh, *dst_pdh;
+  const char *src_relpath, *dst_relpath, *copyfrom_relpath;
+  svn_revnum_t copyfrom_rev;
+  svn_wc__db_status_t status, dst_status;
+  svn_boolean_t have_work;
+  apr_int64_t copyfrom_id;
+  svn_wc__db_kind_t kind;
+  const apr_array_header_t *children;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(src_abspath));
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath));
+
+  /* ### This should all happen in one transaction, but that can't
+     ### happen until we move to a centralised database. */
+
+  SVN_ERR(svn_wc__db_pdh_parse_local_abspath(&src_pdh, &src_relpath, db,
+                                             src_abspath,
+                                             svn_sqlite__mode_readwrite,
+                                             scratch_pool, scratch_pool));
+  VERIFY_USABLE_PDH(src_pdh);
+
+  SVN_ERR(svn_wc__db_pdh_parse_local_abspath(&dst_pdh, &dst_relpath, db,
+                                             dst_abspath,
+                                             svn_sqlite__mode_readwrite,
+                                             scratch_pool, scratch_pool));
+  VERIFY_USABLE_PDH(dst_pdh);
+
+  SVN_ERR(get_info_for_copy(&copyfrom_id, &copyfrom_relpath, &copyfrom_rev,
+                            &status, &kind, &have_work,
+                            src_pdh, db, src_abspath,
+                            scratch_pool, scratch_pool));
+
+  SVN_ERR_ASSERT(kind == svn_wc__db_kind_file || kind == svn_wc__db_kind_dir);
+
   /* ### New status, not finished, see notes/wc-ng/copying */
   switch (status)
     {

Modified: subversion/trunk/subversion/tests/cmdline/depth_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/depth_tests.py?rev=955671&r1=955670&r2=955671&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/depth_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/depth_tests.py Thu Jun 17 16:43:23 2010
@@ -2175,6 +2175,7 @@ def excluded_path_misc_operation(sbox):
   A_path = os.path.join(wc_dir, 'A')
   B_path = os.path.join(A_path, 'B')
   L_path = os.path.join(A_path, 'L')
+  M_path = os.path.join(A_path, 'M')
   E_path = os.path.join(B_path, 'E')
   LE_path = os.path.join(L_path, 'E')
 
@@ -2211,19 +2212,27 @@ def excluded_path_misc_operation(sbox):
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'rm', '--force', L_path)
 
-  # copy A/B to A/L again, excluded entry should be copied too
+  # copy A/B to A/L and then cp A/L to A/M, excluded entry should be
+  # copied both times
   expected_output = ['A         '+L_path+'\n']
   svntest.actions.run_and_verify_svn(None, expected_output, [],
                                      'cp', B_path, L_path)
+  expected_output = ['A         '+M_path+'\n']
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'cp', L_path, M_path)
 
   # commit this copy, with an excluded item.
-  expected_output = svntest.wc.State(wc_dir, { 'A/L' : Item(verb='Adding'), })
+  expected_output = svntest.wc.State(wc_dir, { 'A/L' : Item(verb='Adding'),
+                                               'A/M' : Item(verb='Adding'), })
   expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
   expected_status.remove('A/B/E/alpha', 'A/B/E/beta', 'A/B/E')
   expected_status.add({
     'A/L'        : Item(status='  ', wc_rev=2),
     'A/L/lambda' : Item(status='  ', wc_rev=2),
     'A/L/F'      : Item(status='  ', wc_rev=2),
+    'A/M'        : Item(status='  ', wc_rev=2),
+    'A/M/lambda' : Item(status='  ', wc_rev=2),
+    'A/M/F'      : Item(status='  ', wc_rev=2),
     })
   svntest.actions.run_and_verify_commit(wc_dir,
                                         expected_output,