Author: rhuijben
Date: Thu Oct 11 16:21:42 2012
New Revision: 1397145

URL: http://svn.apache.org/viewvc?rev=1397145&view=rev
Log:
Integrate 3 private libsvn_wc functions that report about node states that we
used to call hidden. Use the resulting function in both 'svn cp' to working
copy scenarios to improve error handling.

* subversion/include/private/svn_wc_private.h
  (svn_wc__node_is_status_server_excluded,
   svn_wc__node_is_status_not_present,
   svn_wc__node_is_status_excluded): Replace by a single function called ...
  (svn_wc__node_is_not_present): ... this, with three optional output
    arguments.

* subversion/libsvn_client/commit_util.c
  (harvest_not_present_for_copy): Update caller.

* subversion/libsvn_client/copy.c
  (verify_wc_srcs_and_dsts,
   repos_to_wc_copy_locked): Use similar code based on the wc.db state to
     determine whether a copy/move destination is valid. Only return
     SVN_ERR_ENTRY_EXISTS if a copy as child should be performed.

* subversion/libsvn_wc/node.c
  (svn_wc__node_is_status_server_excluded,
   svn_wc__node_is_status_not_present,
   svn_wc__node_is_status_excluded): Replace by a single function called ...
  (svn_wc__node_is_not_present): ... this, with three optional output
    arguments.

* subversion/tests/cmdline/copy_tests.py
  (copy_over_excluded): New function, partially based on problems described as
    part of issue 2843.
  (test_list): Add test.

Modified:
    subversion/trunk/subversion/include/private/svn_wc_private.h
    subversion/trunk/subversion/libsvn_client/commit_util.c
    subversion/trunk/subversion/libsvn_client/copy.c
    subversion/trunk/subversion/libsvn_wc/node.c
    subversion/trunk/subversion/tests/cmdline/copy_tests.py

Modified: subversion/trunk/subversion/include/private/svn_wc_private.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_wc_private.h?rev=1397145&r1=1397144&r2=1397145&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_wc_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_wc_private.h Thu Oct 11 
16:21:42 2012
@@ -557,42 +557,25 @@ svn_wc__node_get_deleted_ancestor(const 
                                   apr_pool_t *scratch_pool);
 
 /**
- * Set @a *is_server_excluded to whether @a local_abspath has been
- * excluded by the server, using @a wc_ctx.  If @a local_abspath is not
- * in the working copy, return @c SVN_ERR_WC_PATH_NOT_FOUND.
- * Use @a scratch_pool for all temporary allocations.
- */
-svn_error_t *
-svn_wc__node_is_status_server_excluded(svn_boolean_t *is_server_excluded,
-                                       svn_wc_context_t *wc_ctx,
-                                       const char *local_abspath,
-                                       apr_pool_t *scratch_pool);
-
-/**
- * Set @a *is_not_present to whether the status of @a local_abspath is
- * #svn_wc__db_status_not_present, using @a wc_ctx.
- * If @a local_abspath is not in the working copy, return
- * @c SVN_ERR_WC_PATH_NOT_FOUND.  Use @a scratch_pool for all temporary
- * allocations.
- */
-svn_error_t *
-svn_wc__node_is_status_not_present(svn_boolean_t *is_not_present,
-                                   svn_wc_context_t *wc_ctx,
-                                   const char *local_abspath,
-                                   apr_pool_t *scratch_pool);
-
-/**
- * Set @a *is_excluded to whether the status of @a local_abspath is
- * #svn_wc__db_status_excluded, using @a wc_ctx.
+ * Set @a *not_present to TRUE when @a local_abspath has status
+ * svn_wc__db_status_not_present. Set @a *user_excluded to TRUE when
+ * @a local_abspath has status svn_wc__db_status_excluded. Set
+ * @a *server_excluded to TRUE when @a local_abspath has status
+ * svn_wc__db_status_server_excluded. Otherwise set these values to FALSE.
+ *
+ * If a value is not interesting you can pass #NULL.
+ *
  * If @a local_abspath is not in the working copy, return
  * @c SVN_ERR_WC_PATH_NOT_FOUND.  Use @a scratch_pool for all temporary
  * allocations.
  */
 svn_error_t *
