Author: cmpilato
Date: Wed Mar 30 16:54:01 2011
New Revision: 1087015

URL: http://svn.apache.org/viewvc?rev=1087015&view=rev
Log:
Fix (mostly) issue #3848 ("'svn switch' should protect users from
unintended switches").

Make the 'svn switch' perform a sanity check to ensure that the switch
target and the new switch URL location share some version control
ancestry, failing if they don't.  This check can be disabled with the
--ignore-ancestry command-line option.

This is the result of sheer frustration at how easy it is to
fat-finger a switch ("switch branches/foo to ^/branches -- oh no!!")
and the seemingly unrecoverable destruction that this can cause in
terms of tree conflicts and orphaned files, especially if you
interrupt the operation at the "oh no!" mental moment.

NOTE: There is likely some JavaHL work needed to wrap
      svn_client_switch3() instead of svn_client_switch2().

* subversion/include/svn_client.h
  (svn_client_switch3): New.
  (svn_client_switch2): Deprecate.

* subversion/libsvn_client/client.h
  (svn_client__switch_internal): Add 'ignore_ancestry' parameter,

* subversion/libsvn_client/switch.c
  (switch_internal): Add 'ignore_ancestry' parameter, and use it to
    togger whether or not to perfect a (newly added) common ancestry
    sanity check between the switch target path and the switch URL.
  (svn_client__switch_internal): Add 'ignore_ancestry' parameter,
    passed to updated call to switch_internal().
  (svn_client_switch3): Was svn_client_switch2().  Now accepts
    'ignore_ancestry' parameter.

* subversion/libsvn_client/deprecated.c
  (svn_client_switch2): "New" wrapper around svn_client_switch3().
  (svn_client_switch): Update call to svn_client__switch_internal().

* subversion/libsvn_client/externals.c
  (switch_dir_external, switch_file_external): Update calls to
    svn_client__switch_internal().

* subversion/svn/switch-cmd.c
  (svn_cl__switch): Now use svn_client_switch3(), passing the value of
    opt_state->ignore_ancestry.  Trap the
    SVN_ERR_CLIENT_UNRELATED_RESOURCES error, offering the suggestion
    to use --ignore-ancestry if it is raised.

* subversion/svn/main.c
  (svn_cl__cmd_table): Allow the 'switch' subcommand to accept the
    --ignore-ancestry option.

* subversion/tests/cmdline/basic_tests.py,
* subversion/tests/cmdline/lock_tests.py,
* subversion/tests/cmdline/merge_reintegrate_tests.py,
* subversion/tests/cmdline/merge_tests.py,
* subversion/tests/cmdline/svnversion_tests.py,
* subversion/tests/cmdline/switch_tests.py,
* subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout,
* subversion/tests/cmdline/svntest/actions.py
  Adjust multivarious tests and test helper functions to pass
  '--ignore-ancestry' as now required.

Modified:
    subversion/trunk/subversion/include/svn_client.h
    subversion/trunk/subversion/libsvn_client/client.h
    subversion/trunk/subversion/libsvn_client/deprecated.c
    subversion/trunk/subversion/libsvn_client/externals.c
    subversion/trunk/subversion/libsvn_client/switch.c
    subversion/trunk/subversion/svn/main.c
    subversion/trunk/subversion/svn/switch-cmd.c
    subversion/trunk/subversion/tests/cmdline/basic_tests.py
    
subversion/trunk/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout
    subversion/trunk/subversion/tests/cmdline/lock_tests.py
    subversion/trunk/subversion/tests/cmdline/merge_reintegrate_tests.py
    subversion/trunk/subversion/tests/cmdline/merge_tests.py
    subversion/trunk/subversion/tests/cmdline/svntest/actions.py
    subversion/trunk/subversion/tests/cmdline/svnversion_tests.py
    subversion/trunk/subversion/tests/cmdline/switch_tests.py

