Author: rhuijben
Date: Thu Dec 19 09:46:43 2013
New Revision: 1552265
URL: http://svn.apache.org/r1552265
Log:
Re-use ra sessions when determining where a path is copied from using a
libsvn_client internal api. Give public api a caller from our test suite
by adding a simple C test.
* subversion/libsvn_client/client.h
(svn_client__get_copy_source): Add argument.
* subversion/libsvn_client/log.c
(svn_client__get_copy_source): Add support for using an existing session.
* subversion/libsvn_client/merge.c
(normalize_merge_sources_internal): Pass existing ra session.
* subversion/libsvn_client/mergeinfo.c
(svn_client_suggest_merge_sources): Open ra session and pass it to two
functions instead of having them create and close their own sessions.
Use subpool.
* subversion/tests/libsvn_client/client-test.c
(test_suggest_mergesources): New test.
(test_funcs): Add test_suggest_mergesources.
Modified:
subversion/trunk/subversion/libsvn_client/client.h
subversion/trunk/subversion/libsvn_client/log.c
subversion/trunk/subversion/libsvn_client/merge.c
subversion/trunk/subversion/libsvn_client/mergeinfo.c
subversion/trunk/subversion/tests/libsvn_client/client-test.c
Modified: subversion/trunk/subversion/libsvn_client/client.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/client.h?rev=1552265&r1=1552264&r2=1552265&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/client.h (original)
+++ subversion/trunk/subversion/libsvn_client/client.h Thu Dec 19 09:46:43 2013
@@ -93,12 +93,17 @@ svn_client__get_revision_number(svn_revn
/* Set *ORIGINAL_REPOS_RELPATH and *ORIGINAL_REVISION to the original location
that served as the source of the copy from which PATH_OR_URL at REVISION was
created, or NULL and SVN_INVALID_REVNUM (respectively) if PATH_OR_URL at
- REVISION was not the result of a copy operation. */
+ REVISION was not the result of a copy operation.
+
+ If RA_SESSION is not NULL it is an existing session to the repository that
+ might be reparented temporarily to obtain the information.
+ */
svn_error_t *
svn_client__get_copy_source(const char **original_repos_relpath,
svn_revnum_t *original_revision,
const char *path_or_url,
const svn_opt_revision_t *revision,
+ svn_ra_session_t *ra_session,
svn_client_ctx_t *ctx,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
Modified: subversion/trunk/subversion/libsvn_client/log.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/log.c?rev=1552265&r1=1552264&r2=1552265&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/log.c (original)
+++ subversion/trunk/subversion/libsvn_client/log.c Thu Dec 19 09:46:43 2013
@@ -96,6 +96,7 @@ svn_client__get_copy_source(const char *
svn_revnum_t *original_revision,
const char *path_or_url,
const svn_opt_revision_t *revision,
+ svn_ra_session_t *ra_session,
svn_client_ctx_t *ctx,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
@@ -103,18 +104,49 @@ svn_client__get_copy_source(const char *
svn_error_t *err;
copyfrom_info_t copyfrom_info = { 0 };
apr_pool_t *sesspool = svn_pool_create(scratch_pool);
- svn_ra_session_t *ra_session;
svn_client__pathrev_t *at_loc;
+ const char *old_session_url = NULL;
copyfrom_info.is_first = TRUE;
copyfrom_info.path = NULL;
copyfrom_info.rev = SVN_INVALID_REVNUM;
copyfrom_info.pool = result_pool;
- SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &at_loc,
- path_or_url, NULL,
- revision, revision,
- ctx, sesspool));
+ if (!ra_session)
+ {
+ SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &at_loc,
+ path_or_url, NULL,
+ revision, revision,
+ ctx, sesspool));
+ }
+ else
+ {
+ const char *url;
+ if (svn_path_is_url(path_or_url))
+ url = path_or_url;
+ else
+ {
+ SVN_ERR(svn_client_url_from_path2(&url, path_or_url, ctx, sesspool,
+ sesspool));
+
+ return svn_error_createf(SVN_ERR_ENTRY_MISSING_URL, NULL,
+ _("'%s' has no URL"), path_or_url);
+ }
+
+ SVN_ERR(svn_client__ensure_ra_session_url(&old_session_url, ra_session,
+ url, sesspool));
+
+ err = svn_client__resolve_rev_and_url(&at_loc, ra_session, path_or_url,
+ revision, revision, ctx,
+ sesspool);
+
+ /* On error reparent back (and return), otherwise reparent to new
+ location */
+ SVN_ERR(svn_error_compose_create(
+ err,
+ svn_ra_reparent(ra_session, err ? old_session_url
+ : at_loc->url, sesspool)));
+ }
/* Find the copy source. Walk the location segments to find the revision
at which this node was created (copied or added). */
@@ -124,6 +156,11 @@ svn_client__get_copy_source(const char *
copyfrom_info_receiver, ©from_info,
scratch_pool);
+ if (old_session_url)
+ err = svn_error_compose_create(
+ err,
+ svn_ra_reparent(ra_session, old_session_url, sesspool));
+
svn_pool_destroy(sesspool);
if (err)
Modified: subversion/trunk/subversion/libsvn_client/merge.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/merge.c?rev=1552265&r1=1552264&r2=1552265&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/merge.c (original)
+++ subversion/trunk/subversion/libsvn_client/merge.c Thu Dec 19 09:46:43 2013
@@ -7066,7 +7066,8 @@ normalize_merge_sources_internal(apr_arr
SVN_ERR(svn_client__get_copy_source(&original_repos_relpath,
&original_revision,
segment_url,
- &range_start_rev, ctx,
+ &range_start_rev,
+ ra_session, ctx,
result_pool, scratch_pool));
/* Got copyfrom data? Fix up the first segment to cover
back to COPYFROM_REV + 1, and then prepend a new
Modified: subversion/trunk/subversion/libsvn_client/mergeinfo.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/mergeinfo.c?rev=1552265&r1=1552264&r2=1552265&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/mergeinfo.c (original)
+++ subversion/trunk/subversion/libsvn_client/mergeinfo.c Thu Dec 19 09:46:43
2013
@@ -2231,6 +2231,8 @@ svn_client_suggest_merge_sources(apr_arr
svn_mergeinfo_catalog_t mergeinfo_cat;
svn_mergeinfo_t mergeinfo;
apr_hash_index_t *hi;
+ apr_pool_t *session_pool = svn_pool_create(pool);
+ svn_ra_session_t *ra_session;
list = apr_array_make(pool, 1, sizeof(const char *));
@@ -2249,17 +2251,21 @@ svn_client_suggest_merge_sources(apr_arr
1. The copyfrom source.
2. All remaining merge sources (unordered).
*/
+ SVN_ERR(svn_client__ra_session_from_path2(&ra_session, NULL, path_or_url,
+ NULL, peg_revision, peg_revision,
+ ctx, session_pool));
- /* ### TODO: Share ra_session batons to improve efficiency? */
SVN_ERR(get_mergeinfo(&mergeinfo_cat, &repos_root, path_or_url,
- peg_revision, FALSE, FALSE, ctx, NULL, pool, pool));
+ peg_revision, FALSE, FALSE,
+ ctx, ra_session, session_pool, session_pool));
if (mergeinfo_cat && apr_hash_count(mergeinfo_cat))
{
/* We asked only for the PATH_OR_URL's mergeinfo, not any of its
descendants. So if there is anything in the catalog it is the
mergeinfo for PATH_OR_URL. */
- mergeinfo = svn__apr_hash_index_val(apr_hash_first(pool, mergeinfo_cat));
+ mergeinfo = svn__apr_hash_index_val(apr_hash_first(session_pool,
+ mergeinfo_cat));
}
else
{
@@ -2267,17 +2273,19 @@ svn_client_suggest_merge_sources(apr_arr
}
SVN_ERR(svn_client__get_copy_source(©from_path, ©from_rev,
- path_or_url, peg_revision, ctx,
- pool, pool));
+ path_or_url, peg_revision, ra_session,
+ ctx, session_pool, session_pool));
if (copyfrom_path)
{
APR_ARRAY_PUSH(list, const char *) =
- svn_path_url_add_component2(repos_root, copyfrom_path, pool);
+ svn_path_url_add_component2(repos_root, copyfrom_path, session_pool);
}
if (mergeinfo)
{
- for (hi = apr_hash_first(pool, mergeinfo); hi; hi = apr_hash_next(hi))
+ for (hi = apr_hash_first(session_pool, mergeinfo);
+ hi;
+ hi = apr_hash_next(hi))
{
const char *rel_path = svn__apr_hash_index_key(hi);
@@ -2287,6 +2295,8 @@ svn_client_suggest_merge_sources(apr_arr
}
}
+ svn_pool_destroy(session_pool);
+
*suggestions = list;
return SVN_NO_ERROR;
}
Modified: subversion/trunk/subversion/tests/libsvn_client/client-test.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_client/client-test.c?rev=1552265&r1=1552264&r2=1552265&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_client/client-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_client/client-test.c Thu Dec 19
09:46:43 2013
@@ -769,6 +769,39 @@ test_foreign_repos_copy(const svn_test_o
return SVN_NO_ERROR;
}
+static svn_error_t *
+test_suggest_mergesources(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ const char *repos_url;
+ svn_client_ctx_t *ctx;
+ svn_client_mtcc_t *mtcc;
+ apr_array_header_t *results;
+ svn_opt_revision_t peg_rev;
+
+ peg_rev.kind = svn_opt_revision_unspecified;
+
+ /* Create a filesytem and repository containing the Greek tree. */
+ SVN_ERR(create_greek_repos(&repos_url, "mergesources", opts, pool));
+
+ SVN_ERR(svn_client_create_context(&ctx, pool));
+
+ SVN_ERR(svn_client_mtcc_create(&mtcc, repos_url, -1, ctx, pool, pool));
+ SVN_ERR(svn_client_mtcc_add_copy("A", 1, "AA", mtcc, pool));
+ SVN_ERR(svn_client_mtcc_commit(NULL, NULL, NULL, mtcc, pool));
+
+ SVN_ERR(svn_client_suggest_merge_sources(
+ &results,
+ svn_path_url_add_component2(repos_url, "AA", pool),
+ &peg_rev, ctx, pool));
+ SVN_TEST_ASSERT(results != NULL);
+ SVN_TEST_ASSERT(results->nelts >= 1);
+ SVN_TEST_STRING_ASSERT(APR_ARRAY_IDX(results, 0, const char *),
+ svn_path_url_add_component2(repos_url, "A", pool));
+
+ return SVN_NO_ERROR;
+}
+
/* ==========================================================================
*/
@@ -789,5 +822,7 @@ struct svn_test_descriptor_t test_funcs[
SVN_TEST_OPTS_PASS(test_16k_add, "test adding 16k files"),
#endif
SVN_TEST_OPTS_PASS(test_youngest_common_ancestor, "test
youngest_common_ancestor"),
+ SVN_TEST_OPTS_PASS(test_suggest_mergesources,
+ "test svn_client_suggest_merge_sources"),
SVN_TEST_NULL
};