You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2013/02/26 14:38:15 UTC

svn commit: r1450166 - in /subversion/trunk/subversion: include/private/ libsvn_client/ libsvn_wc/ tests/cmdline/ tests/libsvn_wc/

Author: rhuijben
Date: Tue Feb 26 13:38:14 2013
New Revision: 1450166

URL: http://svn.apache.org/r1450166
Log:
Add a few more arguments to svn_wc__node_get_base() to make its results
more reliable and usable in update and lock scenarios when handling
replaced nodes.

* subversion/include/private/svn_wc_private.h
  (svn_wc__node_get_base): Update arguments and documentation.

* subversion/libsvn_client/commit_util.c
  (harvest_status_callback): Don't obtain parent directory revision if the node
    is added.

* subversion/libsvn_client/locking_commands.c
  (organize_lock_targets): Improve error reporting.

* subversion/libsvn_client/merge.c
  (calculate_remaining_ranges): Update caller.

* subversion/libsvn_client/mergeinfo.c
  (svn_client__get_wc_mergeinfo): Update caller.

* subversion/libsvn_client/update.c
  (update_internal): Check anchor base status instead of a combination of base
    and working.

* subversion/libsvn_client/util.c
  (svn_client__wc_node_get_base): Update caller.

* subversion/libsvn_wc/node.c
  (svn_wc__node_get_base): Handle new arguments.

* subversion/tests/cmdline/lock_tests.py
  (lock_path_not_in_head): Update expected error.

* subversion/tests/libsvn_wc/wc-test.c
  (test_node_get_base): Update caller.