Modified: subversion/trunk/subversion/include/svn_client.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_client.h?rev=1087015&r1=1087014&r2=1087015&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_client.h (original)
+++ subversion/trunk/subversion/include/svn_client.h Wed Mar 30 16:54:01 2011
@@ -1326,6 +1326,12 @@ svn_client_update(svn_revnum_t *result_r
  *              set equal to the base properties. <br>
  *              If @c FALSE, then abort if there are any unversioned
  *              obstructing items.
+ * @param[in] ignore_ancestry  If @c FALSE, then verify that the file
+ *              or directory at @a path shares some common version control
+ *              ancestry with the switch URL location (represented by the
+ *              combination of @a url, @a peg_revision, and @a revision),
+ *              and returning #SVN_ERR_CLIENT_UNRELATED_RESOURCES if they
+ *              do not. If @c TRUE, no such sanity checks are performed.
  * @param[in] ctx   The standard client context, used for authentication and
  *              notification.  The notifier is invoked for paths affected by
  *              the switch, and also for files which may be restored from the
@@ -1340,12 +1346,35 @@ svn_client_update(svn_revnum_t *result_r
  *         #svn_opt_revision_date. <br>
  *         If no error occurred, return #SVN_NO_ERROR.
  *
- * @since New in 1.5.
+ * @since New in 1.7.
  *
  * @see #svn_depth_t <br> #svn_client_ctx_t <br> @ref clnt_revisions for
  *      a discussion of operative and peg revisions.
  */
 svn_error_t *
+svn_client_switch3(svn_revnum_t *result_rev,
+                   const char *path,
+                   const char *url,
+                   const svn_opt_revision_t *peg_revision,
+                   const svn_opt_revision_t *revision,
+                   svn_depth_t depth,
+                   svn_boolean_t depth_is_sticky,
+                   svn_boolean_t ignore_externals,
+                   svn_boolean_t allow_unver_obstructions,
+                   svn_boolean_t ignore_ancestry,
+                   svn_client_ctx_t *ctx,
+                   apr_pool_t *pool);
+
+
+/**
+ * Similar to svn_client_switch3() but with @a ignore_ancestry always
+ * set to TRUE.
+ *
+ * @since New in 1.5.
+ * @deprecated Provided for backward compatibility with the 1.4 API.
+ */
+SVN_DEPRECATED
+svn_error_t *
 svn_client_switch2(svn_revnum_t *result_rev,
                    const char *path,
                    const char *url,

Modified: subversion/trunk/subversion/libsvn_client/client.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/client.h?rev=1087015&r1=1087014&r2=1087015&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/client.h (original)
+++ subversion/trunk/subversion/libsvn_client/client.h Wed Mar 30 16:54:01 2011
@@ -576,19 +576,28 @@ svn_client__checkout_internal(svn_revnum
 /* Switch a working copy PATH to URL@PEG_REVISION at REVISION, and (if not
    NULL) set RESULT_REV to the switch revision. A write lock will be
    acquired and released if not held. Only switch as deeply as DEPTH
-   indicates.  If TIMESTAMP_SLEEP is NULL this function will sleep before
+   indicates.
+
+   If TIMESTAMP_SLEEP is NULL this function will sleep before
    returning to ensure timestamp integrity.  If TIMESTAMP_SLEEP is not
    NULL then the function will not sleep but will set *TIMESTAMP_SLEEP
    to TRUE if a sleep is required, and will not change
-   *TIMESTAMP_SLEEP if no sleep is required.  If IGNORE_EXTERNALS is true,
-   don't process externals.  If ALLOW_UNVER_OBSTRUCTIONS is TRUE, unversioned
-   children of PATH that obstruct items added from the repos are tolerated;
-   if FALSE, these obstructions cause the switch to fail.
+   *TIMESTAMP_SLEEP if no sleep is required.
+
+   If IGNORE_EXTERNALS is true, don't process externals.
+
+   If ALLOW_UNVER_OBSTRUCTIONS is TRUE, unversioned children of PATH
+   that obstruct items added from the repos are tolerated; if FALSE,
+   these obstructions cause the switch to fail.
 
    DEPTH and DEPTH_IS_STICKY behave as for svn_client__update_internal().
 
    If INNERSWITCH is true, no anchor check is performed on the target.
-   */
+
+   If IGNORE_ANCESTRY is true, don't perform a common ancestry check
+   between the PATH and URL; otherwise, do, and return
+   SVN_ERR_CLIENT_UNRELATED_RESOURCES if they aren't related.
+*/
 svn_error_t *
 svn_client__switch_internal(svn_revnum_t *result_rev,
                             const char *path,
@@ -601,6 +610,7 @@ svn_client__switch_internal(svn_revnum_t
                             svn_boolean_t ignore_externals,
                             svn_boolean_t allow_unver_obstructions,
                             svn_boolean_t innerswitch,
+                            svn_boolean_t ignore_ancestry,
                             svn_client_ctx_t *ctx,
                             apr_pool_t *pool);
 

Modified: subversion/trunk/subversion/libsvn_client/deprecated.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/deprecated.c?rev=1087015&r1=1087014&r2=1087015&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/deprecated.c (original)
+++ subversion/trunk/subversion/libsvn_client/deprecated.c Wed Mar 30 16:54:01 
2011
@@ -1905,6 +1905,24 @@ svn_client_update(svn_revnum_t *result_r
 
 /*** From switch.c ***/
 svn_error_t *
+svn_client_switch2(svn_revnum_t *result_rev,
+                   const char *path,
+                   const char *switch_url,
+                   const svn_opt_revision_t *peg_revision,
+                   const svn_opt_revision_t *revision,
+                   svn_depth_t depth,
+                   svn_boolean_t depth_is_sticky,
+                   svn_boolean_t ignore_externals,
+                   svn_boolean_t allow_unver_obstructions,
+                   svn_client_ctx_t *ctx,
+                   apr_pool_t *pool)
+{
+  return svn_client_switch3(result_rev, path, switch_url, peg_revision,
+                            revision, depth, depth_is_sticky, ignore_externals,
+                            allow_unver_obstructions, TRUE, ctx, pool);
+}
+
+svn_error_t *
 svn_client_switch(svn_revnum_t *result_rev,
                   const char *path,
                   const char *switch_url,
@@ -1918,8 +1936,8 @@ svn_client_switch(svn_revnum_t *result_r
   return svn_client__switch_internal(result_rev, path, switch_url,
                                      &peg_revision, revision,
                                      SVN_DEPTH_INFINITY_OR_FILES(recurse),
-                                     FALSE, NULL, FALSE, FALSE, FALSE, ctx,
-                                     pool);
+                                     FALSE, NULL, FALSE, FALSE, FALSE, TRUE,
+                                     ctx, pool);
 }
 
 /*** From cat.c ***/

Modified: subversion/trunk/subversion/libsvn_client/externals.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/externals.c?rev=1087015&r1=1087014&r2=1087015&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/externals.c (original)
+++ subversion/trunk/subversion/libsvn_client/externals.c Wed Mar 30 16:54:01 
2011
@@ -251,8 +251,8 @@ switch_dir_external(const char *path,
                                                   peg_revision, revision,
                                                   svn_depth_infinity,
                                                   TRUE, timestamp_sleep,
-                                                  FALSE, FALSE, TRUE, ctx,
-                                                  subpool));
+                                                  FALSE, FALSE, TRUE, TRUE,
+                                                  ctx, subpool));
 
               svn_pool_destroy(subpool);
               return SVN_NO_ERROR;
@@ -453,6 +453,7 @@ switch_file_external(const char *path,
                                     TRUE, /* ignore_externals */
                                     FALSE, /* allow_unver_obstructions */
                                     FALSE, /* innerswitch */
+                                    TRUE, /* ignore_ancestry */
                                     ctx,
                                     pool);
   if (err)

Modified: subversion/trunk/subversion/libsvn_client/switch.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/switch.c?rev=1087015&r1=1087014&r2=1087015&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/switch.c (original)
+++ subversion/trunk/subversion/libsvn_client/switch.c Wed Mar 30 16:54:01 2011
@@ -68,6 +68,7 @@ switch_internal(svn_revnum_t *result_rev
                 svn_boolean_t ignore_externals,
                 svn_boolean_t allow_unver_obstructions,
                 svn_boolean_t innerswitch,
+                svn_boolean_t ignore_ancestry,
                 svn_client_ctx_t *ctx,
                 apr_pool_t *pool)
 {
@@ -132,7 +133,7 @@ switch_internal(svn_revnum_t *result_rev
                              _("Directory '%s' has no URL"),
                              svn_dirent_local_style(anchor_abspath, pool));
 
-    /* We may need to crop the tree if the depth is sticky */
+  /* We may need to crop the tree if the depth is sticky */
   if (depth_is_sticky && depth < svn_depth_infinity)
     {
       svn_node_kind_t target_kind;
@@ -165,6 +166,7 @@ switch_internal(svn_revnum_t *result_rev
                                            switch_url, anchor_abspath,
                                            peg_revision, revision,
                                            ctx, pool));
+
   SVN_ERR(svn_ra_get_repos_root2(ra_session, &source_root, pool));
 
   /* Disallow a switch operation to change the repository root of the
@@ -174,6 +176,30 @@ switch_internal(svn_revnum_t *result_rev
                              _("'%s'\nis not the same repository as\n'%s'"),
                              url, source_root);
 
+  /* If we're not ignoring ancestry, then error out if the switch
+     source and target don't have a common ancestory.
+
+     ### We're acting on the anchor here, not the target.  Is that
+     ### okay? */
+  if (! ignore_ancestry)
+    {
+      const char *target_url, *yc_path;
+      svn_revnum_t target_rev, yc_rev;
+
+      SVN_ERR(svn_wc__node_get_url(&target_url, ctx->wc_ctx, local_abspath,
+                                   pool, pool));
+      SVN_ERR(svn_wc__node_get_base_rev(&target_rev, ctx->wc_ctx,
+                                        local_abspath, pool));
+      SVN_ERR(svn_client__get_youngest_common_ancestor(&yc_path, &yc_rev,
+                                                       switch_rev_url, revnum,
+                                                       target_url, target_rev,
+                                                       ctx, pool));
+      if (! (yc_path && SVN_IS_VALID_REVNUM(yc_rev)))
+        return svn_error_create(SVN_ERR_CLIENT_UNRELATED_RESOURCES,
+                                NULL, NULL);
+    }
+
+
   SVN_ERR(svn_ra_reparent(ra_session, url, pool));
 
   /* Fetch the switch (update) editor.  If REVISION is invalid, that's
@@ -284,6 +310,7 @@ svn_client__switch_internal(svn_revnum_t
                             svn_boolean_t ignore_externals,
                             svn_boolean_t allow_unver_obstructions,
                             svn_boolean_t innerswitch,
+                            svn_boolean_t ignore_ancestry,
                             svn_client_ctx_t *ctx,
                             apr_pool_t *pool)
 {
@@ -310,7 +337,8 @@ svn_client__switch_internal(svn_revnum_t
                          switch_url, peg_revision, revision,
                          depth, depth_is_sticky,
                          timestamp_sleep, ignore_externals,
-                         allow_unver_obstructions, innerswitch, ctx, pool);
+                         allow_unver_obstructions, innerswitch,
+                         ignore_ancestry, ctx, pool);
 
   if (acquired_lock)
     err2 = svn_wc__release_write_lock(ctx->wc_ctx, anchor_abspath, pool);
@@ -321,7 +349,7 @@ svn_client__switch_internal(svn_revnum_t
 }
 
 svn_error_t *
-svn_client_switch2(svn_revnum_t *result_rev,
+svn_client_switch3(svn_revnum_t *result_rev,
                    const char *path,
                    const char *switch_url,
                    const svn_opt_revision_t *peg_revision,
@@ -330,17 +358,17 @@ svn_client_switch2(svn_revnum_t *result_
                    svn_boolean_t depth_is_sticky,
                    svn_boolean_t ignore_externals,
                    svn_boolean_t allow_unver_obstructions,
+                   svn_boolean_t ignore_ancestry,
                    svn_client_ctx_t *ctx,
                    apr_pool_t *pool)
 {
   if (svn_path_is_url(path))
     return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
-                             _("'%s' is not a local path"),
-                             path);
+                             _("'%s' is not a local path"), path);
 
   return svn_client__switch_internal(result_rev, path, switch_url,
                                      peg_revision, revision, depth,
                                      depth_is_sticky, NULL, ignore_externals,
-                                     allow_unver_obstructions, FALSE, ctx,
-                                     pool);
+                                     allow_unver_obstructions, FALSE, 
+                                     ignore_ancestry, ctx, pool);
 }

Modified: subversion/trunk/subversion/svn/main.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/main.c?rev=1087015&r1=1087014&r2=1087015&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/main.c (original)
+++ subversion/trunk/subversion/svn/main.c Wed Mar 30 16:54:01 2011
@@ -1320,6 +1320,10 @@ const svn_opt_subcommand_desc2_t svn_cl_
      "     Use the --set-depth option to set a new working copy depth on the\n"
      "     targets of this operation.\n"
      "\n"
+     "     By default, Subversion will refuse to switch a working copy path 
to\n"
+     "     a new URL with which it shares no common version control 
ancestry.\n"
+     "     Use the '--ignore-ancestry' option to override this sanity check.\n"
+     "\n"
      "  2. The '--relocate' option is deprecated. This syntax is equivalent 
to\n"
      "     'svn relocate FROM-PREFIX TO-PREFIX [PATH]'.\n"
      "\n"
@@ -1332,7 +1336,7 @@ const svn_opt_subcommand_desc2_t svn_cl_
      "    svn switch --relocate http://www.example.com/repo/project \\\n"
      "                          svn://svn.example.com/repo/project\n"),
     { 'r', 'N', opt_depth, opt_set_depth, 'q', opt_merge_cmd, opt_relocate,
-      opt_ignore_externals, opt_force, opt_accept} },
+      opt_ignore_externals, opt_ignore_ancestry, opt_force, opt_accept} },
 
   { "unlock", svn_cl__unlock, {0}, N_
     ("Unlock working copy paths or URLs.\n"

Modified: subversion/trunk/subversion/svn/switch-cmd.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/switch-cmd.c?rev=1087015&r1=1087014&r2=1087015&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/switch-cmd.c (original)
+++ subversion/trunk/subversion/svn/switch-cmd.c Wed Mar 30 16:54:01 2011
@@ -93,6 +93,7 @@ svn_cl__switch(apr_getopt_t *os,
                void *baton,
                apr_pool_t *scratch_pool)
 {
+  svn_error_t *err;
   svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
   svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
   apr_array_header_t *targets;
@@ -172,10 +173,21 @@ svn_cl__switch(apr_getopt_t *os,
   ctx->notify_baton2 = &nwb;
 
   /* Do the 'switch' update. */
-  SVN_ERR(svn_client_switch2(NULL, target, switch_url, &peg_revision,
-                             &(opt_state->start_revision), depth,
-                             depth_is_sticky, opt_state->ignore_externals,
-                             opt_state->force, ctx, scratch_pool));
+  err = svn_client_switch3(NULL, target, switch_url, &peg_revision,
+                           &(opt_state->start_revision), depth,
+                           depth_is_sticky, opt_state->ignore_externals,
+                           opt_state->force, opt_state->ignore_ancestry,
+                           ctx, scratch_pool);
+  if (err)
+    {
+      if (err->apr_err == SVN_ERR_CLIENT_UNRELATED_RESOURCES)
+        return svn_error_createf(SVN_ERR_CLIENT_UNRELATED_RESOURCES, err,
+                                 "Path '%s' does not share common version "
+                                 "control ancestry with the requested switch "
+                                 "location.  Use --ignore-ancestry to disable "
+                                 "this check.", target);
+      return err;
+    }
 
   if (! opt_state->quiet)
     SVN_ERR(svn_cl__print_conflict_stats(nwb.wrapped_baton, scratch_pool));

Modified: subversion/trunk/subversion/tests/cmdline/basic_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/basic_tests.py?rev=1087015&r1=1087014&r2=1087015&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/basic_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/basic_tests.py Wed Mar 30 
16:54:01 2011
@@ -911,7 +911,9 @@ def basic_switch(sbox):
   svntest.actions.run_and_verify_switch(wc_dir, iota_path, gamma_url,
                                         expected_output,
                                         expected_disk,
-                                        expected_status)
+                                        expected_status,
+                                        None, None, None, None, None,
+                                        False, '--ignore-ancestry')
 
   ### Switch the directory `A/D/H' to `A/D/G'.
 
@@ -963,7 +965,9 @@ def basic_switch(sbox):
   svntest.actions.run_and_verify_switch(wc_dir, ADH_path, ADG_url,
                                         expected_output,
                                         expected_disk,
-                                        expected_status)
+                                        expected_status,
+                                        None, None, None, None, None,
+                                        False, '--ignore-ancestry')
 
 #----------------------------------------------------------------------
 

Modified: 
subversion/trunk/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout?rev=1087015&r1=1087014&r2=1087015&view=diff
==============================================================================
--- 
subversion/trunk/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout
 (original)
+++ 
subversion/trunk/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout
 Wed Mar 30 16:54:01 2011
@@ -114,6 +114,10 @@ usage: 1. switch URL[@PEGREV] [PATH]
      Use the --set-depth option to set a new working copy depth on the
      targets of this operation.
 
+     By default, Subversion will refuse to switch a working copy path to
+     a new URL with which it shares no common version control ancestry.
+     Use the '--ignore-ancestry' option to override this sanity check.
+
   2. The '--relocate' option is deprecated. This syntax is equivalent to
      'svn relocate FROM-PREFIX TO-PREFIX [PATH]'.
 
@@ -144,6 +148,7 @@ Valid options:
   --diff3-cmd ARG          : use ARG as merge command
   --relocate               : relocate via URL-rewriting
   --ignore-externals [--ie] : ignore externals definitions
+  --ignore-ancestry [--ia] : ignore ancestry when calculating merges
   --force                  : force operation to run
   --accept ARG             : specify automatic conflict resolution action
                              ('postpone', 'base', 'mine-conflict',

Modified: subversion/trunk/subversion/tests/cmdline/lock_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/lock_tests.py?rev=1087015&r1=1087014&r2=1087015&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/lock_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/lock_tests.py Wed Mar 30 16:54:01 
2011
@@ -867,9 +867,11 @@ def lock_switched_files(sbox):
   alpha_URL = sbox.repo_url + '/A/B/E/alpha'
 
   svntest.actions.run_and_verify_svn(None, None, [], 'switch',
-                                     iota_URL, gamma_path)
+                                     iota_URL, gamma_path,
+                                     '--ignore-ancestry')
   svntest.actions.run_and_verify_svn(None, None, [], 'switch',
-                                     alpha_URL, lambda_path)
+                                     alpha_URL, lambda_path,
+                                     '--ignore-ancestry')
 
   expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
   expected_status.tweak('A/D/gamma', 'A/B/lambda', switched='S')
@@ -1450,7 +1452,8 @@ def lock_twice_in_one_wc(sbox):
   # Switch a second location for the same file in the same working copy
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'switch', sbox.repo_url + '/A',
-                                     os.path.join(wc_dir, 'A', 'B'))
+                                     os.path.join(wc_dir, 'A', 'B'),
+                                     '--ignore-ancestry')
 
   # Lock location 1
   svntest.actions.run_and_verify_svn(None, None, [],

Modified: subversion/trunk/subversion/tests/cmdline/merge_reintegrate_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/merge_reintegrate_tests.py?rev=1087015&r1=1087014&r2=1087015&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/merge_reintegrate_tests.py 
(original)
+++ subversion/trunk/subversion/tests/cmdline/merge_reintegrate_tests.py Wed 
Mar 30 16:54:01 2011
@@ -740,7 +740,8 @@ def reintegrate_fail_on_switched_wc(sbox
                                         expected_output,
                                         expected_disk,
                                         expected_status,
-                                        None, None, None, None, False);
+                                        None, None, None, None, None,
+                                        False, '--ignore-ancestry')
   sbox.simple_update() # avoid mixed-revision error
   svntest.actions.run_and_verify_merge(
     A_path, None, None, sbox.repo_url + '/A_COPY', None, None, None, None,

Modified: subversion/trunk/subversion/tests/cmdline/merge_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/merge_tests.py?rev=1087015&r1=1087014&r2=1087015&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/merge_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/merge_tests.py Wed Mar 30 
16:54:01 2011
@@ -724,7 +724,9 @@ def simple_property_merges(sbox):
                                      A_url, A2_url)
 
   # Re-root the WC at A2.
