Author: rhuijben
Date: Fri Dec 13 23:04:11 2013
New Revision: 1550848
URL: http://svn.apache.org/r1550848
Log:
Allow gracefull handling of the case where an 'mtcc' is opened on a file or
not existing node, by automatically reparenting one level up when allowed.
* subversion/include/svn_client.h
(svn_client_mtcc_create): Update api to allow anchoring higher.
(svn_client_mtcc_get_relpath): Update api to allow anchoring higher.
* subversion/libsvn_client/mtcc.c
(svn_client_mtcc_create): Check if the anchor exist and handle the case where
it doesn't.
(svn_client_mtcc_get_relpath): Allow requesting at least one level higher than
the passed url. (needed for things like mkdir)
* subversion/tests/libsvn_client/mtcc-test.c
(make_greek_tree,
test_mkdir,
test_mkgreek,
test_swap,
test_propset,
test_update_files,
test_overwrite): Update caller.
Modified:
subversion/trunk/subversion/include/svn_client.h
subversion/trunk/subversion/libsvn_client/mtcc.c
subversion/trunk/subversion/tests/libsvn_client/mtcc-test.c
Modified: subversion/trunk/subversion/include/svn_client.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_client.h?rev=1550848&r1=1550847&r2=1550848&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_client.h (original)
+++ subversion/trunk/subversion/include/svn_client.h Fri Dec 13 23:04:11 2013
@@ -6673,6 +6673,10 @@ typedef struct svn_client_mtcc_t svn_cli
/** Creates a new multicommand context for an operation on @a anchor_url and
* its descendants.
*
+ * If @a anchor_url does not specify an existing directory returns an
+ * SVN_ERR_FS_NOT_DIRECTORY error, except when new_anchor_url is not NULL, and
+ * the mtcc can be rooted on an ancestor.
+ *
* Allocate the context in @a result_pool and perform temporary allocations in
* @a scratch_pool.
*
@@ -6680,6 +6684,7 @@ typedef struct svn_client_mtcc_t svn_cli
*/
svn_error_t *
svn_client_mtcc_create(svn_client_mtcc_t **mtcc,
+ const char **new_anchor_url,
const char *anchor_url,
svn_revnum_t base_revision,
svn_client_ctx_t *ctx,
@@ -6694,6 +6699,7 @@ svn_client_mtcc_create(svn_client_mtcc_t
svn_error_t *
svn_client_mtcc_get_relpath(const char **relpath,
const char *url,
+ svn_boolean_t need_anchor,
svn_client_mtcc_t *mtcc,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
Modified: subversion/trunk/subversion/libsvn_client/mtcc.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/mtcc.c?rev=1550848&r1=1550847&r2=1550848&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/mtcc.c (original)
+++ subversion/trunk/subversion/libsvn_client/mtcc.c Fri Dec 13 23:04:11 2013
@@ -236,6 +236,7 @@ svn_client_mtcc_get_origin(const char **
svn_error_t *
svn_client_mtcc_create(svn_client_mtcc_t **mtcc,
+ const char **new_anchor_url,
const char *anchor_url,
svn_revnum_t base_revision,
svn_client_ctx_t *ctx,
@@ -243,6 +244,10 @@ svn_client_mtcc_create(svn_client_mtcc_t
apr_pool_t *scratch_pool)
{
apr_pool_t *mtcc_pool;
+ svn_node_kind_t kind;
+
+ if (new_anchor_url)
+ *new_anchor_url = NULL;
mtcc_pool = svn_pool_create(result_pool);
@@ -258,6 +263,26 @@ svn_client_mtcc_create(svn_client_mtcc_t
NULL /* wri_abspath */, ctx,
mtcc_pool, scratch_pool));
+ SVN_ERR(svn_ra_check_path((*mtcc)->ra_session, "", base_revision, &kind,
+ scratch_pool));
+
+ if (kind != svn_node_dir)
+ {
+ if (!new_anchor_url)
+ {
+ svn_pool_clear(mtcc_pool);
+ *mtcc = NULL;
+ return svn_error_createf(SVN_ERR_FS_NOT_DIRECTORY, NULL,
+ _("Can't open session on '%s' because "
+ "it is not a directory."),
+ anchor_url);
+ }
+
+ *new_anchor_url = svn_uri_dirname(anchor_url, result_pool);
+ SVN_ERR(svn_ra_reparent((*mtcc)->ra_session, *new_anchor_url,
+ scratch_pool));
+ }
+
return SVN_NO_ERROR;
}
@@ -290,6 +315,7 @@ update_copy_src(svn_client_mtcc_op_t *op
svn_error_t *
svn_client_mtcc_get_relpath(const char **relpath,
const char *url,
+ svn_boolean_t need_anchor,
svn_client_mtcc_t *mtcc,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
@@ -302,7 +328,9 @@ svn_client_mtcc_get_relpath(const char *
err = svn_ra_get_path_relative_to_session(mtcc->ra_session, relpath, url,
result_pool);
- if (! err || err->apr_err != SVN_ERR_RA_ILLEGAL_URL)
+ if (! err && (*relpath || !need_anchor))
+ return SVN_NO_ERROR;
+ if (err && err->apr_err != SVN_ERR_RA_ILLEGAL_URL)
return svn_error_trace(err);
svn_error_clear(err);
@@ -310,7 +338,10 @@ svn_client_mtcc_get_relpath(const char *
SVN_ERR(svn_ra_get_session_url(mtcc->ra_session, &session_url,
scratch_pool));
- new_anchor = svn_uri_get_longest_ancestor(url, session_url, scratch_pool);
+ if (!err && !*relpath && need_anchor)
+ new_anchor = svn_uri_dirname(session_url, scratch_pool);
+ else
+ new_anchor = svn_uri_get_longest_ancestor(url, session_url, scratch_pool);
if (svn_path_is_empty(new_anchor))
{
Modified: subversion/trunk/subversion/tests/libsvn_client/mtcc-test.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_client/mtcc-test.c?rev=1550848&r1=1550847&r2=1550848&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_client/mtcc-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_client/mtcc-test.c Fri Dec 13
23:04:11 2013
@@ -84,7 +84,7 @@ make_greek_tree(const char *repos_url,
subpool = svn_pool_create(scratch_pool);
SVN_ERR(svn_client_create_context2(&ctx, NULL, subpool));
- SVN_ERR(svn_client_mtcc_create(&mtcc, repos_url, 0, ctx, subpool, subpool));
+ SVN_ERR(svn_client_mtcc_create(&mtcc, NULL, repos_url, 0, ctx, subpool,
subpool));
for (i = 0; svn_test__greek_tree_nodes[i].path; i++)
{
@@ -130,7 +130,7 @@ test_mkdir(const svn_test_opts_t *opts,
SVN_ERR(svn_test__create_repos(&repos, repos_abspath, opts, pool));
SVN_ERR(svn_client_create_context2(&ctx, NULL, pool));
- SVN_ERR(svn_client_mtcc_create(&mtcc, repos_url, 0, ctx, pool, pool));
+ SVN_ERR(svn_client_mtcc_create(&mtcc, NULL, repos_url, 0, ctx, pool, pool));
SVN_ERR(svn_client_mtcc_add_mkdir("branches", mtcc, pool));
SVN_ERR(svn_client_mtcc_add_mkdir("trunk", mtcc, pool));
@@ -162,7 +162,7 @@ test_mkgreek(const svn_test_opts_t *opts
SVN_ERR(make_greek_tree(repos_url, pool));
SVN_ERR(svn_client_create_context2(&ctx, NULL, pool));
- SVN_ERR(svn_client_mtcc_create(&mtcc, repos_url, 1, ctx, pool, pool));
+ SVN_ERR(svn_client_mtcc_create(&mtcc, NULL, repos_url, 1, ctx, pool, pool));
SVN_ERR(svn_client_mtcc_add_copy("A", 1, "greek_A", mtcc, pool));
@@ -189,7 +189,7 @@ test_swap(const svn_test_opts_t *opts,
SVN_ERR(make_greek_tree(repos_url, pool));
SVN_ERR(svn_client_create_context2(&ctx, NULL, pool));
- SVN_ERR(svn_client_mtcc_create(&mtcc, repos_url, 1, ctx, pool, pool));
+ SVN_ERR(svn_client_mtcc_create(&mtcc, NULL, repos_url, 1, ctx, pool, pool));
SVN_ERR(svn_client_mtcc_add_move("A/B", "B", mtcc, pool));
SVN_ERR(svn_client_mtcc_add_move("A/D", "A/B", mtcc, pool));
@@ -218,7 +218,7 @@ test_propset(const svn_test_opts_t *opts
SVN_ERR(make_greek_tree(repos_url, pool));
SVN_ERR(svn_client_create_context2(&ctx, NULL, pool));
- SVN_ERR(svn_client_mtcc_create(&mtcc, repos_url, 1, ctx, pool, pool));
+ SVN_ERR(svn_client_mtcc_create(&mtcc, NULL, repos_url, 1, ctx, pool, pool));
SVN_ERR(svn_client_mtcc_add_propset("iota", "key",
svn_string_create("val", pool), FALSE,
@@ -257,7 +257,7 @@ test_update_files(const svn_test_opts_t
SVN_ERR(make_greek_tree(repos_url, pool));
SVN_ERR(svn_client_create_context2(&ctx, NULL, pool));
- SVN_ERR(svn_client_mtcc_create(&mtcc, repos_url, 1, ctx, pool, pool));
+ SVN_ERR(svn_client_mtcc_create(&mtcc, NULL, repos_url, 1, ctx, pool, pool));
/* Update iota with knowledge of the old data */
SVN_ERR(svn_client_mtcc_add_update_file(svn_test__greek_tree_nodes[0].path,
@@ -315,7 +315,7 @@ test_overwrite(const svn_test_opts_t *op
SVN_ERR(make_greek_tree(repos_url, pool));
SVN_ERR(svn_client_create_context2(&ctx, NULL, pool));
- SVN_ERR(svn_client_mtcc_create(&mtcc, repos_url, 1, ctx, pool, pool));
+ SVN_ERR(svn_client_mtcc_create(&mtcc, NULL, repos_url, 1, ctx, pool, pool));
SVN_ERR(svn_client_mtcc_add_copy("A", 1, "AA", mtcc, pool));