summaryrefslogtreecommitdiffstats
path: root/subversion/libsvn_client
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/libsvn_client')
-rw-r--r--subversion/libsvn_client/commit.c17
-rw-r--r--subversion/libsvn_client/merge.c29
-rw-r--r--subversion/libsvn_client/mergeinfo.c187
-rw-r--r--subversion/libsvn_client/update.c18
4 files changed, 178 insertions, 73 deletions
diff --git a/subversion/libsvn_client/commit.c b/subversion/libsvn_client/commit.c
index 6b30885..07fdce1 100644
--- a/subversion/libsvn_client/commit.c
+++ b/subversion/libsvn_client/commit.c
@@ -999,9 +999,22 @@ svn_client_commit6(const apr_array_header_t *targets,
}
cleanup:
- /* Sleep to ensure timestamp integrity. */
+ /* Sleep to ensure timestamp integrity. BASE_ABSPATH may have been
+ removed by the commit or it may the common ancestor of multiple
+ working copies. */
if (timestamp_sleep)
- svn_io_sleep_for_timestamps(base_abspath, pool);
+ {
+ const char *wcroot_abspath;
+ svn_error_t *err = svn_wc__get_wcroot(&wcroot_abspath, ctx->wc_ctx,
+ base_abspath, pool, pool);
+ if (err)
+ {
+ svn_error_clear(err);
+ wcroot_abspath = NULL;
+ }
+
+ svn_io_sleep_for_timestamps(wcroot_abspath, pool);
+ }
/* Abort the commit if it is still in progress. */
svn_pool_clear(iterpool); /* Close open handles before aborting */
diff --git a/subversion/libsvn_client/merge.c b/subversion/libsvn_client/merge.c
index 17a5d23..cb07f83 100644
--- a/subversion/libsvn_client/merge.c
+++ b/subversion/libsvn_client/merge.c
@@ -10716,7 +10716,7 @@ log_find_operative_revs(void *baton,
suffix = svn_relpath_skip_ancestor(subtree_missing_this_rev,
source_rel_path);
- if (suffix)
+ if (suffix && suffix[0] != '\0')
{
missing_path = apr_pstrmemdup(pool, path,
strlen(path) - strlen(suffix) - 1);
@@ -12051,11 +12051,15 @@ short_circuit_mergeinfo_log(svn_mergeinfo_catalog_t *target_mergeinfo_cat,
svn_log_entry_receiver_t receiver,
svn_revnum_t *revision,
svn_client_ctx_t *ctx,
+ svn_ra_session_t *ra_session,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
apr_array_header_t *revprops;
svn_error_t *err;
+ const char *session_url;
+
+ SVN_ERR(svn_ra_get_session_url(ra_session, &session_url, scratch_pool));
revprops = apr_array_make(scratch_pool, 0, sizeof(const char *));
err = svn_client__mergeinfo_log(finding_merged,
@@ -12068,8 +12072,12 @@ short_circuit_mergeinfo_log(svn_mergeinfo_catalog_t *target_mergeinfo_cat,
source_end_revision,
receiver, revision,
TRUE, svn_depth_infinity,
- revprops, ctx, result_pool,
- scratch_pool);
+ revprops, ctx, ra_session,
+ result_pool, scratch_pool);
+
+ err = svn_error_compose_create(
+ err,
+ svn_ra_reparent(ra_session, session_url, scratch_pool));
if (err)
{
@@ -12133,6 +12141,7 @@ find_last_merged_location(svn_client__pathrev_t **base_p,
const branch_history_t *source_branch,
svn_client__pathrev_t *target,
svn_client_ctx_t *ctx,
+ svn_ra_session_t *ra_session,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@@ -12160,7 +12169,8 @@ find_last_merged_location(svn_client__pathrev_t **base_p,
&source_end_rev, &source_start_rev,
operative_rev_receiver,
&youngest_merged_rev,
- ctx, result_pool, scratch_pool));
+ ctx, ra_session,
+ result_pool, scratch_pool));
if (!SVN_IS_VALID_REVNUM(youngest_merged_rev))
{
@@ -12195,7 +12205,8 @@ find_last_merged_location(svn_client__pathrev_t **base_p,
&source_start_rev, &source_end_rev,
operative_rev_receiver,
&oldest_eligible_rev,
- ctx, scratch_pool, scratch_pool));
+ ctx, ra_session,
+ scratch_pool, scratch_pool));
/* If there are revisions eligible for merging, use the oldest one
to calculate the base. Otherwise there are no operative revisions
@@ -12249,7 +12260,9 @@ find_base_on_source(svn_client__pathrev_t **base_p,
s_t->yca,
&s_t->source_branch,
s_t->target_branch.tip,
- ctx, result_pool, scratch_pool));
+ ctx,
+ s_t->source_ra_session,
+ result_pool, scratch_pool));
return SVN_NO_ERROR;
}
@@ -12282,7 +12295,9 @@ find_base_on_target(svn_client__pathrev_t **base_p,
s_t->yca,
&s_t->target_branch,
s_t->source,
- ctx, result_pool, scratch_pool));
+ ctx,
+ s_t->target_ra_session,
+ result_pool, scratch_pool));
return SVN_NO_ERROR;
}
diff --git a/subversion/libsvn_client/mergeinfo.c b/subversion/libsvn_client/mergeinfo.c
index 6dd3434..2d277f5 100644
--- a/subversion/libsvn_client/mergeinfo.c
+++ b/subversion/libsvn_client/mergeinfo.c
@@ -1021,6 +1021,11 @@ svn_client__elide_mergeinfo(const char *target_abspath,
Set *REPOS_ROOT to the root URL of the repository associated with
PATH_OR_URL.
+ If RA_SESSION is NOT NULL and PATH_OR_URL refers to a URL, RA_SESSION
+ (which must be of the repository containing PATH_OR_URL) will be used
+ instead of a temporary RA session. Caller is responsible for reparenting
+ the session if it wants to use it after the call.
+
Allocate *MERGEINFO_CATALOG and all its contents in RESULT_POOL. Use
SCRATCH_POOL for all temporary allocations.
@@ -1034,17 +1039,30 @@ get_mergeinfo(svn_mergeinfo_catalog_t *mergeinfo_catalog,
svn_boolean_t include_descendants,
svn_boolean_t ignore_invalid_mergeinfo,
svn_client_ctx_t *ctx,
+ svn_ra_session_t *ra_session,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- svn_ra_session_t *ra_session;
const char *local_abspath;
svn_boolean_t use_url = svn_path_is_url(path_or_url);
svn_client__pathrev_t *peg_loc;
- SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &peg_loc,
- path_or_url, NULL, peg_revision,
- peg_revision, ctx, scratch_pool));
+ if (ra_session && svn_path_is_url(path_or_url))
+ {
+ SVN_ERR(svn_ra_reparent(ra_session, path_or_url, scratch_pool));
+ SVN_ERR(svn_client__resolve_rev_and_url(&peg_loc, ra_session,
+ path_or_url,
+ peg_revision,
+ peg_revision,
+ ctx, scratch_pool));
+ }
+ else
+ {
+ SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &peg_loc,
+ path_or_url, NULL,
+ peg_revision,
+ peg_revision, ctx, scratch_pool));
+ }
/* If PATH_OR_URL is as working copy path determine if we will need to
contact the repository for the requested PEG_REVISION. */
@@ -1064,10 +1082,6 @@ get_mergeinfo(svn_mergeinfo_catalog_t *mergeinfo_catalog,
}
}
- /* Check server Merge Tracking capability. */
- SVN_ERR(svn_ra__assert_mergeinfo_capable_server(ra_session, path_or_url,
- scratch_pool));
-
SVN_ERR(svn_ra_get_repos_root2(ra_session, repos_root, result_pool));
if (use_url)
@@ -1391,17 +1405,21 @@ filter_log_entry_with_rangelist(void *baton,
obviously back. If it was added or replaced it's still around
possibly it was replaced one or more times, but it's back now.
Regardless, LOG_ENTRY->REVISION is *not* an eligible revision! */
- if (ancestor_is_self /* Explicit mergeinfo on TARGET_PATH_AFFECTED */
+ if (nearest_ancestor_mergeinfo &&
+ ancestor_is_self /* Explicit mergeinfo on TARGET_PATH_AFFECTED */
&& (change->action != 'M'))
{
svn_rangelist_t *rangelist =
svn_hash_gets(nearest_ancestor_mergeinfo, path);
- svn_merge_range_t *youngest_range = APR_ARRAY_IDX(
- rangelist, rangelist->nelts - 1, svn_merge_range_t *);
+ if (rangelist)
+ {
+ svn_merge_range_t *youngest_range = APR_ARRAY_IDX(
+ rangelist, rangelist->nelts - 1, svn_merge_range_t *);
- if (youngest_range
- && (youngest_range->end > log_entry->revision))
- continue;
+ if (youngest_range
+ && (youngest_range->end > log_entry->revision))
+ continue;
+ }
}
if (nearest_ancestor_mergeinfo)
@@ -1496,33 +1514,22 @@ logs_for_mergeinfo_rangelist(const char *source_url,
svn_log_entry_receiver_t log_receiver,
void *log_receiver_baton,
svn_client_ctx_t *ctx,
+ svn_ra_session_t *ra_session,
apr_pool_t *scratch_pool)
{
- apr_array_header_t *target;
svn_merge_range_t *oldest_range, *youngest_range;
- apr_array_header_t *revision_ranges;
- svn_opt_revision_t oldest_rev, youngest_rev;
+ svn_revnum_t oldest_rev, youngest_rev;
struct filter_log_entry_baton_t fleb;
if (! rangelist->nelts)
return SVN_NO_ERROR;
- /* Sort the rangelist. */
- qsort(rangelist->elts, rangelist->nelts,
- rangelist->elt_size, svn_sort_compare_ranges);
-
- /* Build a single-member log target list using SOURCE_URL. */
- target = apr_array_make(scratch_pool, 1, sizeof(const char *));
- APR_ARRAY_PUSH(target, const char *) = source_url;
-
/* Calculate and construct the bounds of our log request. */
youngest_range = APR_ARRAY_IDX(rangelist, rangelist->nelts - 1,
svn_merge_range_t *);
- youngest_rev.kind = svn_opt_revision_number;
- youngest_rev.value.number = youngest_range->end;
+ youngest_rev = youngest_range->end;
oldest_range = APR_ARRAY_IDX(rangelist, 0, svn_merge_range_t *);
- oldest_rev.kind = svn_opt_revision_number;
- oldest_rev.value.number = oldest_range->start;
+ oldest_rev = oldest_range->start;
if (! target_mergeinfo_catalog)
target_mergeinfo_catalog = apr_hash_make(scratch_pool);
@@ -1547,19 +1554,29 @@ logs_for_mergeinfo_rangelist(const char *source_url,
fleb.log_receiver_baton = log_receiver_baton;
fleb.ctx = ctx;
- /* Drive the log. */
- revision_ranges = apr_array_make(scratch_pool, 1,
- sizeof(svn_opt_revision_range_t *));
- if (oldest_revs_first)
- APR_ARRAY_PUSH(revision_ranges, svn_opt_revision_range_t *)
- = svn_opt__revision_range_create(&oldest_rev, &youngest_rev, scratch_pool);
+ if (!ra_session)
+ SVN_ERR(svn_client__open_ra_session_internal(&ra_session, NULL, source_url,
+ NULL, NULL, FALSE, FALSE, ctx,
+ scratch_pool, scratch_pool));
else
- APR_ARRAY_PUSH(revision_ranges, svn_opt_revision_range_t *)
- = svn_opt__revision_range_create(&youngest_rev, &oldest_rev, scratch_pool);
- SVN_ERR(svn_client_log5(target, &youngest_rev, revision_ranges,
- 0, discover_changed_paths, FALSE, FALSE, revprops,
- filter_log_entry_with_rangelist, &fleb, ctx,
- scratch_pool));
+ SVN_ERR(svn_ra_reparent(ra_session, source_url, scratch_pool));
+
+ {
+ apr_array_header_t *target;
+ target = apr_array_make(scratch_pool, 1, sizeof(const char *));
+ APR_ARRAY_PUSH(target, const char *) = "";
+
+ SVN_ERR(svn_ra_get_log2(ra_session, target,
+ oldest_revs_first ? oldest_rev : youngest_rev,
+ oldest_revs_first ? youngest_rev : oldest_rev,
+ 0 /* limit */,
+ discover_changed_paths,
+ FALSE /* strict_node_history */,
+ FALSE /* include_merged_revisions */,
+ revprops,
+ filter_log_entry_with_rangelist, &fleb,
+ scratch_pool));
+ }
/* Check for cancellation. */
if (ctx->cancel_func)
@@ -1620,7 +1637,7 @@ svn_client_mergeinfo_get_merged(apr_hash_t **mergeinfo_p,
svn_mergeinfo_t mergeinfo;
SVN_ERR(get_mergeinfo(&mergeinfo_cat, &repos_root, path_or_url,
- peg_revision, FALSE, FALSE, ctx, pool, pool));
+ peg_revision, FALSE, FALSE, ctx, NULL, pool, pool));
if (mergeinfo_cat)
{
const char *repos_relpath;
@@ -1666,6 +1683,7 @@ svn_client__mergeinfo_log(svn_boolean_t finding_merged,
svn_depth_t depth,
const apr_array_header_t *revprops,
svn_client_ctx_t *ctx,
+ svn_ra_session_t *ra_session,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@@ -1719,6 +1737,9 @@ svn_client__mergeinfo_log(svn_boolean_t finding_merged,
subpool = svn_pool_create(scratch_pool);
+ if (ra_session)
+ target_session = ra_session;
+
/* We need the union of TARGET_PATH_OR_URL@TARGET_PEG_REVISION's mergeinfo
and MERGE_SOURCE_URL's history. It's not enough to do path
matching, because renames in the history of MERGE_SOURCE_URL
@@ -1735,11 +1756,27 @@ svn_client__mergeinfo_log(svn_boolean_t finding_merged,
it ourselves. We do need to get the repos_root
though, because get_mergeinfo() won't do it for us. */
target_mergeinfo_cat = *target_mergeinfo_catalog;
- SVN_ERR(svn_client__ra_session_from_path2(&target_session, &pathrev,
- target_path_or_url, NULL,
- target_peg_revision,
- target_peg_revision,
- ctx, subpool));
+
+ if (ra_session && svn_path_is_url(target_path_or_url))
+ {
+ SVN_ERR(svn_ra_reparent(ra_session, target_path_or_url, subpool));
+ SVN_ERR(svn_client__resolve_rev_and_url(&pathrev, ra_session,
+ target_path_or_url,
+ target_peg_revision,
+ target_peg_revision,
+ ctx, subpool));
+ target_session = ra_session;
+ }
+ else
+ {
+ SVN_ERR(svn_client__ra_session_from_path2(&target_session,
+ &pathrev,
+ target_path_or_url,
+ NULL,
+ target_peg_revision,
+ target_peg_revision,
+ ctx, subpool));
+ }
SVN_ERR(svn_ra_get_repos_root2(target_session, &repos_root,
scratch_pool));
}
@@ -1751,7 +1788,7 @@ svn_client__mergeinfo_log(svn_boolean_t finding_merged,
SVN_ERR(get_mergeinfo(target_mergeinfo_catalog, &repos_root,
target_path_or_url, target_peg_revision,
depth == svn_depth_infinity, TRUE,
- ctx, result_pool, scratch_pool));
+ ctx, ra_session, result_pool, scratch_pool));
target_mergeinfo_cat = *target_mergeinfo_catalog;
}
}
@@ -1763,7 +1800,7 @@ svn_client__mergeinfo_log(svn_boolean_t finding_merged,
SVN_ERR(get_mergeinfo(&target_mergeinfo_cat, &repos_root,
target_path_or_url, target_peg_revision,
depth == svn_depth_infinity, TRUE,
- ctx, scratch_pool, scratch_pool));
+ ctx, ra_session, scratch_pool, scratch_pool));
}
if (!svn_path_is_url(target_path_or_url))
@@ -1833,11 +1870,28 @@ svn_client__mergeinfo_log(svn_boolean_t finding_merged,
scratch_pool));
}
- SVN_ERR(svn_client__ra_session_from_path2(&source_session, &pathrev,
- source_path_or_url, NULL,
- source_peg_revision,
- source_peg_revision,
- ctx, subpool));
+ if (target_session
+ && svn_path_is_url(source_path_or_url)
+ && repos_root
+ && svn_uri_skip_ancestor(repos_root, source_path_or_url, subpool))
+ {
+ /* We can re-use the existing session */
+ source_session = target_session;
+ SVN_ERR(svn_ra_reparent(source_session, source_path_or_url, subpool));
+ SVN_ERR(svn_client__resolve_rev_and_url(&pathrev, source_session,
+ source_path_or_url,
+ source_peg_revision,
+ source_peg_revision,
+ ctx, subpool));
+ }
+ else
+ {
+ SVN_ERR(svn_client__ra_session_from_path2(&source_session, &pathrev,
+ source_path_or_url, NULL,
+ source_peg_revision,
+ source_peg_revision,
+ ctx, subpool));
+ }
SVN_ERR(svn_client__get_revision_number(&start_rev, &youngest_rev,
ctx->wc_ctx, source_path_or_url,
source_session,
@@ -1856,9 +1910,6 @@ svn_client__mergeinfo_log(svn_boolean_t finding_merged,
scratch_pool));
if (start_rev > end_rev)
oldest_revs_first = FALSE;
-
- /* Close the source and target sessions. */
- svn_pool_destroy(subpool);
}
/* Separate the explicit or inherited mergeinfo on TARGET_PATH_OR_URL,
@@ -2115,7 +2166,10 @@ svn_client__mergeinfo_log(svn_boolean_t finding_merged,
log_target = svn_path_url_add_component2(repos_root, log_target + 1,
scratch_pool);
- SVN_ERR(logs_for_mergeinfo_rangelist(log_target, merge_source_fspaths,
+ {
+ svn_error_t *err;
+
+ err = logs_for_mergeinfo_rangelist(log_target, merge_source_fspaths,
finding_merged,
master_inheritable_rangelist,
oldest_revs_first,
@@ -2126,8 +2180,13 @@ svn_client__mergeinfo_log(svn_boolean_t finding_merged,
discover_changed_paths,
revprops,
log_receiver, log_receiver_baton,
- ctx, scratch_pool));
- return SVN_NO_ERROR;
+ ctx, target_session, scratch_pool);
+
+ /* Close the source and target sessions. */
+ svn_pool_destroy(subpool); /* For SVN_ERR_CEASE_INVOCATION */
+
+ return svn_error_trace(err);
+ }
}
svn_error_t *
@@ -2146,13 +2205,15 @@ svn_client_mergeinfo_log2(svn_boolean_t finding_merged,
svn_client_ctx_t *ctx,
apr_pool_t *scratch_pool)
{
- return svn_client__mergeinfo_log(finding_merged, target_path_or_url,
+ return svn_error_trace(
+ svn_client__mergeinfo_log(finding_merged, target_path_or_url,
target_peg_revision, NULL,
source_path_or_url, source_peg_revision,
source_start_revision, source_end_revision,
log_receiver, log_receiver_baton,
discover_changed_paths, depth, revprops,
- ctx, scratch_pool, scratch_pool);
+ ctx, NULL,
+ scratch_pool, scratch_pool));
}
svn_error_t *
@@ -2190,7 +2251,7 @@ svn_client_suggest_merge_sources(apr_array_header_t **suggestions,
/* ### TODO: Share ra_session batons to improve efficiency? */
SVN_ERR(get_mergeinfo(&mergeinfo_cat, &repos_root, path_or_url,
- peg_revision, FALSE, FALSE, ctx, pool, pool));
+ peg_revision, FALSE, FALSE, ctx, NULL, pool, pool));
if (mergeinfo_cat && apr_hash_count(mergeinfo_cat))
{
diff --git a/subversion/libsvn_client/update.c b/subversion/libsvn_client/update.c
index 21f33ec..fe3f86d 100644
--- a/subversion/libsvn_client/update.c
+++ b/subversion/libsvn_client/update.c
@@ -701,7 +701,23 @@ svn_client_update4(apr_array_header_t **result_revs,
cleanup:
if (sleep)
- svn_io_sleep_for_timestamps((paths->nelts == 1) ? path : NULL, pool);
+ {
+ const char *wcroot_abspath;
+
+ if (paths->nelts == 1)
+ {
+ const char *abspath;
+
+ /* PATH iteslf may have been removed by the update. */
+ SVN_ERR(svn_dirent_get_absolute(&abspath, path, pool));
+ SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath, ctx->wc_ctx, abspath,
+ pool, pool));
+ }
+ else
+ wcroot_abspath = NULL;
+
+ svn_io_sleep_for_timestamps(wcroot_abspath, pool);
+ }
return svn_error_trace(err);
}
OpenPOWER on IntegriCloud