-  svntest.actions.run_and_verify_svn(None, None, [], 'switch', A2_url, wc_dir)
+  svntest.main.safe_rmtree(wc_dir)
+  svntest.actions.run_and_verify_svn(None, None, [], 'checkout',
+                                     A2_url, wc_dir)
 
   # Attempt to re-merge rev 4 of the original A's alpha.  Mergeinfo
   # inherited from A2 (created by its copy from A) allows us to avoid
@@ -16519,10 +16521,10 @@ def merge_change_to_file_with_executable
   svntest.main.file_append(beta_path, 'appended beta text')
   sbox.simple_commit()
 
-  # Switch the WC to the branch
-  svntest.actions.run_and_verify_svn(None, None, [], 'switch',
-                                     sbox.repo_url + '/branch',
-                                     wc_dir)
+  # Re-root the WC at the branch
+  svntest.main.safe_rmtree(wc_dir)
+  svntest.actions.run_and_verify_svn(None, None, [], 'checkout',
+                                     sbox.repo_url + '/branch', wc_dir)
   
   # Recalculate the paths
   alpha_path = os.path.join(wc_dir, "alpha")

Modified: subversion/trunk/subversion/tests/cmdline/svntest/actions.py
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/svntest/actions.py?rev=1087015&r1=1087014&r2=1087015&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/svntest/actions.py (original)
+++ subversion/trunk/subversion/tests/cmdline/svntest/actions.py Wed Mar 30 
16:54:01 2011
@@ -2696,7 +2696,8 @@ def deep_trees_run_tests_scheme_for_swit
         x_status.wc_dir = local
 
       run_and_verify_switch(local, local, incoming, x_out, x_disk, None,
-                            error_re_string = test_case.error_re_string)
+                            test_case.error_re_string, None, None, None,
+                            None, False, '--ignore-ancestry')
       run_and_verify_unquiet_status(local, x_status)
 
       x_info = test_case.expected_info or {}