Modified:
    subversion/trunk/subversion/include/private/svn_wc_private.h
    subversion/trunk/subversion/libsvn_client/commit_util.c
    subversion/trunk/subversion/libsvn_client/locking_commands.c
    subversion/trunk/subversion/libsvn_client/merge.c
    subversion/trunk/subversion/libsvn_client/mergeinfo.c
    subversion/trunk/subversion/libsvn_client/update.c
    subversion/trunk/subversion/libsvn_client/util.c
    subversion/trunk/subversion/libsvn_wc/node.c
    subversion/trunk/subversion/tests/cmdline/lock_tests.py
    subversion/trunk/subversion/tests/libsvn_wc/wc-test.c

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=1450166&r1=1450165&r2=1450166&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_wc_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_wc_private.h Tue Feb 26 13:38:14 2013
@@ -621,9 +621,10 @@ svn_wc__node_has_working(svn_boolean_t *
  * to, regardless of any uncommitted changes (delete, replace and/or copy-here/
  * move-here).
  *
- * If there is no base node at @a local_abspath (such as when there is a
- * locally added/copied/moved-here node that is not part of a replace),
- * return @c SVN_INVALID_REVNUM/NULL/NULL/NULL/NULL.
+ * If there is no BASE node at @a local_abspath or if @a show_hidden is FALSE,
+ * no status 'normal' or 'incomplete' BASE node report
+ * SVN_ERR_WC_PATH_NOT_FOUND, or if @a ignore_enoent is TRUE, @a kind
+ * svn_node_unknown, @a revision SVN_INVALID_REVNUM and all other values NULL.
  *
  * All output arguments may be NULL.
  *
@@ -631,13 +632,16 @@ svn_wc__node_has_working(svn_boolean_t *
  * @a scratch_pool.
  */
 svn_error_t *
-svn_wc__node_get_base(svn_revnum_t *revision,
+svn_wc__node_get_base(svn_node_kind_t *kind,
+                      svn_revnum_t *revision,
                       const char **repos_relpath,
                       const char **repos_root_url,
                       const char **repos_uuid,
                       const char **lock_token,
                       svn_wc_context_t *wc_ctx,
                       const char *local_abspath,
+                      svn_boolean_t ignore_enoent,
+                      svn_boolean_t show_hidden,
                       apr_pool_t *result_pool,
                       apr_pool_t *scratch_pool);
 

Modified: subversion/trunk/subversion/libsvn_client/commit_util.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/commit_util.c?rev=1450166&r1=1450165&r2=1450166&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/commit_util.c (original)
+++ subversion/trunk/subversion/libsvn_client/commit_util.c Tue Feb 26 13:38:14 2013
@@ -762,12 +762,14 @@ harvest_status_callback(void *status_bat
   else if (copy_mode
            && !(state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE))
     {
-      svn_revnum_t dir_rev;
+      svn_revnum_t dir_rev = SVN_INVALID_REVNUM;
 
-      if (!copy_mode_root && !status->switched)
-        SVN_ERR(svn_wc__node_get_base(&dir_rev, NULL, NULL, NULL, NULL, wc_ctx,
-                                      svn_dirent_dirname(local_abspath,
-                                                         scratch_pool),
+      if (!copy_mode_root && !status->switched && !is_added)
+        SVN_ERR(svn_wc__node_get_base(NULL, &dir_rev, NULL, NULL, NULL, NULL,
+                                      wc_ctx, svn_dirent_dirname(local_abspath,
+                                                                 scratch_pool),
+                                      FALSE /* ignore_enoent */,
+                                      FALSE /* show_hidden */,
                                       scratch_pool, scratch_pool));
 
       if (copy_mode_root || status->switched || node_rev != dir_rev)

Modified: subversion/trunk/subversion/libsvn_client/locking_commands.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/locking_commands.c?rev=1450166&r1=1450165&r2=1450166&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/locking_commands.c (original)
+++ subversion/trunk/subversion/libsvn_client/locking_commands.c Tue Feb 26 13:38:14 2013
@@ -304,6 +304,7 @@ organize_lock_targets(const char **commo
           const char *target_url;
           struct wc_lock_item_t *wli;
           const char *local_abspath;
+          svn_node_kind_t kind;
 
           svn_pool_clear(iterpool);
 
@@ -311,16 +312,17 @@ organize_lock_targets(const char **commo
           local_abspath = svn_dirent_join(common_dirent, rel_target, scratch_pool);
           wli = apr_pcalloc(scratch_pool, sizeof(*wli));
 
-          SVN_ERR(svn_wc__node_get_base(&wli->revision, &repos_relpath,
+          SVN_ERR(svn_wc__node_get_base(&kind, &wli->revision, &repos_relpath,
                                         &repos_root_url, NULL,
                                         &wli->lock_token,
                                         wc_ctx, local_abspath,
+                                        FALSE /* ignore_enoent */,
+                                        FALSE /* show_hidden */,
                                         result_pool, iterpool));
 
-          /* Node exists in BASE? */
-          if (! repos_root_url || !repos_relpath)
-            return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
-                                     _("The node '%s' was not found."),
+          if (kind != svn_node_file)
+            return svn_error_createf(SVN_ERR_WC_NOT_FILE, NULL,
+                                     _("The node '%s' is not a file"),
                                      svn_dirent_local_style(local_abspath,
                                                             iterpool));
 

Modified: subversion/trunk/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/merge.c?rev=1450166&r1=1450165&r2=1450166&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/merge.c (original)
+++ subversion/trunk/subversion/libsvn_client/merge.c Tue Feb 26 13:38:14 2013
@@ -4592,8 +4592,11 @@ calculate_remaining_ranges(svn_client__m
      So in the name of user friendliness, return an error suggesting a helpful
      course of action.
   */
-  SVN_ERR(svn_wc__node_get_base(&child_base_revision, NULL, NULL, NULL, NULL,
+  SVN_ERR(svn_wc__node_get_base(NULL, &child_base_revision,
+                                NULL, NULL, NULL, NULL,
                                 ctx->wc_ctx, child->abspath,
+                                TRUE /* ignore_enoent */,
+                                FALSE /* show_hidden */,
                                 scratch_pool, scratch_pool));
   /* If CHILD has no base revision then it hasn't been committed yet, so it
      can't have any "future" history. */

Modified: subversion/trunk/subversion/libsvn_client/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/mergeinfo.c?rev=1450166&r1=1450165&r2=1450166&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/mergeinfo.c (original)
+++ subversion/trunk/subversion/libsvn_client/mergeinfo.c Tue Feb 26 13:38:14 2013
@@ -217,8 +217,10 @@ svn_client__get_wc_mergeinfo(svn_mergein
   if (limit_abspath)
     SVN_ERR_ASSERT(svn_dirent_is_absolute(limit_abspath));
 
-  SVN_ERR(svn_wc__node_get_base(&base_revision, NULL, NULL, NULL, NULL,
+  SVN_ERR(svn_wc__node_get_base(NULL, &base_revision, NULL, NULL, NULL, NULL,
                                 ctx->wc_ctx, local_abspath,
+                                TRUE /* ignore_enoent */,
+                                FALSE /* show_hidden */,
                                 scratch_pool, scratch_pool));
 
   iterpool = svn_pool_create(scratch_pool);
@@ -286,9 +288,15 @@ svn_client__get_wc_mergeinfo(svn_mergein
                                           walk_relpath, result_pool);
           local_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
 
-          SVN_ERR(svn_wc__node_get_base(&parent_base_rev, NULL, NULL, NULL,
-                                        NULL, ctx->wc_ctx, local_abspath,
+          SVN_ERR(svn_wc__node_get_base(NULL, &parent_base_rev, NULL, NULL,
+                                        NULL, NULL,
+                                        ctx->wc_ctx, local_abspath,
+                                        TRUE, FALSE,
                                         scratch_pool, scratch_pool));
+
+          /* ### This checks the WORKING changed_rev, so invalid on replacement
+             ### not even reliable in case an ancestor was copied from a
+             ### different location */
           SVN_ERR(svn_wc__node_get_changed_info(&parent_changed_rev,
                                                 NULL, NULL,
                                                 ctx->wc_ctx, local_abspath,

Modified: subversion/trunk/subversion/libsvn_client/update.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/update.c?rev=1450166&r1=1450165&r2=1450166&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/update.c (original)
+++ subversion/trunk/subversion/libsvn_client/update.c Tue Feb 26 13:38:14 2013
@@ -193,7 +193,10 @@ update_internal(svn_revnum_t *result_rev
   void *report_baton;
   const char *corrected_url;
   const char *target;
-  svn_client__pathrev_t *anchor_loc;
+  const char *repos_root_url;
+  const char *repos_relpath;
+  const char *repos_uuid;
+  const char *anchor_url;
   svn_error_t *err;
   svn_revnum_t revnum;
   svn_boolean_t use_commit_times;
@@ -208,12 +211,11 @@ update_internal(svn_revnum_t *result_rev
   apr_array_header_t *preserved_exts;
   struct svn_client__dirent_fetcher_baton_t dfb;
   svn_boolean_t server_supports_depth;
-  svn_boolean_t text_conflicted, prop_conflicted, tree_conflicted;
   svn_boolean_t cropping_target;
+  svn_boolean_t target_conflicted = FALSE;
   svn_config_t *cfg = ctx->config ? apr_hash_get(ctx->config,
                                                  SVN_CONFIG_CATEGORY_CONFIG,
                                                  APR_HASH_KEY_STRING) : NULL;
-  svn_boolean_t is_not_present, is_excluded, is_server_excluded;
 
   if (result_rev)
     *result_rev = SVN_INVALID_REVNUM;
@@ -228,44 +230,43 @@ update_internal(svn_revnum_t *result_rev
     target = "";
 
   /* Check if our anchor exists in BASE. If it doesn't we can't update. */
-  SVN_ERR(svn_client__wc_node_get_base(&anchor_loc, anchor_abspath,
-                                       ctx->wc_ctx, pool, pool));
-  err = svn_wc__node_is_not_present(&is_not_present, &is_excluded,
-                                    &is_server_excluded,
-                                    ctx->wc_ctx, anchor_abspath, TRUE, pool);
-  if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
-    {
-      svn_error_clear(err);
-      is_not_present = TRUE;  /* Causes the update to skip */
-    }
-  else
-    SVN_ERR(err);
+  SVN_ERR(svn_wc__node_get_base(NULL, NULL, &repos_relpath, &repos_root_url,
+                                &repos_uuid, NULL,
+                                ctx->wc_ctx, anchor_abspath,
+                                TRUE, FALSE,
+                                pool, pool));
 
   /* It does not make sense to update conflict victims. */
-  err = svn_wc_conflicted_p3(&text_conflicted, &prop_conflicted,
-                             &tree_conflicted,
-                             ctx->wc_ctx, local_abspath, pool);
-  if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+  if (repos_relpath)
     {
+      svn_error_t *err;
+      svn_boolean_t text_conflicted, prop_conflicted, tree_conflicted;
+
+      anchor_url = svn_path_url_add_component2(repos_root_url, repos_relpath,
+                                               pool);
+
+      err = svn_wc_conflicted_p3(&text_conflicted, &prop_conflicted,
+                                 &tree_conflicted,
+                                 ctx->wc_ctx, local_abspath, pool);
+
+      if (err && err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+        return svn_error_trace(err);
       svn_error_clear(err);
-      text_conflicted = FALSE;
-      prop_conflicted = FALSE;
-      tree_conflicted = FALSE;
+
+      if (!err && (text_conflicted || prop_conflicted || tree_conflicted))
+        target_conflicted = TRUE;
     }
   else
-    SVN_ERR(err);
+    anchor_url = NULL;
 
-  if (! anchor_loc
-      || text_conflicted || prop_conflicted || tree_conflicted
-      || is_not_present || is_excluded || is_server_excluded)
+  if (! anchor_url || target_conflicted)
     {
       if (ctx->notify_func2)
         {
           svn_wc_notify_t *nt;
 
           nt = svn_wc_create_notify(local_abspath,
-                                    (text_conflicted || prop_conflicted
-                                                     || tree_conflicted)
+                                    target_conflicted
                                       ? svn_wc_notify_skip_conflicted
                                       : svn_wc_notify_update_skip_working_only,
                                     pool);
@@ -343,7 +344,7 @@ update_internal(svn_revnum_t *result_rev
 
   /* Open an RA session for the URL */
   SVN_ERR(svn_client__open_ra_session_internal(&ra_session, &corrected_url,
-                                               anchor_loc->url,
+                                               anchor_url,
                                                anchor_abspath, NULL, TRUE,
                                                TRUE, ctx, pool));
 
@@ -358,15 +359,15 @@ update_internal(svn_revnum_t *result_rev
       SVN_ERR(svn_ra_get_repos_root2(ra_session, &new_repos_root_url, pool));
 
       /* svn_client_relocate2() will check the uuid */
-      SVN_ERR(svn_client_relocate2(anchor_abspath, anchor_loc->url,
+      SVN_ERR(svn_client_relocate2(anchor_abspath, anchor_url,
                                    new_repos_root_url, ignore_externals,
                                    ctx, pool));
 
       /* Store updated repository root for externals */
-      anchor_loc->repos_root_url = new_repos_root_url;
+      repos_root_url = new_repos_root_url;
       /* ### We should update anchor_loc->repos_uuid too, although currently
        * we don't use it. */
-      anchor_loc->url = corrected_url;
+      anchor_url = corrected_url;
     }
 
   /* Resolve unspecified REVISION now, because we need to retrieve the
@@ -388,7 +389,7 @@ update_internal(svn_revnum_t *result_rev
 
   dfb.ra_session = ra_session;
   dfb.target_revision = revnum;
-  dfb.anchor_url = anchor_loc->url;
+  dfb.anchor_url = anchor_url;
 
   SVN_ERR(svn_client__get_inheritable_props(&wcroot_iprops, local_abspath,
                                             revnum, depth, ra_session,
@@ -456,7 +457,7 @@ update_internal(svn_revnum_t *result_rev
 
       SVN_ERR(svn_client__handle_externals(new_externals,
                                            new_depths,
-                                           anchor_loc->repos_root_url, local_abspath,
+                                           repos_root_url, local_abspath,
                                            depth, use_sleep,
                                            ctx, pool));
     }

Modified: subversion/trunk/subversion/libsvn_client/util.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/util.c?rev=1450166&r1=1450165&r2=1450166&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/util.c (original)
+++ subversion/trunk/subversion/libsvn_client/util.c Tue Feb 26 13:38:14 2013
@@ -179,12 +179,15 @@ svn_client__wc_node_get_base(svn_client_
 
   *base_p = apr_palloc(result_pool, sizeof(**base_p));
 
-  SVN_ERR(svn_wc__node_get_base(&(*base_p)->rev,
+  SVN_ERR(svn_wc__node_get_base(NULL,
+                                &(*base_p)->rev,
                                 &relpath,
                                 &(*base_p)->repos_root_url,
                                 &(*base_p)->repos_uuid,
                                 NULL,
                                 wc_ctx, wc_abspath,
+                                TRUE /* ignore_enoent */,
+                                TRUE /* show_hidden */,
                                 result_pool, scratch_pool));
   if ((*base_p)->repos_root_url && relpath)
     {

Modified: subversion/trunk/subversion/libsvn_wc/node.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/node.c?rev=1450166&r1=1450165&r2=1450166&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/node.c (original)
+++ subversion/trunk/subversion/libsvn_wc/node.c Tue Feb 26 13:38:14 2013
@@ -658,29 +658,53 @@ svn_wc__node_has_working(svn_boolean_t *
 
 
 svn_error_t *
-svn_wc__node_get_base(svn_revnum_t *revision,
+svn_wc__node_get_base(svn_node_kind_t *kind,
+                      svn_revnum_t *revision,
                       const char **repos_relpath,
                       const char **repos_root_url,
                       const char **repos_uuid,
                       const char **lock_token,
                       svn_wc_context_t *wc_ctx,
                       const char *local_abspath,
+                      svn_boolean_t ignore_enoent,
+                      svn_boolean_t show_hidden,
                       apr_pool_t *result_pool,
                       apr_pool_t *scratch_pool)
 {
   svn_error_t *err;
+  svn_wc__db_status_t status;
   svn_wc__db_lock_t *lock;
+  svn_kind_t db_kind;
 
-  err = svn_wc__db_base_get_info(NULL, NULL, revision, repos_relpath,
+  err = svn_wc__db_base_get_info(&status, &db_kind, revision, repos_relpath,
                                  repos_root_url, repos_uuid, NULL,
                                  NULL, NULL, NULL, NULL, NULL,
                                  lock_token ? &lock : NULL,
                                  NULL, NULL, NULL,
                                  wc_ctx->db, local_abspath,
                                  result_pool, scratch_pool);
-  if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+
+  if (err && err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+    return svn_error_trace(err);
+  else if (err
+           || (!err && !show_hidden
+               && (status != svn_wc__db_status_normal
+                   && status != svn_wc__db_status_incomplete)))
     {
+      if (!ignore_enoent)
+        {
+          if (err)
+            return svn_error_trace(err);
+          else
+            return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+                                     _("The node '%s' was not found."),
+                                     svn_dirent_local_style(local_abspath,
+                                                            scratch_pool));
+        }
       svn_error_clear(err);
+
+      if (kind)
+        *kind = svn_node_unknown;
       if (revision)
         *revision = SVN_INVALID_REVNUM;
       if (repos_relpath)
@@ -693,8 +717,9 @@ svn_wc__node_get_base(svn_revnum_t *revi
         *lock_token = NULL;
       return SVN_NO_ERROR;
     }
-  SVN_ERR(err);
 
+  if (kind)
+    *kind = svn__node_kind_from_kind(db_kind);
   if (lock_token)
     *lock_token = lock ? lock->token : NULL;
 

Modified: subversion/trunk/subversion/tests/cmdline/lock_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/lock_tests.py?rev=1450166&r1=1450165&r2=1450166&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/lock_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/lock_tests.py Tue Feb 26 13:38:14 2013
@@ -1474,10 +1474,13 @@ def lock_path_not_in_head(sbox):
   # svn: In file '..\..\..\subversion\libsvn_ra_serf\util.c' line 1120:
   #  assertion failed (ctx->status_code)
   svntest.actions.run_and_verify_svn2(None, None, expected_lock_fail_err_re,
-                                      0, 'lock', D_path)
-  svntest.actions.run_and_verify_svn2(None, None, expected_lock_fail_err_re,
                                       0, 'lock', lambda_path)
 
+  expected_err = 'svn: E155008: The node \'.*D\' is not a file'
+  svntest.actions.run_and_verify_svn(None, None, expected_err,
+                                     'lock', D_path)
+
+
 #----------------------------------------------------------------------
 def verify_path_escaping(sbox):
   "verify escaping of lock paths"

Modified: subversion/trunk/subversion/tests/libsvn_wc/wc-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_wc/wc-test.c?rev=1450166&r1=1450165&r2=1450166&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/wc-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/wc-test.c Tue Feb 26 13:38:14 2013
@@ -133,10 +133,12 @@ test_node_get_base(const svn_test_opts_t
         svn_revnum_t revision;
         const char *repos_relpath, *repos_root_url, *repos_uuid;
 
-        SVN_ERR(svn_wc__node_get_base(&revision, &repos_relpath,
+        SVN_ERR(svn_wc__node_get_base(NULL, &revision, &repos_relpath,
                                       &repos_root_url, &repos_uuid,
                                       NULL,
                                       b->wc_ctx, local_abspath,
+                                      TRUE /* ignore_enoent */,
+                                      FALSE /* show_hidden */,
                                       b->pool, b->pool));
         SVN_TEST_ASSERT(revision == subtest->base_rev);
         if (SVN_IS_VALID_REVNUM(subtest->base_rev))