Index: subversion/libsvn_client/merge.c =================================================================== --- subversion/libsvn_client/merge.c (revision 1657782) +++ subversion/libsvn_client/merge.c (working copy) @@ -7023,7 +7023,8 @@ } /* Similar to normalize_merge_sources() except the input MERGE_RANGE_TS is a - * rangelist. + * rangelist. RA_SESSION may be NULL, in this case temporary RA session will + * be opened using SOURCE_LOC->URL. */ static svn_error_t * normalize_merge_sources_internal(apr_array_header_t **merge_sources_p, @@ -7039,6 +7040,7 @@ svn_revnum_t trim_revision = SVN_INVALID_REVNUM; apr_array_header_t *segments; int i; + svn_boolean_t new_ra_session = FALSE; /* Initialize our return variable. */ *merge_sources_p = apr_array_make(result_pool, 1, sizeof(merge_source_t *)); @@ -7047,6 +7049,14 @@ if (merge_range_ts->nelts == 0) return SVN_NO_ERROR; + if (!ra_session) + { + SVN_ERR(svn_client_open_ra_session2(&ra_session, source_loc->url, + NULL, ctx, scratch_pool, + scratch_pool)); + new_ra_session = TRUE; + } + /* Find the extremes of the revisions across our set of ranges. */ merge_range_find_extremes(&oldest_requested, &youngest_requested, merge_range_ts); @@ -7173,6 +7183,9 @@ apr_array_cat(*merge_sources_p, merge_sources); } + if (new_ra_session) + SVN_ERR(svn_client__ra_session_release(ctx, ra_session)); + return SVN_NO_ERROR; } @@ -9595,41 +9608,6 @@ return SVN_NO_ERROR; } -/** Ensure that *RA_SESSION is opened to URL, either by reusing - * *RA_SESSION if it is non-null and already opened to URL's - * repository, or by allocating a new *RA_SESSION in POOL. - * (RA_SESSION itself cannot be null, of course.) - * - * CTX is used as for svn_client_open_ra_session(). - */ -static svn_error_t * -ensure_ra_session_url(svn_ra_session_t **ra_session, - const char *url, - const char *wri_abspath, - svn_client_ctx_t *ctx, - apr_pool_t *pool) -{ - svn_error_t *err = SVN_NO_ERROR; - - if (*ra_session) - { - err = svn_ra_reparent(*ra_session, url, pool); - } - - /* SVN_ERR_RA_ILLEGAL_URL is raised when url doesn't point to the same - repository as ra_session. */ - if (! *ra_session || (err && err->apr_err == SVN_ERR_RA_ILLEGAL_URL)) - { - svn_error_clear(err); - /* RA_CACHE TODO: release RA session */ - err = svn_client_open_ra_session2(ra_session, url, wri_abspath, - ctx, pool, pool); - } - SVN_ERR(err); - - return SVN_NO_ERROR; -} - /* Drive a merge of MERGE_SOURCES into working copy node TARGET and possibly record mergeinfo describing the merge -- see RECORD_MERGEINFO(). @@ -9709,7 +9687,6 @@ svn_boolean_t *use_sleep, const apr_array_header_t *merge_sources, const merge_target_t *target, - svn_ra_session_t *src_session, svn_boolean_t sources_related, svn_boolean_t same_repos, svn_boolean_t ignore_mergeinfo, @@ -9732,8 +9709,6 @@ const char *preserved_exts_str; int i; svn_boolean_t checked_mergeinfo_capability = FALSE; - svn_ra_session_t *ra_session1 = NULL; - const char *old_src_session_url = NULL; apr_pool_t *iterpool; const svn_diff_tree_processor_t *processor; @@ -9851,13 +9826,6 @@ processor = merge_processor; } - if (src_session) - { - SVN_ERR(svn_ra_get_session_url(src_session, &old_src_session_url, - scratch_pool)); - ra_session1 = src_session; - } - for (i = 0; i < merge_sources->nelts; i++) { svn_node_kind_t src1_kind; @@ -9864,6 +9832,7 @@ merge_source_t *source = APR_ARRAY_IDX(merge_sources, i, merge_source_t *); single_range_conflict_report_t *conflicted_range_report; + svn_ra_session_t *ra_session1; svn_ra_session_t *ra_session2; svn_pool_clear(iterpool); @@ -9875,8 +9844,9 @@ continue; /* Establish RA sessions to our URLs, reuse where possible. */ - SVN_ERR(ensure_ra_session_url(&ra_session1, source->loc1->url, - target->abspath, ctx, scratch_pool)); + SVN_ERR(svn_client_open_ra_session2(&ra_session1, source->loc1->url, + target->abspath, ctx, + iterpool, iterpool)); SVN_ERR(svn_client_open_ra_session2(&ra_session2, source->loc2->url, target->abspath, ctx, iterpool, @@ -9957,6 +9927,7 @@ while (source); SVN_ERR(svn_client__ra_session_release(ctx, ra_session2)); + SVN_ERR(svn_client__ra_session_release(ctx, ra_session1)); /* The final mergeinfo on TARGET_WCPATH may itself elide. */ if (! dry_run) @@ -10001,9 +9972,6 @@ merge_cmd_baton.tree_conflicted_abspaths); } - if (src_session) - SVN_ERR(svn_ra_reparent(src_session, old_src_session_url, iterpool)); - svn_pool_destroy(iterpool); return SVN_NO_ERROR; } @@ -10016,9 +9984,8 @@ Set *CONFLICT_REPORT to indicate if there were any conflicts, as in do_merge(). - The diff to be merged is between SOURCE->loc1 (in URL1_RA_SESSION1) - and SOURCE->loc2 (in URL2_RA_SESSION2); YCA is their youngest - common ancestor. + The diff to be merged is between SOURCE->loc1 and SOURCE->loc2; + YCA is their youngest common ancestor. SAME_REPOS must be true if and only if the source URLs are in the same repository as the target working copy. @@ -10036,8 +10003,6 @@ merge_cousins_and_supplement_mergeinfo(conflict_report_t **conflict_report, svn_boolean_t *use_sleep, const merge_target_t *target, - svn_ra_session_t *URL1_ra_session, - svn_ra_session_t *URL2_ra_session, const merge_source_t *source, const svn_client__pathrev_t *yca, svn_boolean_t same_repos, @@ -10060,9 +10025,6 @@ subtree mergeinfo, then this will help keep memory use in check. */ apr_pool_t *subpool = svn_pool_create(scratch_pool); - assert(session_url_is(URL1_ra_session, source->loc1->url, scratch_pool)); - assert(session_url_is(URL2_ra_session, source->loc2->url, scratch_pool)); - SVN_ERR_ASSERT(svn_dirent_is_absolute(target->abspath)); SVN_ERR_ASSERT(! source->ancestral); @@ -10070,13 +10032,13 @@ &remove_sources, source->loc1, svn_rangelist__initialize(source->loc1->rev, yca->rev, TRUE, scratch_pool), - URL1_ra_session, ctx, scratch_pool, subpool)); + NULL, ctx, scratch_pool, subpool)); SVN_ERR(normalize_merge_sources_internal( &add_sources, source->loc2, svn_rangelist__initialize(yca->rev, source->loc2->rev, TRUE, scratch_pool), - URL2_ra_session, ctx, scratch_pool, subpool)); + NULL, ctx, scratch_pool, subpool)); *conflict_report = NULL; @@ -10091,7 +10053,7 @@ APR_ARRAY_PUSH(faux_sources, const merge_source_t *) = source; SVN_ERR(do_merge(&modified_subtrees, NULL, conflict_report, use_sleep, faux_sources, target, - URL1_ra_session, TRUE, same_repos, + TRUE, same_repos, FALSE /*ignore_mergeinfo*/, diff_ignore_ancestry, force_delete, dry_run, FALSE, NULL, TRUE, FALSE, depth, merge_options, ctx, @@ -10131,7 +10093,7 @@ svn_pool_clear(subpool); SVN_ERR(do_merge(NULL, add_result_catalog, conflict_report, use_sleep, add_sources, target, - URL1_ra_session, TRUE, same_repos, + TRUE, same_repos, FALSE /*ignore_mergeinfo*/, diff_ignore_ancestry, force_delete, dry_run, TRUE, modified_subtrees, TRUE, @@ -10146,7 +10108,7 @@ svn_pool_clear(subpool); SVN_ERR(do_merge(NULL, remove_result_catalog, conflict_report, use_sleep, remove_sources, target, - URL1_ra_session, TRUE, same_repos, + TRUE, same_repos, FALSE /*ignore_mergeinfo*/, diff_ignore_ancestry, force_delete, dry_run, TRUE, modified_subtrees, TRUE, @@ -10400,7 +10362,6 @@ svn_error_t *err; svn_boolean_t use_sleep = FALSE; svn_client__pathrev_t *yca = NULL; - apr_pool_t *sesspool; svn_boolean_t same_repos; /* ### FIXME: This function really ought to do a history check on @@ -10414,13 +10375,12 @@ /* Open RA sessions to both sides of our merge source, and resolve URLs * and revisions. */ - sesspool = svn_pool_create(scratch_pool); SVN_ERR(svn_client__ra_session_from_path2( &ra_session1, &source1_loc, - source1, NULL, revision1, revision1, ctx, sesspool)); + source1, NULL, revision1, revision1, ctx, scratch_pool)); SVN_ERR(svn_client__ra_session_from_path2( &ra_session2, &source2_loc, - source2, NULL, revision2, revision2, ctx, sesspool)); + source2, NULL, revision2, revision2, ctx, scratch_pool)); /* We can't do a diff between different repositories. */ /* ### We should also insist that the root URLs of the two sources match, @@ -10440,6 +10400,10 @@ &yca, source1_loc, source2_loc, ra_session1, ctx, scratch_pool, scratch_pool)); + /* Close our temporary RA sessions. */ + SVN_ERR(svn_client__ra_session_release(ctx, ra_session2)); + SVN_ERR(svn_client__ra_session_release(ctx, ra_session1)); + /* Check for a youngest common ancestor. If we have one, we'll be doing merge tracking. @@ -10471,7 +10435,7 @@ &merge_sources, source1_loc, svn_rangelist__initialize(source1_loc->rev, yca->rev, TRUE, scratch_pool), - ra_session1, ctx, scratch_pool, scratch_pool)); + NULL, 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. */ @@ -10482,7 +10446,7 @@ &merge_sources, source2_loc, svn_rangelist__initialize(yca->rev, source2_loc->rev, TRUE, scratch_pool), - ra_session2, ctx, scratch_pool, scratch_pool)); + NULL, ctx, scratch_pool, scratch_pool)); } /* And otherwise, we need to do both: reverse merge the left side, and merge the right. */ @@ -10497,8 +10461,6 @@ err = merge_cousins_and_supplement_mergeinfo(conflict_report, &use_sleep, target, - ra_session1, - ra_session2, &source, yca, same_repos, @@ -10510,10 +10472,6 @@ ctx, result_pool, scratch_pool); - /* Close our temporary RA sessions (this could've happened - after the second call to normalize_merge_sources() inside - the merge_cousins_and_supplement_mergeinfo() routine). */ - svn_pool_destroy(sesspool); if (use_sleep) svn_io_sleep_for_timestamps(target->abspath, scratch_pool); @@ -10532,19 +10490,11 @@ err = do_merge(NULL, NULL, conflict_report, &use_sleep, merge_sources, target, - ra_session1, sources_related, same_repos, + sources_related, same_repos, ignore_mergeinfo, diff_ignore_ancestry, force_delete, dry_run, record_only, NULL, FALSE, FALSE, depth, merge_options, ctx, result_pool, scratch_pool); - /* Close our temporary RA sessions. */ - if (!err) - { - SVN_ERR(svn_client__ra_session_release(ctx, ra_session2)); - SVN_ERR(svn_client__ra_session_release(ctx, ra_session1)); - } - svn_pool_destroy(sesspool); - if (use_sleep) svn_io_sleep_for_timestamps(target->abspath, scratch_pool); @@ -11677,6 +11627,9 @@ target_ra_session, target, ctx, scratch_pool, scratch_pool)); + SVN_ERR(svn_client__ra_session_release(ctx, source_ra_session)); + SVN_ERR(svn_client__ra_session_release(ctx, target_ra_session)); + if (! source) { return SVN_NO_ERROR; @@ -11692,8 +11645,6 @@ err = merge_cousins_and_supplement_mergeinfo(conflict_report, &use_sleep, target, - target_ra_session, - source_ra_session, source, yc_ancestor, TRUE /* same_repos */, svn_depth_infinity, @@ -11705,12 +11656,6 @@ ctx, result_pool, scratch_pool); - if (!err) - { - SVN_ERR(svn_client__ra_session_release(ctx, source_ra_session)); - SVN_ERR(svn_client__ra_session_release(ctx, target_ra_session)); - } - if (use_sleep) svn_io_sleep_for_timestamps(target_abspath, scratch_pool); @@ -11779,7 +11724,6 @@ svn_client__pathrev_t *source_loc; apr_array_header_t *merge_sources; svn_ra_session_t *ra_session; - apr_pool_t *sesspool; svn_boolean_t use_sleep = FALSE; svn_error_t *err; svn_boolean_t same_repos; @@ -11790,14 +11734,11 @@ allow_mixed_rev, TRUE, TRUE, ctx, scratch_pool, scratch_pool)); - /* Create a short lived session pool */ - sesspool = svn_pool_create(scratch_pool); - /* Open an RA session to our source URL, and determine its root URL. */ SVN_ERR(svn_client__ra_session_from_path2( &ra_session, &source_loc, source_path_or_url, NULL, source_peg_revision, source_peg_revision, - ctx, sesspool)); + ctx, scratch_pool)); /* Normalize our merge sources. */ SVN_ERR(normalize_merge_sources(&merge_sources, source_path_or_url, @@ -11808,20 +11749,18 @@ /* Check for same_repos. */ same_repos = is_same_repos(&target->loc, source_loc, TRUE /* strict_urls */); + /* We're done with our RA session. */ + SVN_ERR(svn_client__ra_session_release(ctx, ra_session)); + /* Do the real merge! (We say with confidence that our merge sources are both ancestral and related.) */ err = do_merge(NULL, NULL, conflict_report, &use_sleep, - merge_sources, target, ra_session, + merge_sources, target, TRUE /*sources_related*/, same_repos, ignore_mergeinfo, diff_ignore_ancestry, force_delete, dry_run, record_only, NULL, FALSE, FALSE, depth, merge_options, ctx, result_pool, scratch_pool); - /* We're done with our RA session. */ - if (!err) - SVN_ERR(svn_client__ra_session_release(ctx, ra_session)); - svn_pool_destroy(sesspool); - if (use_sleep) svn_io_sleep_for_timestamps(target_abspath, scratch_pool); @@ -12650,8 +12589,6 @@ if (reintegrate_like) { merge_source_t source; - svn_ra_session_t *base_ra_session; - svn_ra_session_t *right_ra_session; if (record_only) return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL, @@ -12671,17 +12608,18 @@ "and the force_delete option " "cannot be used with this kind of merge")); - SVN_ERR(svn_client_open_ra_session2(&right_ra_session, merge->right->url, - target->abspath, ctx, scratch_pool, - scratch_pool)); - /* Check for and reject any abnormalities -- such as revisions that * have not yet been merged in the opposite direction -- that a * 'reintegrate' merge would have rejected. */ { merge_source_t *source2; + svn_ra_session_t *right_ra_session; svn_ra_session_t *target_ra_session; + SVN_ERR(svn_client_open_ra_session2(&right_ra_session, merge->right->url, + target->abspath, ctx, scratch_pool, + scratch_pool)); + SVN_ERR(svn_client_open_ra_session2(&target_ra_session, target->loc.url, target->abspath, ctx, scratch_pool, scratch_pool)); @@ -12692,6 +12630,7 @@ ctx, scratch_pool, scratch_pool)); SVN_ERR(svn_client__ra_session_release(ctx, target_ra_session)); + SVN_ERR(svn_client__ra_session_release(ctx, right_ra_session)); } source.loc1 = merge->base; @@ -12698,16 +12637,9 @@ source.loc2 = merge->right; source.ancestral = ! merge->is_reintegrate_like; - SVN_ERR(svn_client_open_ra_session2(&base_ra_session, - merge->base->url, - target->abspath, ctx, scratch_pool, - scratch_pool)); - err = merge_cousins_and_supplement_mergeinfo(conflict_report, &use_sleep, target, - base_ra_session, - right_ra_session, &source, merge->yca, TRUE /* same_repos */, depth, @@ -12717,11 +12649,6 @@ merge_options, ctx, result_pool, scratch_pool); - if (!err) - { - SVN_ERR(svn_client__ra_session_release(ctx, base_ra_session)); - SVN_ERR(svn_client__ra_session_release(ctx, right_ra_session)); - } } else /* ! merge->is_reintegrate_like */ { @@ -12735,28 +12662,22 @@ find the base for each sutree, and then here use the oldest base among all subtrees. */ apr_array_header_t *merge_sources; - svn_ra_session_t *ra_session; /* Normalize our merge sources, do_merge() requires this. See the 'MERGEINFO MERGE SOURCE NORMALIZATION' global comment. */ - SVN_ERR(svn_client_open_ra_session2(&ra_session, merge->right->url, - target->abspath, ctx, scratch_pool, - scratch_pool)); SVN_ERR(normalize_merge_sources_internal( &merge_sources, merge->right, svn_rangelist__initialize(merge->yca->rev, merge->right->rev, TRUE, scratch_pool), - ra_session, ctx, scratch_pool, scratch_pool)); + NULL, ctx, scratch_pool, scratch_pool)); err = do_merge(NULL, NULL, conflict_report, &use_sleep, - merge_sources, target, ra_session, + merge_sources, target, TRUE /*related*/, TRUE /*same_repos*/, FALSE /*ignore_mergeinfo*/, diff_ignore_ancestry, force_delete, dry_run, record_only, NULL, FALSE, FALSE, depth, merge_options, ctx, result_pool, scratch_pool); - if (!err) - SVN_ERR(svn_client__ra_session_release(ctx, ra_session)); } if (use_sleep)