Modified: subversion/trunk/subversion/tests/cmdline/svnversion_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/svnversion_tests.py?rev=1087015&r1=1087014&r2=1087015&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/svnversion_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/svnversion_tests.py Wed Mar 30 
16:54:01 2011
@@ -107,7 +107,9 @@ def svnversion_test(sbox):
   if svntest.actions.run_and_verify_switch(wc_dir, iota_path, gamma_url,
                                            expected_output,
                                            expected_disk,
-                                           expected_status):
+                                           expected_status,
+                                           None, None, None, None, None,
+                                           False, '--ignore-ancestry'):
     raise svntest.Failure
 
   # Prop modified, mixed, part wc switched

Modified: subversion/trunk/subversion/tests/cmdline/switch_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/switch_tests.py?rev=1087015&r1=1087014&r2=1087015&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/switch_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/switch_tests.py Wed Mar 30 
16:54:01 2011
@@ -131,9 +131,11 @@ def do_routine_switching(wc_dir, repo_ur
     svntest.actions.run_and_verify_switch(wc_dir, iota_path, gamma_url,
                                           expected_output,
                                           expected_disk,
-                                          expected_status)
+                                          expected_status,
+                                          None, None, None, None, None,
+                                          False, '--ignore-ancestry')
   else:
-    svntest.main.run_svn(None, 'switch',
+    svntest.main.run_svn(None, 'switch', '--ignore-ancestry',
                          gamma_url, iota_path)
 
   ### Switch the directory `A/B' to `A/D/G'.
@@ -165,10 +167,12 @@ def do_routine_switching(wc_dir, repo_ur
     svntest.actions.run_and_verify_switch(wc_dir, AB_path, ADG_url,
                                           expected_output,
                                           expected_disk,
-                                          expected_status)
+                                          expected_status,
+                                          None, None, None, None, None,
+                                          False, '--ignore-ancestry')
   else:
-    svntest.main.run_svn(None,
-                         'switch', ADG_url, AB_path)
+    svntest.main.run_svn(None, 'switch', '--ignore-ancestry',
+                         ADG_url, AB_path)
 
 
 #----------------------------------------------------------------------
@@ -671,7 +675,9 @@ def delete_subdir(sbox):
   svntest.actions.run_and_verify_switch(wc_dir, A_path, A2_url,
                                         expected_output,
                                         expected_disk,
-                                        expected_status)
+                                        expected_status,
+                                        None, None, None, None, None,
+                                        False, '--ignore-ancestry')
 
 #----------------------------------------------------------------------
 # Issue 1532: Switch a file to a dir: can't switch it back to the file
