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$' }],