Author: stsp Date: Tue Sep 30 20:03:43 2014 New Revision: 1628536 URL: http://svn.apache.org/r1628536 Log: Fix issue #4085, "external can shadow a versioned directory".
* subversion/libsvn_client/externals.c (switch_dir_external): Don't try to switch BASE nodes over to an external. The switch will succeed, but the subsequent attempt of registering the external will fail with an error. The working copy is then left in a bad state until the path is switched back. With this fix we fail much earlier, before switching the path, allowing users to recover cleanly by removing either the external definition or the directory shadowed by the external. * subversion/tests/cmdline/externals_tests.py (shadowing): Remove XFail marker. Modified: subversion/trunk/subversion/libsvn_client/externals.c subversion/trunk/subversion/tests/cmdline/externals_tests.py Modified: subversion/trunk/subversion/libsvn_client/externals.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/externals.c?rev=1628536&r1=1628535&r2=1628536&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_client/externals.c (original) +++ subversion/trunk/subversion/libsvn_client/externals.c Tue Sep 30 20:03:43 2014 @@ -169,6 +169,37 @@ switch_dir_external(const char *local_ab if (revision->kind == svn_opt_revision_number) external_rev = revision->value.number; + /* + * The code below assumes existing versioned paths are *not* part of + * the external's defining working copy. + * The working copy library does not support registering externals + * on top of existing BASE nodes and will error out if we try. + * So if the external target is part of the defining working copy's + * BASE tree, don't attempt to create the external. Doing so would + * leave behind a switched path instead of an external (since the + * switch succeeds but registration of the external in the DB fails). + * The working copy then cannot be updated until the path is switched back. + * See issue #4085. + */ + SVN_ERR(svn_wc__node_get_base(&kind, NULL, NULL, + &repos_root_url, &repos_uuid, + NULL, ctx->wc_ctx, local_abspath, + TRUE, /* ignore_enoent */ + TRUE, /* show hidden */ + pool, pool)); + if (kind != svn_node_unknown) + { + const char *wcroot_abspath; + const char *defining_wcroot_abspath; + + SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath, ctx->wc_ctx, + local_abspath, pool, pool)); + SVN_ERR(svn_wc__get_wcroot(&defining_wcroot_abspath, ctx->wc_ctx, + defining_abspath, pool, pool)); + if (strcmp(wcroot_abspath, defining_wcroot_abspath) == 0) + return svn_error_create(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL, NULL); + } + /* If path is a directory, try to update/switch to the correct URL and revision. */ SVN_ERR(svn_io_check_path(local_abspath, &kind, pool)); Modified: subversion/trunk/subversion/tests/cmdline/externals_tests.py URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/externals_tests.py?rev=1628536&r1=1628535&r2=1628536&view=diff ============================================================================== --- subversion/trunk/subversion/tests/cmdline/externals_tests.py (original) +++ subversion/trunk/subversion/tests/cmdline/externals_tests.py Tue Sep 30 20:03:43 2014 @@ -2795,7 +2795,6 @@ def include_immediate_dir_externals(sbox @Issue(4085) -@XFail() def shadowing(sbox): "external shadows an existing dir"