@@ -686,13 +692,13 @@ def file_dir_file(sbox):
   file_url = sbox.repo_url + '/iota'
   dir_url = sbox.repo_url + '/A/C'
 
-  svntest.actions.run_and_verify_svn(None, None, [],
-                                     'switch', dir_url, file_path)
+  svntest.actions.run_and_verify_svn(None, None, [], 'switch',
+                                     '--ignore-ancestry', dir_url, file_path)
   if not os.path.isdir(file_path):
     raise svntest.Failure
 
-  svntest.actions.run_and_verify_svn(None, None, [],
-                                     'switch', file_url, file_path)
+  svntest.actions.run_and_verify_svn(None, None, [], 'switch',
+                                     '--ignore-ancestry', file_url, file_path)
   if not os.path.isfile(file_path):
     raise svntest.Failure
 
@@ -736,8 +742,8 @@ def nonrecursive_switching(sbox):
   svntest.main.run_svn(None, 'ci', '-m', '', wc1_dir)
 
   # Try to switch "wc2" to the branch (non-recursively)
-  svntest.actions.run_and_verify_svn(None, None, [],
-                                     'switch', '-N', version1_url, wc2_dir)
+  svntest.actions.run_and_verify_svn(None, None, [], 'switch', '-N',
+                                     '--ignore-ancestry', version1_url, 
wc2_dir)
 
   # Check the URLs of the (not switched) directories.
   expected_infos = [
@@ -783,7 +789,8 @@ def failed_anchor_is_target(sbox):
 
   # This switch raises a tree conflict on 'psi', because of the local mods.
   svntest.actions.run_and_verify_svn(None, svntest.verify.AnyOutput, [],
-                                     'switch', G_url, H_path)
+                                     'switch', '--ignore-ancestry',
+                                     G_url, H_path)
 
   expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
   expected_status.tweak('A/D/H', switched='S', wc_rev=2)
