Author: svn-role
Date: Fri Jun 21 04:00:38 2013
New Revision: 1495279
URL: http://svn.apache.org/r1495279
Log:
Merge r1493475 from trunk:
* r1493475
Improve 'svn merge' performance over WAN: Use already fetched
history-as-mergeinfo data to find youngest common ancestor in automatic
merge.
Justification:
No reason to create an RA session or perform RA calls if the information
is already in memory.
Votes:
+1: rhuijben, ivan, stefan2
Modified:
subversion/branches/1.8.x/ (props changed)
subversion/branches/1.8.x/STATUS
subversion/branches/1.8.x/subversion/libsvn_client/client.h
subversion/branches/1.8.x/subversion/libsvn_client/merge.c
subversion/branches/1.8.x/subversion/libsvn_client/ra.c
Propchange: subversion/branches/1.8.x/
------------------------------------------------------------------------------
Merged /subversion/trunk:r1493475
Modified: subversion/branches/1.8.x/STATUS
URL:
http://svn.apache.org/viewvc/subversion/branches/1.8.x/STATUS?rev=1495279&r1=1495278&r2=1495279&view=diff
==============================================================================
--- subversion/branches/1.8.x/STATUS (original)
+++ subversion/branches/1.8.x/STATUS Fri Jun 21 04:00:38 2013
@@ -197,16 +197,6 @@ Veto-blocked changes:
Approved changes:
=================
- * r1493475
- Improve 'svn merge' performance over WAN: Use already fetched
- history-as-mergeinfo data to find youngest common ancestor in automatic
- merge.
- Justification:
- No reason to create an RA session or perform RA calls if the information
- is already in memory.
- Votes:
- +1: rhuijben, ivan, stefan2
-
* r1494342
C tests: support --compatible-version=1.8.
Justification:
Modified: subversion/branches/1.8.x/subversion/libsvn_client/client.h
URL:
http://svn.apache.org/viewvc/subversion/branches/1.8.x/subversion/libsvn_client/client.h?rev=1495279&r1=1495278&r2=1495279&view=diff
==============================================================================
--- subversion/branches/1.8.x/subversion/libsvn_client/client.h (original)
+++ subversion/branches/1.8.x/subversion/libsvn_client/client.h Fri Jun 21
04:00:38 2013
@@ -20,7 +20,8 @@
* under the License.
* ====================================================================
*/
-
+
+
#ifndef SVN_LIBSVN_CLIENT_H
#define SVN_LIBSVN_CLIENT_H
@@ -208,6 +209,9 @@ svn_client__repos_location_segments(apr_
Use the authentication baton cached in CTX to authenticate against
the repository. Use POOL for all allocations.
+ See also svn_client__calc_youngest_common_ancestor() to find youngest
+ common ancestor for already fetched history-as-mergeinfo information.
+
See also svn_client__youngest_common_ancestor().
*/
svn_error_t *
@@ -219,6 +223,34 @@ svn_client__get_youngest_common_ancestor
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+/* Find the common ancestor of two locations in a repository using already
+ fetched history-as-mergeinfo information.
+
+ Ancestry is determined by the 'copy-from' relationship and the normal
+ successor relationship.
+
+ Set *ANCESTOR_P to the location of the youngest common ancestor of
+ LOC1 and LOC2. If the locations have no common ancestor (including if
+ they don't have the same repository root URL), set *ANCESTOR_P to NULL.
+
+ HISTORY1, HAS_REV_ZERO_HISTORY1, HISTORY2, HAS_REV_ZERO_HISTORY2 are
+ history-as-mergeinfo information as returned by
+ svn_client__get_history_as_mergeinfo() for LOC1 and LOC2 respectively.
+
+ See also svn_client__get_youngest_common_ancestor().
+
+*/
+svn_error_t *
+svn_client__calc_youngest_common_ancestor(svn_client__pathrev_t **ancestor_p,
+ const svn_client__pathrev_t *loc1,
+ apr_hash_t *history1,
+ svn_boolean_t has_rev_zero_history1,
+ const svn_client__pathrev_t *loc2,
+ apr_hash_t *history2,
+ svn_boolean_t has_rev_zero_history2,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
/* Ensure that RA_SESSION's session URL matches SESSION_URL,
reparenting that session if necessary.
Store the previous session URL in *OLD_SESSION_URL (so that if the
@@ -247,7 +279,8 @@ svn_client__ensure_ra_session_url(const
apr_pool_t *pool);
/* ---------------------------------------------------------------- */
-
+
+
/*** RA callbacks ***/
@@ -329,7 +362,8 @@ svn_client__ra_make_cb_baton(svn_wc_cont
apr_pool_t *result_pool);
/* ---------------------------------------------------------------- */
-
+
+
/*** Add/delete ***/
/* If AUTOPROPS is not null: Then read automatic properties matching PATH
@@ -442,7 +476,8 @@ svn_client__make_local_parents(const cha
apr_pool_t *pool);
/* ---------------------------------------------------------------- */
-
+
+
/*** Checkout, update and switch ***/
/* Update a working copy LOCAL_ABSPATH to REVISION, and (if not NULL) set
@@ -581,7 +616,8 @@ svn_client__switch_internal(svn_revnum_t
apr_pool_t *pool);
/* ---------------------------------------------------------------- */
-
+
+
/*** Inheritable Properties ***/
/* Convert any svn_prop_inherited_item_t elements in INHERITED_PROPS which
@@ -626,7 +662,8 @@ svn_client__get_inheritable_props(apr_ha
apr_pool_t *scratch_pool);
/* ---------------------------------------------------------------- */
-
+
+
/*** Editor for repository diff ***/
/* Create an editor for a pure repository comparison, i.e. comparing one
@@ -666,7 +703,8 @@ svn_client__get_diff_editor2(const svn_d
apr_pool_t *result_pool);
/* ---------------------------------------------------------------- */
-
+
+
/*** Editor for diff summary ***/
/* Set *CALLBACKS and *CALLBACK_BATON to a set of diff callbacks that will
@@ -689,7 +727,8 @@ svn_client__get_diff_summarize_callbacks
apr_pool_t *pool);
/* ---------------------------------------------------------------- */
-
+
+
/*** Copy Stuff ***/
/* This structure is used to associate a specific copy or move SRC with a
@@ -730,7 +769,8 @@ typedef struct svn_client__copy_pair_t
} svn_client__copy_pair_t;
/* ---------------------------------------------------------------- */
-
+
+
/*** Commit Stuff ***/
/* WARNING: This is all new, untested, un-peer-reviewed conceptual
@@ -944,7 +984,8 @@ svn_client__do_commit(const char *base_u
apr_pool_t *scratch_pool);
-
+
+
/*** Externals (Modules) ***/
/* Handle changes to the svn:externals property described by EXTERNALS_NEW,
@@ -1116,7 +1157,8 @@ svn_client__resolve_conflicts(svn_boolea
svn_client_ctx_t *ctx,
apr_pool_t *scratch_pool);
-
+
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
Modified: subversion/branches/1.8.x/subversion/libsvn_client/merge.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.8.x/subversion/libsvn_client/merge.c?rev=1495279&r1=1495278&r2=1495279&view=diff
==============================================================================
--- subversion/branches/1.8.x/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/1.8.x/subversion/libsvn_client/merge.c Fri Jun 21
04:00:38 2013
@@ -12298,9 +12298,13 @@ find_automatic_merge(svn_client__pathrev
&s_t->target->loc, SVN_INVALID_REVNUM, SVN_INVALID_REVNUM,
s_t->target_ra_session, ctx, scratch_pool));
- SVN_ERR(svn_client__get_youngest_common_ancestor(
- &s_t->yca, s_t->source, &s_t->target->loc, s_t->source_ra_session,
- ctx, result_pool, result_pool));
+ SVN_ERR(svn_client__calc_youngest_common_ancestor(
+ &s_t->yca, s_t->source, s_t->source_branch.history,
+ s_t->source_branch.has_r0_history,
+ &s_t->target->loc, s_t->target_branch.history,
+ s_t->target_branch.has_r0_history,
+ result_pool, scratch_pool));
+
if (! s_t->yca)
return svn_error_createf(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
_("'%s@%ld' must be ancestrally related to "
Modified: subversion/branches/1.8.x/subversion/libsvn_client/ra.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.8.x/subversion/libsvn_client/ra.c?rev=1495279&r1=1495278&r2=1495279&view=diff
==============================================================================
--- subversion/branches/1.8.x/subversion/libsvn_client/ra.c (original)
+++ subversion/branches/1.8.x/subversion/libsvn_client/ra.c Fri Jun 21 04:00:38
2013
@@ -862,23 +862,20 @@ svn_client__repos_locations(const char *
return SVN_NO_ERROR;
}
-
svn_error_t *
-svn_client__get_youngest_common_ancestor(svn_client__pathrev_t **ancestor_p,
- const svn_client__pathrev_t *loc1,
- const svn_client__pathrev_t *loc2,
- svn_ra_session_t *session,
- svn_client_ctx_t *ctx,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+svn_client__calc_youngest_common_ancestor(svn_client__pathrev_t **ancestor_p,
+ const svn_client__pathrev_t *loc1,
+ apr_hash_t *history1,
+ svn_boolean_t has_rev_zero_history1,
+ const svn_client__pathrev_t *loc2,
+ apr_hash_t *history2,
+ svn_boolean_t has_rev_zero_history2,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
- apr_pool_t *sesspool = NULL;
- apr_hash_t *history1, *history2;
apr_hash_index_t *hi;
svn_revnum_t yc_revision = SVN_INVALID_REVNUM;
const char *yc_relpath = NULL;
- svn_boolean_t has_rev_zero_history1;
- svn_boolean_t has_rev_zero_history2;
if (strcmp(loc1->repos_root_url, loc2->repos_root_url) != 0)
{
@@ -886,32 +883,6 @@ svn_client__get_youngest_common_ancestor
return SVN_NO_ERROR;
}
- /* Open an RA session for the two locations. */
- if (session == NULL)
- {
- sesspool = svn_pool_create(scratch_pool);
- SVN_ERR(svn_client_open_ra_session2(&session, loc1->url, NULL, ctx,
- sesspool, sesspool));
- }
-
- /* We're going to cheat and use history-as-mergeinfo because it
- saves us a bunch of annoying custom data comparisons and such. */
- SVN_ERR(svn_client__get_history_as_mergeinfo(&history1,
- &has_rev_zero_history1,
- loc1,
- SVN_INVALID_REVNUM,
- SVN_INVALID_REVNUM,
- session, ctx, scratch_pool));
- SVN_ERR(svn_client__get_history_as_mergeinfo(&history2,
- &has_rev_zero_history2,
- loc2,
- SVN_INVALID_REVNUM,
- SVN_INVALID_REVNUM,
- session, ctx, scratch_pool));
- /* Close the ra session if we opened one. */
- if (sesspool)
- svn_pool_destroy(sesspool);
-
/* Loop through the first location's history, check for overlapping
paths and ranges in the second location's history, and
remembering the youngest matching location. */
@@ -965,6 +936,63 @@ svn_client__get_youngest_common_ancestor
}
svn_error_t *
+svn_client__get_youngest_common_ancestor(svn_client__pathrev_t **ancestor_p,
+ const svn_client__pathrev_t *loc1,
+ const svn_client__pathrev_t *loc2,
+ svn_ra_session_t *session,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ apr_pool_t *sesspool = NULL;
+ apr_hash_t *history1, *history2;
+ svn_boolean_t has_rev_zero_history1;
+ svn_boolean_t has_rev_zero_history2;
+
+ if (strcmp(loc1->repos_root_url, loc2->repos_root_url) != 0)
+ {
+ *ancestor_p = NULL;
+ return SVN_NO_ERROR;
+ }
+
+ /* Open an RA session for the two locations. */
+ if (session == NULL)
+ {
+ sesspool = svn_pool_create(scratch_pool);
+ SVN_ERR(svn_client_open_ra_session2(&session, loc1->url, NULL, ctx,
+ sesspool, sesspool));
+ }
+
+ /* We're going to cheat and use history-as-mergeinfo because it
+ saves us a bunch of annoying custom data comparisons and such. */
+ SVN_ERR(svn_client__get_history_as_mergeinfo(&history1,
+ &has_rev_zero_history1,
+ loc1,
+ SVN_INVALID_REVNUM,
+ SVN_INVALID_REVNUM,
+ session, ctx, scratch_pool));
+ SVN_ERR(svn_client__get_history_as_mergeinfo(&history2,
+ &has_rev_zero_history2,
+ loc2,
+ SVN_INVALID_REVNUM,
+ SVN_INVALID_REVNUM,
+ session, ctx, scratch_pool));
+ /* Close the ra session if we opened one. */
+ if (sesspool)
+ svn_pool_destroy(sesspool);
+
+ SVN_ERR(svn_client__calc_youngest_common_ancestor(ancestor_p,
+ loc1, history1,
+ has_rev_zero_history1,
+ loc2, history2,
+ has_rev_zero_history2,
+ result_pool,
+ scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
svn_client__youngest_common_ancestor(const char **ancestor_url,
svn_revnum_t *ancestor_rev,
const char *path_or_url1,