-svn_wc__node_is_status_excluded(svn_boolean_t *is_excluded,
-                                   svn_wc_context_t *wc_ctx,
-                                   const char *local_abspath,
-                                   apr_pool_t *scratch_pool);
+svn_wc__node_is_not_present(svn_boolean_t *not_present,
+                            svn_boolean_t *user_excluded,
+                            svn_boolean_t *server_excluded,
+                            svn_wc_context_t *wc_ctx,
+                            const char *local_abspath,
+                            apr_pool_t *scratch_pool);
 
 /**
  * Set @a *is_added to whether @a local_abspath is added, using

Modified: subversion/trunk/subversion/libsvn_client/commit_util.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/commit_util.c?rev=1397145&r1=1397144&r2=1397145&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/commit_util.c (original)
+++ subversion/trunk/subversion/libsvn_client/commit_util.c Thu Oct 11 16:21:42 
2012
@@ -482,8 +482,8 @@ harvest_not_present_for_copy(svn_wc_cont
 
       svn_pool_clear(iterpool);
 
-      SVN_ERR(svn_wc__node_is_status_not_present(&not_present, wc_ctx,
-                                                  this_abspath, scratch_pool));
+      SVN_ERR(svn_wc__node_is_not_present(&not_present, NULL, NULL, wc_ctx,
+                                          this_abspath, scratch_pool));
 
       if (!not_present)
         continue;

Modified: subversion/trunk/subversion/libsvn_client/copy.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/copy.c?rev=1397145&r1=1397144&r2=1397145&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/copy.c (original)
+++ subversion/trunk/subversion/libsvn_client/copy.c Thu Oct 11 16:21:42 2012
@@ -397,11 +397,30 @@ verify_wc_srcs_and_dsts(const apr_array_
       /* If DST_PATH does not exist, then its basename will become a new
          file or dir added to its parent (possibly an implicit '.').
          Else, just error out. */