@@ -878,8 +885,8 @@ def bad_intermediate_urls(sbox):
   })
 
   actions.run_and_verify_switch(wc_dir, wc_dir, url_A_C, expected_output,
-    expected_disk, expected_status, None, None, None, None, None, False)
-
+                                expected_disk, expected_status, None, None,
+                                None, None, None, False, '--ignore-ancestry')
 
   # However, the URL for wc/A should now reflect ^/A/C/A, not something else.
   expected_infos = [
@@ -974,8 +981,9 @@ def obstructed_switch(sbox):
   expected_status.tweak('A/B/E/beta', wc_rev='3')
 
   actions.run_and_verify_switch(wc_dir, A_B_E, url_A_B_Esave,
-    expected_output, expected_disk, expected_status, None, None, None, None,
-    None, False)
+                                expected_output, expected_disk,
+                                expected_status, None, None, None, None,
+                                None, False, '--ignore-ancestry')
 
   # svn status
   expected_status.add({
@@ -1030,7 +1038,9 @@ def commit_mods_below_switch(sbox):
   svntest.actions.run_and_verify_switch(wc_dir, C_path, B_url,
                                         expected_output,
                                         expected_disk,
-                                        expected_status)
+                                        expected_status,
+                                        None, None, None, None, None,
+                                        False, '--ignore-ancestry')
 
   D_path = os.path.join(wc_dir, 'A', 'D')
   svntest.actions.run_and_verify_svn(None, None, [],
@@ -1078,6 +1088,7 @@ def relocate_beyond_repos_root(sbox):
   svntest.actions.run_and_verify_svn(None, None,
                                      ".*Invalid relocation destination.*",
                                      'switch', '--relocate',
+                                     '--ignore-ancestry',
                                      A_url, other_B_url, A_wc_dir)
 
   # Another way of trying to change the fs path, leading to an invalid
@@ -1085,10 +1096,12 @@ def relocate_beyond_repos_root(sbox):
   svntest.actions.run_and_verify_svn(None, None,
                                      ".*is not the root.*",
                                      'switch', '--relocate',
+                                     '--ignore-ancestry',
                                      repo_url, other_B_url, A_wc_dir)
 
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'switch', '--relocate',
+                                     '--ignore-ancestry',
                                      A_url, other_A_url, A_wc_dir)
 
   # Check that we can contact the repository, meaning that the
@@ -1162,7 +1175,9 @@ def refresh_read_only_attribute(sbox):
   svntest.actions.run_and_verify_switch(wc_dir, A_path, branch_url,
                                         expected_output,
                                         expected_disk,
-                                        expected_status)
+                                        expected_status,
+                                        None, None, None, None, None,
+                                        False, '--ignore-ancestry')
 
   # The file with we set svn:needs-lock on should now be writable, but
   # is still read-only!
@@ -1193,7 +1208,7 @@ def switch_change_repos_root(sbox):
                  ".*No repository found.*"
   svntest.actions.run_and_verify_svn(None, None,
                                      expected_err,
-                                     'switch',
+                                     'switch', '--ignore-ancestry',
                                      other_A_url, A_wc_dir)
 
   # Test 2: A switch that changes the repo root part of the URL shouldn't work.
@@ -1203,7 +1218,7 @@ def switch_change_repos_root(sbox):
   svntest.main.create_repos(other_repo_dir)
   svntest.actions.run_and_verify_svn(None, None,
                                      ".*UUID.*",
-                                     'switch',
+                                     'switch', '--ignore-ancestry',
                                      other_A_url, A_wc_dir)
 
   # Make sure we didn't break the WC.
@@ -1240,6 +1255,7 @@ def relocate_and_propset(sbox):
   svntest.main.copy_repos(repo_dir, other_repo_dir, 1, 0)
   svntest.main.safe_rmtree(repo_dir, 1)
   svntest.actions.run_and_verify_svn(None, None, [], 'switch', '--relocate',
+                                     '--ignore-ancestry',
                                      repo_url, other_repo_url, wc_dir)
 
   # Remove gamma from the working copy.
