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 2012/03/25 17:45:41 UTC
svn commit: r1305066 - /subversion/trunk/subversion/libsvn_client/merge.c
Author: julianfoad
Date: Sun Mar 25 15:45:41 2012
New Revision: 1305066
URL: http://svn.apache.org/viewvc?rev=1305066&view=rev
Log:
Replace (url, rev) pairs with repo_location_t structs in merge code.
* subversion/libsvn_client/merge.c
(repo_location_create, repos_location, get_youngest_common_ancestor):
New functions.
(...everywhere...): Replace (url, rev) pairs with repo_location_t structs.
Modified:
subversion/trunk/subversion/libsvn_client/merge.c
Modified: subversion/trunk/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/merge.c?rev=1305066&r1=1305065&r2=1305066&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/merge.c (original)
+++ subversion/trunk/subversion/libsvn_client/merge.c Sun Mar 25 15:45:41 2012
@@ -328,6 +328,33 @@ typedef struct merge_cmd_baton_t {
/*** Utilities ***/
+/* Return a new repo_location_t structure, allocated in RESULT_POOL,
+ * initialized with deep copies of REPO, REV and URL. */
+static repo_location_t *
+repo_location_create(const url_uuid_t *repo,
+ svn_revnum_t rev,
+ const char *url,
+ apr_pool_t *result_pool)
+{
+ repo_location_t *loc = apr_palloc(result_pool, sizeof(*loc));
+
+ /* ### This 'if' is because 'repo' currently can be null, at least in a
+ * repo_location_t inside a merge_source_t. */
+ if (repo)
+ {
+ loc->repo = apr_palloc(result_pool, sizeof(*loc->repo));
+ loc->repo->url = apr_pstrdup(result_pool, repo->url);
+ loc->repo->uuid = apr_pstrdup(result_pool, repo->uuid);
+ }
+ else
+ {
+ loc->repo = NULL;
+ }
+ loc->rev = rev;
+ loc->url = apr_pstrdup(result_pool, url);
+ return loc;
+}
+
/* Return a deep copy of LOC, allocated in RESULT_POOL. */
static repo_location_t *
repo_location_dup(const repo_location_t *loc,
@@ -381,6 +408,56 @@ merge_source_dup(const merge_source_t *s
return s;
}
+/* Like svn_client__repos_location() but using repo_location_t for input
+ * and output. */
+static svn_error_t *
+repos_location(repo_location_t **op_loc_p,
+ svn_ra_session_t *ra_session,
+ const repo_location_t *peg_loc,
+ svn_revnum_t op_revnum,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ *op_loc_p = apr_palloc(result_pool, sizeof(**op_loc_p));
+ (*op_loc_p)->repo = peg_loc->repo;
+ (*op_loc_p)->rev = op_revnum;
+ SVN_ERR(svn_client__repos_location(&(*op_loc_p)->url, ra_session,
+ peg_loc->url, peg_loc->rev,
+ op_revnum,
+ ctx, result_pool, scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+/* Set *ANCESTOR_P to the location of the youngest common ancestor of
+ * LOC1 and LOC2. If the locations have no common ancestor, set
+ * *ANCESTOR_P to NULL.
+ *
+ * Like svn_client__get_youngest_common_ancestor() but using repo_location_t
+ * for input and output.
+ */
+static svn_error_t *
+get_youngest_common_ancestor(repo_location_t **ancestor_p,
+ const repo_location_t *loc1,
+ const repo_location_t *loc2,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ const char *url;
+ svn_revnum_t rev;
+
+ SVN_ERR(svn_client__get_youngest_common_ancestor(
+ NULL, &url, &rev,
+ loc1->url, loc1->rev, loc2->url, loc2->rev,
+ ctx, result_pool));
+ if (url)
+ *ancestor_p = repo_location_create(loc1->repo, rev, url, result_pool);
+ else
+ *ancestor_p = NULL;
+ return SVN_NO_ERROR;
+}
+
/* Return SVN_ERR_UNSUPPORTED_FEATURE if URL is not inside the repository
of LOCAL_ABSPATH. Use SCRATCH_POOL for temporary allocations. */
static svn_error_t *
@@ -916,8 +993,7 @@ filter_self_referential_mergeinfo(apr_ar
int i;
apr_pool_t *iterpool;
svn_boolean_t is_added;
- const char *target_base_url;
- svn_revnum_t target_base_rev;
+ repo_location_t target_base;
/* Issue #3383: We don't want mergeinfo from a foreign repos.
@@ -945,9 +1021,9 @@ filter_self_referential_mergeinfo(apr_ar
if (is_added)
return SVN_NO_ERROR;
- SVN_ERR(svn_client_url_from_path2(&target_base_url, target_abspath,
+ SVN_ERR(svn_client_url_from_path2(&target_base.url, target_abspath,
ctx, pool, pool));
- SVN_ERR(svn_wc__node_get_base_rev(&target_base_rev, ctx->wc_ctx,
+ SVN_ERR(svn_wc__node_get_base_rev(&target_base.rev, ctx->wc_ctx,
target_abspath, pool));
adjusted_props = apr_array_make(pool, (*props)->nelts, sizeof(svn_prop_t));
@@ -1018,7 +1094,7 @@ filter_self_referential_mergeinfo(apr_ar
the cost of a roundtrip communication with the repository. */
SVN_ERR(split_mergeinfo_on_revision(&younger_mergeinfo,
&mergeinfo,
- target_base_rev,
+ target_base.rev,
iterpool));
/* Filter self-referential mergeinfo from younger_mergeinfo. */
@@ -1047,7 +1123,7 @@ filter_self_referential_mergeinfo(apr_ar
for (j = 0; j < rangelist->nelts; j++)
{
svn_error_t *err2;
- const char *start_url;
+ repo_location_t *start_loc;
svn_merge_range_t *range =
APR_ARRAY_IDX(rangelist, j, svn_merge_range_t *);
@@ -1059,10 +1135,10 @@ filter_self_referential_mergeinfo(apr_ar
/* Check if PATH@BASE_REVISION exists at
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_base_url, target_base_rev,
- range->start + 1,
- ctx, iterpool, iterpool);
+ err2 = repos_location(&start_loc, ra_session,
+ &target_base,
+ range->start + 1,
+ ctx, iterpool, iterpool);
if (err2)
{
if (err2->apr_err == SVN_ERR_CLIENT_UNRELATED_RESOURCES
@@ -1107,7 +1183,7 @@ filter_self_referential_mergeinfo(apr_ar
PATH@RANGE->END actually belong to some other
line of history and we want to record this
mergeinfo, not filter it. */
- if (strcmp(start_url, merge_source_url) != 0)
+ if (strcmp(start_loc->url, merge_source_url) != 0)
{
APR_ARRAY_PUSH(adjusted_rangelist,
svn_merge_range_t *) = range;
@@ -1136,8 +1212,8 @@ filter_self_referential_mergeinfo(apr_ar
svn_mergeinfo_t implicit_mergeinfo;
SVN_ERR(svn_client__get_history_as_mergeinfo(
- &implicit_mergeinfo, NULL, target_base_url,
- target_base_rev, target_base_rev, SVN_INVALID_REVNUM,
+ &implicit_mergeinfo, NULL, target_base.url,
+ target_base.rev, target_base.rev, SVN_INVALID_REVNUM,
ra_session, ctx, iterpool));
/* Remove PATH's implicit mergeinfo from the incoming mergeinfo. */
@@ -4126,14 +4202,13 @@ calculate_remaining_ranges(svn_client__m
/* Hmmm, an inoperative reverse merge from the "future". If it is
from our own future return a helpful error. */
svn_error_t *err;
- const char *start_url;
+ repo_location_t *start_loc;
- err = svn_client__repos_location(&start_url,
- ra_session,
- source->loc1->url,
- source->loc1->rev,
- child_base_revision,
- ctx, scratch_pool, scratch_pool);
+ err = repos_location(&start_loc,
+ ra_session,
+ source->loc1,
+ child_base_revision,
+ ctx, scratch_pool, scratch_pool);
if (err)
{
if (err->apr_err == SVN_ERR_FS_NOT_FOUND
@@ -4148,7 +4223,7 @@ calculate_remaining_ranges(svn_client__m
SVN_ERR(svn_wc__node_get_url(&url, ctx->wc_ctx, child->abspath,
scratch_pool, scratch_pool));
- if (strcmp(start_url, url) == 0)
+ if (strcmp(start_loc->url, url) == 0)
return svn_error_create(SVN_ERR_CLIENT_MERGE_UPDATE_REQUIRED, NULL,
_("Cannot reverse-merge a range from a "
"path's own future history; try "
@@ -6368,19 +6443,19 @@ combine_range_with_segments(apr_array_he
* no SOURCE_PATH_OR_URL argument;
* MERGE_RANGE_TS (array of svn_merge_range_t *) instead of RANGES;
* SOURCE_PEG_REVNUM instead of SOURCE_PEG_REVISION.
- * RA_SESSION is an RA session open to the repository of SOURCE_URL; it may
+ * RA_SESSION is an RA session open to the repository of SOURCE_LOC; it may
* be temporarily reparented within this function.
*/
static svn_error_t *
normalize_merge_sources_internal(apr_array_header_t **merge_sources_p,
- const char *source_url,
- svn_revnum_t source_peg_revnum,
+ const repo_location_t *source_loc,
const apr_array_header_t *merge_range_ts,
svn_ra_session_t *ra_session,
svn_client_ctx_t *ctx,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
+ svn_revnum_t source_peg_revnum = source_loc->rev;
svn_revnum_t oldest_requested, youngest_requested;
svn_revnum_t trim_revision = SVN_INVALID_REVNUM;
const char *source_root_url;
@@ -6405,19 +6480,18 @@ normalize_merge_sources_internal(apr_arr
all the underlying APIs would do in this case right now anyway). */
if (source_peg_revnum < youngest_requested)
{
- const char *start_url;
+ repo_location_t *start_loc;
- SVN_ERR(svn_client__repos_location(&start_url,
- ra_session, source_url,
- source_peg_revnum,
- youngest_requested,
- ctx, scratch_pool, scratch_pool));
+ SVN_ERR(repos_location(&start_loc,
+ ra_session, source_loc,
+ youngest_requested,
+ ctx, scratch_pool, scratch_pool));
source_peg_revnum = youngest_requested;
}
/* Fetch the locations for our merge range span. */
SVN_ERR(svn_client__repos_location_segments(&segments,
- ra_session, source_url,
+ ra_session, source_loc->url,
source_peg_revnum,
youngest_requested,
oldest_requested,
@@ -6534,12 +6608,12 @@ normalize_merge_sources_internal(apr_arr
requested merges; order the objects from oldest to youngest.
Determine the requested merges by examining SOURCE_PATH_OR_URL (and its
- associated URL and revision, SOURCE_URL and SOURCE_PEG_REVNUM) (which
+ associated URL and revision, SOURCE_LOC) (which
specifies the line of history from which merges will be pulled) and
RANGES_TO_MERGE (a list of svn_opt_revision_range_t's which provide
revision ranges).
- RA_SESSION is an RA session open to the repository of SOURCE_URL; it may
+ RA_SESSION is an RA session open to the repository of SOURCE_LOC; it may
be temporarily reparented within this function. Use RA_SESSION to answer
historical questions.
@@ -6554,8 +6628,7 @@ normalize_merge_sources_internal(apr_arr
static svn_error_t *
normalize_merge_sources(apr_array_header_t **merge_sources_p,
const char *source_path_or_url,
- const char *source_url,
- svn_revnum_t source_peg_revnum,
+ const repo_location_t *source_loc,
const apr_array_header_t *ranges_to_merge,
svn_ra_session_t *ra_session,
svn_client_ctx_t *ctx,
@@ -6614,7 +6687,7 @@ normalize_merge_sources(apr_array_header
}
SVN_ERR(normalize_merge_sources_internal(
- merge_sources_p, source_url, source_peg_revnum,
+ merge_sources_p, source_loc,
merge_range_ts, ra_session, ctx, result_pool, scratch_pool));
svn_pool_destroy(iterpool);
@@ -9126,13 +9199,13 @@ merge_cousins_and_supplement_mergeinfo(c
SVN_ERR_ASSERT(svn_dirent_is_absolute(target->abspath));
SVN_ERR(normalize_merge_sources_internal(
- &remove_sources, source->loc1->url, source->loc1->rev,
+ &remove_sources, source->loc1,
svn_rangelist__initialize(source->loc1->rev, yc_rev, TRUE,
scratch_pool),
URL1_ra_session, ctx, scratch_pool, subpool));
SVN_ERR(normalize_merge_sources_internal(
- &add_sources, source->loc2->url, source->loc2->rev,
+ &add_sources, source->loc2,
svn_rangelist__initialize(yc_rev, source->loc2->rev, TRUE,
scratch_pool),
URL2_ra_session, ctx, scratch_pool, subpool));
@@ -9424,8 +9497,7 @@ merge_locked(const char *source1,
apr_array_header_t *merge_sources;
svn_error_t *err;
svn_boolean_t use_sleep = FALSE;
- const char *yc_url = NULL;
- svn_revnum_t yc_rev = SVN_INVALID_REVNUM;
+ repo_location_t *yca = NULL;
apr_pool_t *sesspool;
svn_boolean_t same_repos;
@@ -9461,12 +9533,8 @@ merge_locked(const char *source1,
/* Unless we're ignoring ancestry, see if the two sources are related. */
if (! ignore_ancestry)
- SVN_ERR(svn_client__get_youngest_common_ancestor(NULL, &yc_url, &yc_rev,
- source1_loc->url,
- source1_loc->rev,
- source2_loc->url,
- source2_loc->rev,
- ctx, scratch_pool));
+ SVN_ERR(get_youngest_common_ancestor(&yca, source1_loc, source2_loc,
+ ctx, scratch_pool, scratch_pool));
/* Check for a youngest common ancestor. If we have one, we'll be
doing merge tracking.
@@ -9485,32 +9553,32 @@ merge_locked(const char *source1,
merge recording, then record-only two merges:
from A to C, and from C to B
*/
- if (yc_url && SVN_IS_VALID_REVNUM(yc_rev))
+ if (yca)
{
/* Note that our merge sources are related. */
related = TRUE;
/* If the common ancestor matches the right side of our merge,
then we only need to reverse-merge the left side. */
- if ((strcmp(yc_url, source2_loc->url) == 0)
- && (yc_rev == source2_loc->rev))
+ if ((strcmp(yca->url, source2_loc->url) == 0)
+ && (yca->rev == source2_loc->rev))
{
ancestral = TRUE;
SVN_ERR(normalize_merge_sources_internal(
- &merge_sources, source1_loc->url, source1_loc->rev,
- svn_rangelist__initialize(source1_loc->rev, yc_rev, TRUE,
+ &merge_sources, source1_loc,
+ svn_rangelist__initialize(source1_loc->rev, yca->rev, TRUE,
scratch_pool),
ra_session1, ctx, scratch_pool, scratch_pool));
}
/* If the common ancestor matches the left side of our merge,
then we only need to merge the right side. */
- else if ((strcmp(yc_url, source1_loc->url) == 0)
- && (yc_rev == source1_loc->rev))
+ else if ((strcmp(yca->url, source1_loc->url) == 0)
+ && (yca->rev == source1_loc->rev))
{
ancestral = TRUE;
SVN_ERR(normalize_merge_sources_internal(
- &merge_sources, source2_loc->url, source2_loc->rev,
- svn_rangelist__initialize(yc_rev, source2_loc->rev, TRUE,
+ &merge_sources, source2_loc,
+ svn_rangelist__initialize(yca->rev, source2_loc->rev, TRUE,
scratch_pool),
ra_session2, ctx, scratch_pool, scratch_pool));
}
@@ -9524,7 +9592,7 @@ merge_locked(const char *source1,
ra_session1,
ra_session2,
&source,
- yc_rev,
+ yca->rev,
same_repos,
depth,
ignore_ancestry, force,
@@ -9850,24 +9918,24 @@ log_find_operative_revs(void *baton,
return SVN_NO_ERROR;
}
-/* Determine if the mergeinfo on a reintegrate source SOURCE_REPOS_REL_PATH,
+/* Determine if the mergeinfo on a reintegrate source SOURCE_LOC,
reflects that the source is fully synced with the reintegrate target
- TARGET_REPOS_REL_PATH, even if a naive interpretation of the source's
+ TARGET_LOC, even if a naive interpretation of the source's
mergeinfo says otherwise -- See issue #3577.
UNMERGED_CATALOG represents the history (as mergeinfo) from
- TARGET_REPOS_REL_PATH that is not represented in SOURCE_REPOS_REL_PATH's
+ TARGET_LOC that is not represented in SOURCE_LOC's
explicit/inherited mergeinfo as represented by MERGED_CATALOG.
MERGEINFO_CATALOG may be empty if the source has no explicit or inherited
mergeinfo.
- Using RA_SESSION, which is pointed at TARGET_REPOS_REL_PATH, check that all
+ Using RA_SESSION, which is pointed at TARGET_LOC, check that all
of the unmerged revisions in UNMERGED_CATALOG's mergeinfos are "phantoms",
that is, one of the following conditions holds:
- 1) The revision affects no corresponding paths in SOURCE_REPOS_REL_PATH.
+ 1) The revision affects no corresponding paths in SOURCE_LOC.
- 2) The revision affects corresponding paths in SOURCE_REPOS_REL_PATH,
+ 2) The revision affects corresponding paths in SOURCE_LOC,
but based on the mergeinfo in MERGED_CATALOG, the change was
previously merged.
@@ -9879,8 +9947,8 @@ log_find_operative_revs(void *baton,
Use SCRATCH_POOL for all temporary allocations. */
static svn_error_t *
-find_unsynced_ranges(const char *source_repos_rel_path,
- const char *target_repos_rel_path,
+find_unsynced_ranges(const repo_location_t *source_loc,
+ const repo_location_t *target_loc,
svn_mergeinfo_catalog_t unmerged_catalog,
svn_mergeinfo_catalog_t merged_catalog,
svn_mergeinfo_catalog_t true_unmerged_catalog,
@@ -9914,6 +9982,12 @@ find_unsynced_ranges(const char *source_
are not yet merged to it. */
if (potentially_unmerged_ranges)
{
+ const char *source_repos_rel_path
+ = svn_uri_skip_ancestor(source_loc->repo->url, source_loc->url,
+ scratch_pool);
+ const char *target_repos_rel_path
+ = svn_uri_skip_ancestor(target_loc->repo->url, target_loc->url,
+ scratch_pool);
svn_revnum_t oldest_rev =
(APR_ARRAY_IDX(potentially_unmerged_ranges,
0,
@@ -10289,7 +10363,7 @@ find_unmerged_mergeinfo(svn_mergeinfo_ca
/* Helper for svn_client_merge_reintegrate() which calculates the
'left hand side' of the underlying two-URL merge that a --reintegrate
merge actually performs. If no merge should be performed, set
- *URL_LEFT to NULL and *REV_LEFT to SVN_INVALID_REVNUM.
+ *LEFT_P to NULL.
TARGET->abspath is the absolute working copy path of the reintegrate
merge.
@@ -10312,12 +10386,11 @@ find_unmerged_mergeinfo(svn_mergeinfo_ca
SOURCE_RA_SESSION is a session opened to the SOURCE_LOC
and TARGET_RA_SESSION is open to TARGET->loc.url.
- *URL_LEFT, *MERGED_TO_SOURCE_CATALOG , and *UNMERGED_TO_SOURCE_CATALOG are
+ *LEFT_P, *MERGED_TO_SOURCE_CATALOG , and *UNMERGED_TO_SOURCE_CATALOG are
allocated in RESULT_POOL. SCRATCH_POOL is used for all temporary
allocations. */
static svn_error_t *
-calculate_left_hand_side(const char **url_left,
- svn_revnum_t *rev_left,
+calculate_left_hand_side(repo_location_t **left_p,
svn_mergeinfo_t *merged_to_source_catalog,
svn_mergeinfo_t *unmerged_to_source_catalog,
const merge_target_t *target,
@@ -10337,13 +10410,11 @@ calculate_left_hand_side(const char **ur
/* hash of paths mapped to arrays of svn_mergeinfo_t. */
apr_hash_t *target_history_hash = apr_hash_make(scratch_pool);
svn_revnum_t youngest_merged_rev;
- const char *yc_ancestor_url;
- svn_revnum_t yc_ancestor_rev;
+ repo_location_t *yc_ancestor;
const char *source_repos_rel_path;
/* Initialize our return variables. */
- *url_left = NULL;
- *rev_left = SVN_INVALID_REVNUM;
+ *left_p = NULL;
/* TARGET->abspath may not have explicit mergeinfo and thus may not be
contained within SUBTREES_WITH_MERGEINFO. If this is the case then
@@ -10389,15 +10460,12 @@ calculate_left_hand_side(const char **ur
APR_HASH_KEY_STRING, target_history_as_mergeinfo);
}
- /* Check that SOURCE_URL@SOURCE_REV and TARGET_URL@TARGET_REV are
+ /* Check that SOURCE_LOC and TARGET->loc are
actually related, we can't reintegrate if they are not. Also
- get an initial value for YC_ANCESTOR_REV. */
- SVN_ERR(svn_client__get_youngest_common_ancestor(NULL, &yc_ancestor_url,
- &yc_ancestor_rev,
- source_loc->url, source_loc->rev,
- target->loc.url, target->loc.rev,
- ctx, iterpool));
- if (!(yc_ancestor_url && SVN_IS_VALID_REVNUM(yc_ancestor_rev)))
+ get an initial value for the YCA revision number. */
+ SVN_ERR(get_youngest_common_ancestor(&yc_ancestor, source_loc, &target->loc,
+ ctx, iterpool, iterpool));
+ if (! yc_ancestor)
return svn_error_createf(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
_("'%s@%ld' must be ancestrally related to "
"'%s@%ld'"), source_loc->url, source_loc->rev,
@@ -10406,7 +10474,7 @@ calculate_left_hand_side(const char **ur
/* If the source revision is the same as the youngest common
revision, then there can't possibly be any unmerged revisions
that we need to apply to target. */
- if (source_loc->rev == yc_ancestor_rev)
+ if (source_loc->rev == yc_ancestor->rev)
{
svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
@@ -10439,7 +10507,7 @@ calculate_left_hand_side(const char **ur
TARGET_REPOS_REL_PATH@TARGET_REV to SOURCE_REPOS_REL_PATH@SOURCE_REV. */
SVN_ERR(find_unmerged_mergeinfo(&unmerged_catalog,
&youngest_merged_rev,
- yc_ancestor_rev,
+ yc_ancestor->rev,
mergeinfo_catalog,
target_history_hash,
source_repos_rel_path,
@@ -10459,19 +10527,16 @@ calculate_left_hand_side(const char **ur
if (youngest_merged_rev == SVN_INVALID_REVNUM)
{
/* We never merged to the source. Just return the branch point. */
- *url_left = apr_pstrdup(result_pool, yc_ancestor_url);
- *rev_left = yc_ancestor_rev;
+ *left_p = repo_location_dup(yc_ancestor, result_pool);
}
else
{
/* We've previously merged some or all of the target, up to
youngest_merged_rev, to the source. Set
- *URL_LEFT and *REV_LEFT to cover the youngest part of this range. */
- *rev_left = youngest_merged_rev;
- SVN_ERR(svn_client__repos_location(url_left, target_ra_session,
- target->loc.url, target->loc.rev,
- youngest_merged_rev,
- ctx, result_pool, iterpool));
+ *LEFT_P to cover the youngest part of this range. */
+ SVN_ERR(repos_location(left_p, target_ra_session,
+ &target->loc, youngest_merged_rev,
+ ctx, result_pool, iterpool));
}
svn_pool_destroy(iterpool);
@@ -10487,14 +10552,14 @@ calculate_left_hand_side(const char **ur
*
* Set *SOURCE_P to
* the source-left and source-right locations of the required merge. Set
- * *YC_ANCESTOR_REV_P to the revision number of the youngest ancestor.
+ * *YC_ANCESTOR_P to the location of the youngest ancestor.
* Any of these output pointers may be NULL if not wanted.
*
* See svn_client_find_reintegrate_merge() for other details.
*/
static svn_error_t *
find_reintegrate_merge(merge_source_t **source_p,
- svn_revnum_t *yc_ancestor_rev_p,
+ repo_location_t **yc_ancestor_p,
svn_ra_session_t *source_ra_session,
const repo_location_t *source_loc,
svn_ra_session_t *target_ra_session,
@@ -10503,9 +10568,8 @@ find_reintegrate_merge(merge_source_t **
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- const char *yc_ancestor_relpath;
- svn_revnum_t yc_ancestor_rev;
- repo_location_t loc1 = { 0 };
+ repo_location_t *yc_ancestor;
+ repo_location_t *loc1;
merge_source_t source;
svn_mergeinfo_t unmerged_to_source_mergeinfo_catalog;
svn_mergeinfo_t merged_to_source_mergeinfo_catalog;
@@ -10535,7 +10599,7 @@ find_reintegrate_merge(merge_source_t **
err = svn_error_quick_wrap(err, _("Reintegrate merge not possible"));
SVN_ERR(err);
- SVN_ERR(calculate_left_hand_side(&loc1.url, &loc1.rev,
+ SVN_ERR(calculate_left_hand_side(&loc1,
&merged_to_source_mergeinfo_catalog,
&unmerged_to_source_mergeinfo_catalog,
target,
@@ -10548,16 +10612,16 @@ find_reintegrate_merge(merge_source_t **
/* Did calculate_left_hand_side() decide that there was no merge to
be performed here? */
- if (! loc1.url)
+ if (! loc1)
{
if (source_p)
*source_p = NULL;
- if (yc_ancestor_rev_p)
- *yc_ancestor_rev_p = SVN_INVALID_REVNUM;
+ if (yc_ancestor_p)
+ *yc_ancestor_p = NULL;
return SVN_NO_ERROR;
}
- source.loc1 = &loc1;
+ source.loc1 = loc1;
source.loc2 = source_loc;
/* If the target was moved after the source was branched from it,
@@ -10566,33 +10630,24 @@ find_reintegrate_merge(merge_source_t **
if (strcmp(source.loc1->url, target->loc.url))
SVN_ERR(svn_ra_reparent(target_ra_session, source.loc1->url, scratch_pool));
- SVN_ERR(svn_client__get_youngest_common_ancestor(&yc_ancestor_relpath, NULL,
- &yc_ancestor_rev,
- source.loc2->url,
- source.loc2->rev,
- source.loc1->url,
- source.loc1->rev,
- ctx, scratch_pool));
+ SVN_ERR(get_youngest_common_ancestor(&yc_ancestor, source.loc2, source.loc1,
+ ctx, scratch_pool, scratch_pool));
- if (!(yc_ancestor_relpath && SVN_IS_VALID_REVNUM(yc_ancestor_rev)))
+ if (! yc_ancestor)
return svn_error_createf(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
_("'%s@%ld' must be ancestrally related to "
"'%s@%ld'"),
source.loc1->url, source.loc1->rev,
source.loc2->url, source.loc2->rev);
- if (source.loc1->rev > yc_ancestor_rev)
+ if (source.loc1->rev > yc_ancestor->rev)
{
/* Have we actually merged anything to the source from the
target? If so, make sure we've merged a contiguous
prefix. */
svn_mergeinfo_t final_unmerged_catalog = apr_hash_make(scratch_pool);
- const char *source_repos_rel_path
- = svn_uri_skip_ancestor(source_loc->repo->url, source_loc->url,
- scratch_pool);
- SVN_ERR(find_unsynced_ranges(source_repos_rel_path,
- yc_ancestor_relpath,
+ SVN_ERR(find_unsynced_ranges(source_loc, yc_ancestor,
unmerged_to_source_mergeinfo_catalog,
merged_to_source_mergeinfo_catalog,
final_unmerged_catalog,
@@ -10614,7 +10669,7 @@ find_reintegrate_merge(merge_source_t **
"previously merged from %s to the "
"reintegrate source, but this is "
"not the case:\n%s"),
- yc_ancestor_rev + 1, source.loc2->rev,
+ yc_ancestor->rev + 1, source.loc2->rev,
target->loc.url,
source_mergeinfo_cat_string->data);
}
@@ -10625,8 +10680,8 @@ find_reintegrate_merge(merge_source_t **
if (source_p)
*source_p = merge_source_dup(&source, result_pool);
- if (yc_ancestor_rev_p)
- *yc_ancestor_rev_p = yc_ancestor_rev;
+ if (yc_ancestor_p)
+ *yc_ancestor_p = repo_location_dup(yc_ancestor, result_pool);
return SVN_NO_ERROR;
}
@@ -10759,7 +10814,7 @@ merge_reintegrate_locked(const char *sou
merge_target_t *target;
repo_location_t *source_loc;
merge_source_t *source;
- svn_revnum_t yc_ancestor_rev;
+ repo_location_t *yc_ancestor;
svn_boolean_t use_sleep;
svn_error_t *err;
@@ -10768,7 +10823,7 @@ merge_reintegrate_locked(const char *sou
source_path_or_url, source_peg_revision, target_abspath,
ctx, scratch_pool, scratch_pool));
- SVN_ERR(find_reintegrate_merge(&source, &yc_ancestor_rev,
+ SVN_ERR(find_reintegrate_merge(&source, &yc_ancestor,
source_ra_session, source_loc,
target_ra_session, target,
ctx, scratch_pool, scratch_pool));
@@ -10786,7 +10841,7 @@ merge_reintegrate_locked(const char *sou
err = merge_cousins_and_supplement_mergeinfo(target,
target_ra_session,
source_ra_session,
- source, yc_ancestor_rev,
+ source, yc_ancestor->rev,
TRUE /* same_repos */,
svn_depth_infinity,
FALSE /* ignore_ancestry */,
@@ -10872,7 +10927,7 @@ merge_peg_locked(const char *source_path
/* Normalize our merge sources. */
SVN_ERR(normalize_merge_sources(&merge_sources, source_path_or_url,
- source_loc->url, source_loc->rev,
+ source_loc,
ranges_to_merge, ra_session, ctx,
scratch_pool, scratch_pool));
@@ -11034,7 +11089,6 @@ find_base_on_source(repo_location_t **ba
repo_location_t loc1 = { 0 };
merge_source_t source;
svn_merge_range_t *r;
- repo_location_t *base;
merge_target = svn_client__merge_path_create(s_t->target->abspath,
scratch_pool);
@@ -11063,11 +11117,10 @@ find_base_on_source(repo_location_t **ba
ctx, scratch_pool, scratch_pool));
r = APR_ARRAY_IDX(merge_target->remaining_ranges, 0, svn_merge_range_t *);
- base = apr_palloc(result_pool, sizeof(*base));
- base->url = s_t->source->url; /* ### WRONG: need historical URL */
- base->rev = r->start;
- *base_p = base;
+ /* ### WRONG: need historical URL instead of s_t->source->url. */
+ *base_p = repo_location_create(s_t->source->repo, r->start, s_t->source->url,
+ result_pool);
return SVN_NO_ERROR;
}
@@ -11097,7 +11150,6 @@ find_base_on_target(repo_location_t **ba
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- repo_location_t *base = apr_palloc(result_pool, sizeof(*base));
svn_mergeinfo_t unmerged_to_source_mergeinfo_catalog;
svn_mergeinfo_t merged_to_source_mergeinfo_catalog;
apr_hash_t *subtrees_with_mergeinfo;
@@ -11108,7 +11160,7 @@ find_base_on_target(repo_location_t **ba
svn_depth_infinity,
ctx, scratch_pool, scratch_pool));
- SVN_ERR(calculate_left_hand_side(&base->url, &base->rev,
+ SVN_ERR(calculate_left_hand_side(base_p,
&merged_to_source_mergeinfo_catalog,
&unmerged_to_source_mergeinfo_catalog,
s_t->target,
@@ -11118,14 +11170,12 @@ find_base_on_target(repo_location_t **ba
s_t->target_ra_session,
ctx, result_pool, scratch_pool));
- if (base->url)
+ if (*base_p)
{
- *base_p = base;
*mid_p = s_t->source; /* ### WRONG! This is quite difficult. */
}
else
{
- *base_p = NULL;
*mid_p = NULL;
}
@@ -11143,15 +11193,10 @@ find_symmetric_merge(repo_location_t **y
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- repo_location_t *yca, *base_on_source, *base_on_target, *mid;
+ repo_location_t *base_on_source, *base_on_target, *mid;
- yca = apr_palloc(result_pool, sizeof(*yca));
- SVN_ERR(svn_client__get_youngest_common_ancestor(
- NULL, &yca->url, &yca->rev,
- s_t->source->url, s_t->source->rev,
- s_t->target->loc.url, s_t->target->loc.rev,
- ctx, result_pool));
- *yca_p = yca;
+ SVN_ERR(get_youngest_common_ancestor(yca_p, s_t->source, &s_t->target->loc,
+ ctx, result_pool, result_pool));
/* Find the latest revision of A synced to B and the latest
* revision of B synced to A.
@@ -11187,7 +11232,7 @@ find_symmetric_merge(repo_location_t **y
* the base is the youngest common ancestor of the branches. We'll
* set MID=NULL; in theory the end result should be the same if we
* set MID=YCA instead. */
- *base_p = yca;
+ *base_p = *yca_p;
*mid_p = NULL;
}