-      SVN_ERR(svn_io_check_path(pair->dst_abspath_or_url, &dst_kind,
-                                iterpool));
+      SVN_ERR(svn_wc_read_kind(&dst_kind, ctx->wc_ctx,
+                               pair->dst_abspath_or_url, TRUE /* show_hidden 
*/,
+                               iterpool));
       if (dst_kind != svn_node_none)
         {
-          if (is_move
+          svn_boolean_t is_not_present;
+          svn_boolean_t is_excluded;
+          svn_boolean_t is_server_excluded;
+
+          SVN_ERR(svn_wc__node_is_not_present(&is_not_present, &is_excluded,
+                                              &is_server_excluded, ctx->wc_ctx,
+                                              pair->dst_abspath_or_url,
+                                              iterpool));
+
+          if (is_excluded || is_server_excluded)
+            {
+              return svn_error_createf(
+                  SVN_ERR_WC_OBSTRUCTED_UPDATE,
+                  NULL, _("Path '%s' exists, but is excluded"),
+                  svn_dirent_local_style(pair->dst_abspath_or_url, iterpool));
+            }
+
+          if ((! is_not_present)
+              && is_move
               && copy_pairs->nelts == 1
               && strcmp(svn_dirent_dirname(pair->src_abspath_or_url, iterpool),
                         svn_dirent_dirname(pair->dst_abspath_or_url,
@@ -440,10 +459,20 @@ verify_wc_srcs_and_dsts(const apr_array_
                 }
             }
 
-          return svn_error_createf(
-                      SVN_ERR_ENTRY_EXISTS, NULL,
-                      _("Path '%s' already exists"),
-                      svn_dirent_local_style(pair->dst_abspath_or_url, pool));
+          if (! is_not_present)
+            {
+              svn_boolean_t is_deleted;
+
+              SVN_ERR(svn_wc__node_is_status_deleted(&is_deleted, ctx->wc_ctx,
+                                                     pair->dst_abspath_or_url, 
pool));
+
+              if (! is_deleted)
+                return svn_error_createf(
+                            SVN_ERR_ENTRY_EXISTS, NULL,
+                            _("Path '%s' already exists"),
+                            svn_dirent_local_style(pair->dst_abspath_or_url,
+                                                   pool));
+            }
         }
 
       svn_dirent_split(&pair->dst_parent_abspath, &pair->base_name,
@@ -1621,13 +1650,15 @@ repos_to_wc_copy_locked(const apr_array_
       svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
                                                     svn_client__copy_pair_t *);
       svn_node_kind_t kind;
+      svn_boolean_t is_not_present;
       svn_boolean_t is_excluded;
       svn_boolean_t is_server_excluded;
+      svn_boolean_t is_deleted;
 
       svn_pool_clear(iterpool);
 
       SVN_ERR(svn_wc_read_kind(&kind, ctx->wc_ctx, pair->dst_abspath_or_url,
-                               FALSE, iterpool));
+                               TRUE /* show_hidden */, iterpool));
       if (kind == svn_node_none)
         continue;
 
@@ -1635,48 +1666,34 @@ repos_to_wc_copy_locked(const apr_array_
          ### simplify the conditions? */
 
       /* Hidden by client exclusion */
-      SVN_ERR(svn_wc__node_is_status_excluded(&is_excluded, ctx->wc_ctx,
-                                              pair->dst_abspath_or_url,
-                                              iterpool));
-      if (is_excluded)
-        {
-          return svn_error_createf
-            (SVN_ERR_ENTRY_EXISTS,
-             NULL, _("'%s' is already under version control"),
-             svn_dirent_local_style(pair->dst_abspath_or_url, iterpool));
-        }
+      SVN_ERR(svn_wc__node_is_not_present(&is_not_present, &is_excluded,
+                                          &is_server_excluded, ctx->wc_ctx,
+                                          pair->dst_abspath_or_url,
+                                          iterpool));
 
-      /* Hidden by server exclusion (not authorized) */
-      SVN_ERR(svn_wc__node_is_status_server_excluded(&is_server_excluded,
-                                                     ctx->wc_ctx,
-                                                     pair->dst_abspath_or_url,
-                                                     iterpool));
-      if (is_server_excluded)
-        {
-          return svn_error_createf
-            (SVN_ERR_ENTRY_EXISTS,
-             NULL, _("'%s' is already under version control"),
+      if (is_not_present)
+        continue;
+
+      if (is_excluded || is_server_excluded)
+        {
+          return svn_error_createf(
+             SVN_ERR_WC_OBSTRUCTED_UPDATE,
+             NULL, _("Path '%s' exists, but is excluded"),
              svn_dirent_local_style(pair->dst_abspath_or_url, iterpool));
         }
 
       /* Working file missing to something other than being scheduled
          for addition or in "deleted" state. */
-      if (kind != svn_node_dir)
-        {
-          svn_boolean_t is_deleted;
-          svn_boolean_t is_not_present;
 
-          SVN_ERR(svn_wc__node_is_status_deleted(&is_deleted, ctx->wc_ctx,
-                                                 pair->dst_abspath_or_url,
-                                                 iterpool));
-          SVN_ERR(svn_wc__node_is_status_not_present(&is_not_present,
-                                                     ctx->wc_ctx,
-                                                     pair->dst_abspath_or_url,
-                                                     iterpool));
-          if ((! is_deleted) && (! is_not_present))
-            return svn_error_createf
-              (SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
-               _("Entry for '%s' exists (though the working file is missing)"),
+      SVN_ERR(svn_wc__node_is_status_deleted(&is_deleted, ctx->wc_ctx,
+                                             pair->dst_abspath_or_url,
+                                             iterpool));
+
+      if (! is_deleted)
+        {
+          return svn_error_createf(
+               SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
+               _("Path '%s' exists, but the working file is missing"),
                svn_dirent_local_style(pair->dst_abspath_or_url, iterpool));
         }
     }

Modified: subversion/trunk/subversion/libsvn_wc/node.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/node.c?rev=1397145&r1=1397144&r2=1397145&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/node.c (original)
+++ subversion/trunk/subversion/libsvn_wc/node.c Thu Oct 11 16:21:42 2012
@@ -768,30 +768,12 @@ svn_wc__node_get_deleted_ancestor(const 
 }
 
 svn_error_t *
-svn_wc__node_is_status_server_excluded(svn_boolean_t *is_server_excluded,
-                                       svn_wc_context_t *wc_ctx,
-                                       const char *local_abspath,
-                                       apr_pool_t *scratch_pool)
-{
-  svn_wc__db_status_t status;
-
-  SVN_ERR(svn_wc__db_read_info(&status,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL,
-                               wc_ctx->db, local_abspath,
-                               scratch_pool, scratch_pool));
-  *is_server_excluded = (status == svn_wc__db_status_server_excluded);
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_wc__node_is_status_not_present(svn_boolean_t *is_not_present,
-                                   svn_wc_context_t *wc_ctx,
-                                   const char *local_abspath,
-                                   apr_pool_t *scratch_pool)
+svn_wc__node_is_not_present(svn_boolean_t *is_not_present,
+                            svn_boolean_t *is_excluded,
+                            svn_boolean_t *is_server_excluded,
+                            svn_wc_context_t *wc_ctx,
+                            const char *local_abspath,
+                            apr_pool_t *scratch_pool)
 {
   svn_wc__db_status_t status;
 
@@ -802,27 +784,15 @@ svn_wc__node_is_status_not_present(svn_b
                                NULL, NULL, NULL, NULL, NULL,
                                wc_ctx->db, local_abspath,
                                scratch_pool, scratch_pool));
-  *is_not_present = (status == svn_wc__db_status_not_present);
 
-  return SVN_NO_ERROR;
-}
+  if (is_not_present)
+    *is_not_present = (status == svn_wc__db_status_not_present);
 
-svn_error_t *
-svn_wc__node_is_status_excluded(svn_boolean_t *is_excluded,
-                                   svn_wc_context_t *wc_ctx,
-                                   const char *local_abspath,
-                                   apr_pool_t *scratch_pool)
-{
-  svn_wc__db_status_t status;
+  if (is_excluded)
+    *is_excluded = (status == svn_wc__db_status_excluded);
 
-  SVN_ERR(svn_wc__db_read_info(&status,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL,
-                               wc_ctx->db, local_abspath,
-                               scratch_pool, scratch_pool));
-  *is_excluded = (status == svn_wc__db_status_excluded);
+  if (is_server_excluded)
+    *is_server_excluded = (status == svn_wc__db_status_server_excluded);
 
   return SVN_NO_ERROR;
 }

Modified: subversion/trunk/subversion/tests/cmdline/copy_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/copy_tests.py?rev=1397145&r1=1397144&r2=1397145&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/copy_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/copy_tests.py Thu Oct 11 16:21:42 
2012
@@ -5742,6 +5742,30 @@ def copy_text_conflict(sbox):
   })
   svntest.actions.run_and_verify_unquiet_status(wc_dir, expected_status)
 
+@Issue(2843)
+def copy_over_excluded(sbox):
+  "copy on top of excluded should give error"
+
+  sbox.build(read_only = True)
+  wc_dir = sbox.wc_dir
+
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'update', '--set-depth', 'exclude',
+                                     sbox.ospath('A/D'))
+
+  expected_error = "svn: E155000: Path '.*D' exists.*excluded.*"
+
+  svntest.actions.run_and_verify_svn(None, None, expected_error,
+                                     'cp',
+                                       sbox.repo_url + '/A/C',
+                                       sbox.ospath('A/D'))
+
+  expected_error = "svn: E155000: Path '.*D' exists.*excluded.*"
+  svntest.actions.run_and_verify_svn(None, None, expected_error,
+                                     'cp',
+                                       sbox.ospath('A/C'),
+                                       sbox.ospath('A/D'))
+
 ########################################################################
 # Run the tests
 
@@ -5858,6 +5882,7 @@ test_list = [ None,
               three_nested_moves,
               copy_to_unversioned_parent,
               copy_text_conflict,
+              copy_over_excluded,
              ]
 
 if __name__ == '__main__':


Reply via email to