@@ -1350,8 +1366,8 @@ def forced_switch(sbox):
                                         expected_output,
                                         expected_disk,
                                         expected_status, None,
-                                        None, None, None, None, 0,
-                                        '--force')
+                                        None, None, None, None, False,
+                                        '--force', '--ignore-ancestry')
 
 #----------------------------------------------------------------------
 def forced_switch_failures(sbox):
@@ -1459,8 +1475,9 @@ def forced_switch_failures(sbox):
   expected_status.tweak('A/C', switched='S')
 
   actions.run_and_verify_switch(wc_dir, A_C, url_A_D, expected_output,
-    expected_disk, expected_status, None, None, None, None, None, False,
-    '--force')
+                                expected_disk, expected_status, None, None,
+                                None, None, None, False, '--force',
+                                '--ignore-ancestry')
 
 
   # 2) A forced switch that tries to add a dir when a file of the same
@@ -1485,8 +1502,9 @@ def forced_switch_failures(sbox):
   expected_status.tweak('A/B/F', switched='S')
 
   actions.run_and_verify_switch(wc_dir, A_B_F, url_A_D_G, expected_output,
-    expected_disk, expected_status, None, None, None, None, None, False,
-    '--force')
+                                expected_disk, expected_status, None, None,
+                                None, None, None, False, '--force',
+                                '--ignore-ancestry')
 
   # svn info A/B/F/pi
   expected_stdout = verify.ExpectedOutput(
@@ -1532,7 +1550,8 @@ def forced_switch_failures(sbox):
                     '.*a separate working copy.*already exists')
 
   actions.run_and_verify_switch(wc_dir, A_D_G, url_A_D_H, None, None, None,
-    expected_error, None, None, None, None, False, '--force')
+                                expected_error, None, None, None, None,
+                                False, '--force', '--ignore-ancestry')
 
   # Delete all three obstructions and finish the update.
   # rm -rf A/D/G/I
@@ -1686,7 +1705,8 @@ def switch_with_obstructing_local_adds(s
                                         expected_status,
                                         None,
                                         svntest.tree.detect_conflict_files,
-                                        extra_files, None, None, 0)
+                                        extra_files, None, None, False,
+                                        '--ignore-ancestry')
 
 #----------------------------------------------------------------------
 
@@ -1701,8 +1721,9 @@ def switch_scheduled_add(sbox):
   svntest.main.file_append(file_path, "")
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'add', file_path)
-  svntest.actions.run_and_verify_svn(None, None, [],
-                                     'switch', switch_url, file_path)
+  svntest.actions.run_and_verify_svn(None, None, [], 'switch',
+                                     '--ignore-ancestry',
+                                     switch_url, file_path)
 
 #----------------------------------------------------------------------
 @SkipUnless(server_has_mergeinfo)
@@ -1934,7 +1955,8 @@ def mergeinfo_switch_elision(sbox):
                                         expected_output,
                                         expected_disk,
                                         expected_status,
-                                        None, None, None, None, None, 1)
+                                        None, None, None, None, None, True,
+                                        '--ignore-ancestry')
 
   # Now check a switch which reverses and earlier switch and leaves
   # a path in an unswitched state.
@@ -1955,7 +1977,8 @@ def mergeinfo_switch_elision(sbox):
                                         expected_output,
                                         expected_disk,
                                         expected_status,
-                                        None, None, None, None, None, 1)
+                                        None, None, None, None, None, True,
+                                        '--ignore-ancestry')
 
   svntest.actions.run_and_verify_svn(None,
                                      ["property '" + SVN_PROP_MERGEINFO +
@@ -1976,7 +1999,8 @@ def mergeinfo_switch_elision(sbox):
                                         expected_output,
                                         expected_disk,
                                         expected_status,
-                                        None, None, None, None, None, 1)
+                                        None, None, None, None, None, True,
+                                        '--ignore-ancestry')
 
 #----------------------------------------------------------------------
 
@@ -2006,8 +2030,8 @@ def switch_with_depth(sbox):
                                         expected_output,
                                         expected_disk,
                                         expected_status, None,
-                                        None, None, None, None, 0,
-                                        '--depth', 'empty')
+                                        None, None, None, None, False,
+                                        '--depth', 'empty', 
'--ignore-ancestry')
 
   # Set up expected results for reverting 'switch --depth=empty'
   expected_output = svntest.wc.State(wc_dir, {})
@@ -2018,8 +2042,8 @@ def switch_with_depth(sbox):
                                         expected_output,
                                         expected_disk,
                                         expected_status, None,
-                                        None, None, None, None, 0,
-                                        '--depth', 'empty')
+                                        None, None, None, None, False,
+                                        '--depth', 'empty', 
'--ignore-ancestry')
 
   # Set up expected results of 'switch --depth=files'
   expected_output = svntest.wc.State(wc_dir, {
@@ -2045,8 +2069,8 @@ def switch_with_depth(sbox):
                                         expected_output,
                                         expected_disk,
                                         expected_status, None,
-                                        None, None, None, None, 0,
-                                        '--depth', 'files')
+                                        None, None, None, None, False,
+                                        '--depth', 'files', 
'--ignore-ancestry')
 
   # Set up expected results for reverting 'switch --depth=files'
   expected_output = svntest.wc.State(wc_dir, {
@@ -2060,8 +2084,8 @@ def switch_with_depth(sbox):
                                         expected_output,
                                         expected_disk,
                                         expected_status, None,
-                                        None, None, None, None, 0,
-                                        '--depth', 'files')
+                                        None, None, None, None, False,
+                                        '--depth', 'files', 
'--ignore-ancestry')
 
   # Putting the depth=immediates stuff in a subroutine, because we're
   # going to run it at least twice.
@@ -2098,8 +2122,9 @@ def switch_with_depth(sbox):
                                           expected_output,
                                           expected_disk,
                                           expected_status, None,
