You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2011/11/10 14:29:32 UTC
svn commit: r1200324 - in /subversion/trunk/subversion/libsvn_client:
client.h merge.c ra.c
Author: julianfoad
Date: Thu Nov 10 13:29:31 2011
New Revision: 1200324
URL: http://svn.apache.org/viewvc?rev=1200324&view=rev
Log:
Simplify the merge code a bit by introducing and using a simpler version of
svn_client__repos_locations() to eliminate a bunch of boiler-plate code.
* subversion/libsvn_client/client.h,
subversion/libsvn_client/ra.c
(svn_client__repos_location): New function.
(repos_locations): New function, factored out ...
(svn_client__repos_locations): ... of here.
* subversion/libsvn_client/merge.c
(filter_self_referential_mergeinfo, calculate_remaining_ranges,
normalize_merge_sources, calculate_left_hand_side): Use it.
Modified:
subversion/trunk/subversion/libsvn_client/client.h
subversion/trunk/subversion/libsvn_client/merge.c
subversion/trunk/subversion/libsvn_client/ra.c
Modified: subversion/trunk/subversion/libsvn_client/client.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/client.h?rev=1200324&r1=1200323&r2=1200324&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/client.h (original)
+++ subversion/trunk/subversion/libsvn_client/client.h Thu Nov 10 13:29:31 2011
@@ -143,6 +143,22 @@ svn_client__repos_locations(const char *
svn_client_ctx_t *ctx,
apr_pool_t *pool);
+/* Trace a line of history of a particular versioned resource back to a
+ * specific revision.
+ *
+ * Set *OP_URL to the URL that the object PEG_URL@PEG_REVNUM had in
+ * revision OP_REVNUM.
+ * RA_SESSION is required. */
+svn_error_t *
+svn_client__repos_location(const char **start_url,
+ svn_ra_session_t *ra_session,
+ const char *peg_url,
+ svn_revnum_t peg_revnum,
+ svn_revnum_t op_revnum,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
/* Set *SEGMENTS to an array of svn_location_segment_t * objects, each
representing a reposition location segment for the history of PATH
Modified: subversion/trunk/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/merge.c?rev=1200324&r1=1200323&r2=1200324&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/merge.c (original)
+++ subversion/trunk/subversion/libsvn_client/merge.c Thu Nov 10 13:29:31 2011
@@ -973,34 +973,21 @@ filter_self_referential_mergeinfo(apr_ar
{
svn_error_t *err2;
const char *start_url;
- svn_opt_revision_t peg_rev, rev1_opt;
svn_merge_range_t *range =
APR_ARRAY_IDX(rangelist, j, svn_merge_range_t *);
- peg_rev.kind = svn_opt_revision_number;
- peg_rev.value.number = base_revision;
- rev1_opt.kind = svn_opt_revision_number;
- /* SVN_PROP_MERGEINFO only stores forward merges, so
- the start range of svn_merge_range_t RANGE is not
- inclusive. */
- rev1_opt.value.number = range->start + 1;
-
/* Because the merge source normalization code
ensures mergeinfo refers to real locations on
the same line of history, there's no need to
look at the whole range, just the start. */
/* Check if PATH@BASE_REVISION exists at
- RANGE->START on the same line of history. */
- err2 = svn_client__repos_locations(&start_url, NULL,
- NULL, NULL,
- ra_session,
- target_url,
- &peg_rev,
- &rev1_opt,
- NULL,
- ctx,
- iterpool);
+ RANGE->START on the same line of history.
+ (start+1 because RANGE->start is not inclusive.) */
+ err2 = svn_client__repos_location(&start_url, ra_session,
+ target_url, base_revision,
+ range->start + 1,
+ ctx, iterpool, iterpool);
if (err2)
{
if (err2->apr_err == SVN_ERR_CLIENT_UNRELATED_RESOURCES
@@ -4033,16 +4020,11 @@ calculate_remaining_ranges(svn_client__m
from our own future return a helpful error. */
svn_error_t *err;
const char *start_url;
- svn_opt_revision_t requested, pegrev;
- requested.kind = svn_opt_revision_number;
- requested.value.number = child_base_revision;
- pegrev.kind = svn_opt_revision_number;
- pegrev.value.number = revision1;
-
- err = svn_client__repos_locations(&start_url, NULL,
- NULL, NULL, ra_session, url1,
- &pegrev, &requested,
- NULL, ctx, scratch_pool);
+
+ err = svn_client__repos_location(&start_url,
+ ra_session, url1, revision1,
+ child_base_revision,
+ ctx, scratch_pool, scratch_pool);
if (err)
{
if (err->apr_err == SVN_ERR_FS_NOT_FOUND
@@ -6511,17 +6493,11 @@ normalize_merge_sources(apr_array_header
if (peg_revnum < youngest_requested)
{
const char *start_url;
- svn_opt_revision_t requested, pegrev;
- requested.kind = svn_opt_revision_number;
- requested.value.number = youngest_requested;
- pegrev.kind = svn_opt_revision_number;
- pegrev.value.number = peg_revnum;
-
- SVN_ERR(svn_client__repos_locations(&start_url, NULL,
- NULL, NULL,
- ra_session, source_url,
- &pegrev, &requested,
- NULL, ctx, iterpool));
+
+ SVN_ERR(svn_client__repos_location(&start_url,
+ ra_session, source_url, peg_revnum,
+ youngest_requested,
+ ctx, iterpool, iterpool));
peg_revnum = youngest_requested;
}
@@ -10559,25 +10535,11 @@ calculate_left_hand_side(const char **ur
/* We've previously merged some or all of the target, up to
youngest_merged_rev, from TARGET_ABSPATH to the source. Set
*URL_LEFT and *REV_LEFT to cover the youngest part of this range. */
- svn_opt_revision_t peg_revision, youngest_rev;
- const char *youngest_url;
-
- peg_revision.kind = svn_opt_revision_number;
- peg_revision.value.number = target_rev;
-
- youngest_rev.kind = svn_opt_revision_number;
- youngest_rev.value.number = youngest_merged_rev;
-
- *rev_left = youngest_rev.value.number;
-
- /* Get the URL of the target_url@youngest_merged_rev. */
- SVN_ERR(svn_client__repos_locations(&youngest_url, NULL,
- NULL, NULL, target_ra_session,
- target_url, &peg_revision,
- &youngest_rev, NULL,
- ctx, iterpool));
-
- *url_left = apr_pstrdup(result_pool, youngest_url);
+ *rev_left = youngest_merged_rev;
+ SVN_ERR(svn_client__repos_location(url_left, target_ra_session,
+ target_url, target_rev,
+ youngest_merged_rev,
+ ctx, result_pool, iterpool));
}
svn_pool_destroy(iterpool);
Modified: subversion/trunk/subversion/libsvn_client/ra.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/ra.c?rev=1200324&r1=1200323&r2=1200324&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/ra.c (original)
+++ subversion/trunk/subversion/libsvn_client/ra.c Thu Nov 10 13:29:31 2011
@@ -577,6 +577,100 @@ svn_client__repos_location_segments(apr_
return SVN_NO_ERROR;
}
+/* Set *START_URL and *END_URL to the URLs that the object URL@PEG_REVNUM
+ * had in revisions START_REVNUM and END_REVNUM. Return an error if the
+ * node cannot be traced back to one of the requested revisions.
+ *
+ * START_URL and/or END_URL may be NULL if not wanted. START_REVNUM and
+ * END_REVNUM must be valid revision numbers except that END_REVNUM may
+ * be SVN_INVALID_REVNUM if END_URL is NULL. RA_SESSION is required.
+ */
+static svn_error_t *
+repos_locations(const char **start_url,
+ const char **end_url,
+ svn_ra_session_t *ra_session,
+ const char *url,
+ svn_revnum_t peg_revnum,
+ svn_revnum_t start_revnum,
+ svn_revnum_t end_revnum,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ const char *repos_url, *start_path, *end_path;
+ apr_array_header_t *revs;
+ apr_hash_t *rev_locs;
+
+ SVN_ERR_ASSERT(peg_revnum != SVN_INVALID_REVNUM);
+ SVN_ERR_ASSERT(start_revnum != SVN_INVALID_REVNUM);
+ SVN_ERR_ASSERT(end_revnum != SVN_INVALID_REVNUM || end_url == NULL);
+
+ /* Avoid a network request in the common easy case. */
+ if (start_revnum == peg_revnum
+ && (end_revnum == peg_revnum || end_revnum == SVN_INVALID_REVNUM))
+ {
+ if (start_url)
+ *start_url = url;
+ if (end_url)
+ *end_url = url;
+ return SVN_NO_ERROR;
+ }
+
+ SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_url, scratch_pool));
+
+ revs = apr_array_make(scratch_pool, 2, sizeof(svn_revnum_t));
+ APR_ARRAY_PUSH(revs, svn_revnum_t) = start_revnum;
+ if (end_revnum != start_revnum && end_revnum != SVN_INVALID_REVNUM)
+ APR_ARRAY_PUSH(revs, svn_revnum_t) = end_revnum;
+
+ SVN_ERR(svn_ra_get_locations(ra_session, &rev_locs, "", peg_revnum,
+ revs, scratch_pool));
+
+ /* We'd better have all the paths we were looking for! */
+ if (start_url)
+ {
+ start_path = apr_hash_get(rev_locs, &start_revnum, sizeof(svn_revnum_t));
+ if (! start_path)
+ return svn_error_createf
+ (SVN_ERR_CLIENT_UNRELATED_RESOURCES, NULL,
+ _("Unable to find repository location for '%s' in revision %ld"),
+ url, start_revnum);
+ *start_url = svn_path_url_add_component2(repos_url, start_path + 1,
+ result_pool);
+ }
+
+ if (end_url)
+ {
+ end_path = apr_hash_get(rev_locs, &end_revnum, sizeof(svn_revnum_t));
+ if (! end_path)
+ return svn_error_createf
+ (SVN_ERR_CLIENT_UNRELATED_RESOURCES, NULL,
+ _("The location for '%s' for revision %ld does not exist in the "
+ "repository or refers to an unrelated object"),
+ url, end_revnum);
+
+ *end_url = svn_path_url_add_component2(repos_url, end_path + 1,
+ result_pool);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client__repos_location(const char **op_url,
+ svn_ra_session_t *ra_session,
+ const char *peg_url,
+ svn_revnum_t peg_revnum,
+ svn_revnum_t op_revnum,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ SVN_ERR(repos_locations(op_url, NULL,
+ ra_session, peg_url, peg_revnum,
+ op_revnum, SVN_INVALID_REVNUM,
+ result_pool, scratch_pool));
+ return SVN_NO_ERROR;
+}
svn_error_t *
svn_client__repos_locations(const char **start_url,
@@ -591,16 +685,11 @@ svn_client__repos_locations(const char *
svn_client_ctx_t *ctx,
apr_pool_t *pool)
{
- const char *repos_url;
const char *url;
- const char *start_path = NULL;
- const char *end_path = NULL;
const char *local_abspath_or_url;
svn_revnum_t peg_revnum = SVN_INVALID_REVNUM;
svn_revnum_t start_revnum, end_revnum;
svn_revnum_t youngest_rev = SVN_INVALID_REVNUM;
- apr_array_header_t *revs;
- apr_hash_t *rev_locs;
apr_pool_t *subpool = svn_pool_create(pool);
/* Ensure that we are given some real revision data to work with.
@@ -711,47 +800,10 @@ svn_client__repos_locations(const char *
*end_revision = end_revnum;
}
- if (start_revnum == peg_revnum && end_revnum == peg_revnum)
- {
- /* Avoid a network request in the common easy case. */
- *start_url = url;
- if (end->kind != svn_opt_revision_unspecified)
- *end_url = url;
- svn_pool_destroy(subpool);
- return SVN_NO_ERROR;
- }
-
- SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_url, subpool));
-
- revs = apr_array_make(subpool, 2, sizeof(svn_revnum_t));
- APR_ARRAY_PUSH(revs, svn_revnum_t) = start_revnum;
- if (end_revnum != start_revnum)
- APR_ARRAY_PUSH(revs, svn_revnum_t) = end_revnum;
-
- SVN_ERR(svn_ra_get_locations(ra_session, &rev_locs, "", peg_revnum,
- revs, subpool));
-
- /* We'd better have all the paths we were looking for! */
- start_path = apr_hash_get(rev_locs, &start_revnum, sizeof(svn_revnum_t));
- if (! start_path)
- return svn_error_createf
- (SVN_ERR_CLIENT_UNRELATED_RESOURCES, NULL,
- _("Unable to find repository location for '%s' in revision %ld"),
- path_or_url_local_style(path, pool), start_revnum);
-
- end_path = apr_hash_get(rev_locs, &end_revnum, sizeof(svn_revnum_t));
- if (! end_path)
- return svn_error_createf
- (SVN_ERR_CLIENT_UNRELATED_RESOURCES, NULL,
- _("The location for '%s' for revision %ld does not exist in the "
- "repository or refers to an unrelated object"),
- path_or_url_local_style(path, pool), end_revnum);
-
- /* Set our return variables */
- *start_url = svn_path_url_add_component2(repos_url, start_path + 1, pool);
- if (end->kind != svn_opt_revision_unspecified)
- *end_url = svn_path_url_add_component2(repos_url, end_path + 1, pool);
-
+ SVN_ERR(repos_locations(start_url, end_url,
+ ra_session, url, peg_revnum,
+ start_revnum, end_revnum,
+ pool, subpool));
svn_pool_destroy(subpool);
return SVN_NO_ERROR;
}