-                                          None, None, None, None, 0,
-                                          '--depth', 'immediates')
+                                          None, None, None, None, False,
+                                          '--depth', 'immediates',
+                                          '--ignore-ancestry')
 
   sw_depth_imm()
 
@@ -2122,7 +2147,8 @@ def switch_with_depth(sbox):
                                         expected_output,
                                         expected_disk,
                                         expected_status, None,
-                                        None, None, None, None, 0)
+                                        None, None, None, None, False,
+                                        '--ignore-ancestry')
 
   # Okay, repeat 'switch --depth=immediates'.  (Afterwards we'll
   # 'switch --depth=infinity', to test going all the way.)
@@ -2147,8 +2173,9 @@ def switch_with_depth(sbox):
                                         expected_output,
                                         expected_disk,
                                         expected_status, None,
-                                        None, None, None, None, 0,
-                                        '--depth', 'infinity')
+                                        None, None, None, None, False,
+                                        '--depth', 'infinity',
+                                        '--ignore-ancestry')
 
 #----------------------------------------------------------------------
 
@@ -2213,8 +2240,8 @@ def switch_to_dir_with_peg_rev(sbox):
                                         expected_output,
                                         expected_disk,
                                         expected_status, None,
-                                        None, None, None, None, 0,
-                                        '-r', '2')
+                                        None, None, None, None, False,
+                                        '-r', '2', '--ignore-ancestry')
 
 def switch_urls_with_spaces(sbox):
   "switch file and dir to url containing spaces"
@@ -2258,7 +2285,9 @@ def switch_urls_with_spaces(sbox):
   svntest.actions.run_and_verify_switch(wc_dir, ABC_path, XYZ_url,
                                         expected_output,
                                         expected_disk,
-                                        expected_status)
+                                        expected_status,
+                                        None, None, None, None, None,
+                                        False, '--ignore-ancestry')
 
   # Test 2: switch file 'bar baz bal' to 'tau pau mau'
   tpm_url = repo_url + '/tau pau mau'
@@ -2283,7 +2312,9 @@ def switch_urls_with_spaces(sbox):
   svntest.actions.run_and_verify_switch(wc_dir, bbb_path, tpm_url,
                                         expected_output,
                                         expected_disk,
-                                        expected_status)
+                                        expected_status,
+                                        None, None, None, None, None,
+                                        False, '--ignore-ancestry')
 
 def switch_to_dir_with_peg_rev2(sbox):
   "switch to old rev of now renamed branch"
@@ -2350,8 +2381,8 @@ def switch_to_dir_with_peg_rev2(sbox):
                                         expected_output,
                                         expected_disk,
                                         expected_status, None,
-                                        None, None, None, None, 0,
-                                        '-r', '2')
+                                        None, None, None, None, False,
+                                        '-r', '2', '--ignore-ancestry')
 
 def switch_to_root(sbox):
   "switch a folder to the root of its repository"
@@ -2401,7 +2432,9 @@ def switch_to_root(sbox):
   svntest.actions.run_and_verify_switch(wc_dir, ADG_path, sbox.repo_url,
                                         expected_output,
                                         expected_disk,
-                                        expected_status)
+                                        expected_status,
+                                        None, None, None, None, None,
+                                        False, '--ignore-ancestry')
 
 #----------------------------------------------------------------------
 # Make sure that switch continue after deleting locally modified
@@ -2448,7 +2481,9 @@ def tolerate_local_mods(sbox):
   svntest.actions.run_and_verify_switch(wc_dir, A_path, A2_url,
                                         expected_output,
                                         expected_disk,
-                                        expected_status)
+                                        expected_status,
+                                        None, None, None, None, None,
+                                        False, '--ignore-ancestry')
 
 #----------------------------------------------------------------------
 
@@ -2978,6 +3013,7 @@ def single_file_relocate(sbox):
   svntest.actions.run_and_verify_svn(None, None,
                                      ".*Cannot relocate.*",
                                      'switch', '--relocate',
+                                     '--ignore-ancestry',
                                      iota_url, other_iota_url, iota_path)
 
 
@@ -2998,6 +3034,7 @@ def relocate_with_switched_children(sbox
 
   # Do the switch and check the results in three ways.
   svntest.actions.run_and_verify_svn(None, None, [], 'switch', '--relocate',
+                                     '--ignore-ancestry',
                                      repo_url, other_repo_url, wc_dir)
 
   # Attempt to commit changes and examine results
@@ -3047,7 +3084,8 @@ def copy_with_switched_subdir(sbox):
   svntest.actions.run_and_verify_status(wc_dir, state)
 
   # Switch D
-  svntest.actions.run_and_verify_svn(None, None, [], 'switch', E_url, G)
+  svntest.actions.run_and_verify_svn(None, None, [], 'switch',
+                                     '--ignore-ancestry', E_url, G)
 
   state.tweak('A/D/G', switched='S')
   state.remove('A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau');
@@ -3097,7 +3135,8 @@ def copy_with_switched_subdir(sbox):
                                      sbox.repo_url, wc_dir)
 
   # Switch D again to recreate state
-  svntest.actions.run_and_verify_svn(None, None, [], 'switch', E_url, G)
+  svntest.actions.run_and_verify_svn(None, None, [], 'switch',
+                                     '--ignore-ancestry', E_url, G)
 
   # Clear the statuses
   state.tweak(status='  ', copied=None, wc_rev='2')
@@ -3130,8 +3169,9 @@ def relocate_with_relative_externals(sbo
 
   # Now relocate our working copy.
   svntest.actions.run_and_verify_svn(None, None, [], 'switch', '--relocate',
+                                     '--ignore-ancestry',
                                      repo_url, other_repo_url, wc_dir)
-
+  
   # Check the URLs of the externals -- were they updated to point to the
   # .other repository URL?
   svntest.actions.run_and_verify_info([{ 'URL' : '.*.other/A/D/G$' }],


Reply via email to