julianf...@apache.org wrote on Tue, Mar 20, 2012 at 17:15:23 -0000: > Modified: subversion/trunk/subversion/include/private/svn_client_private.h > URL: > http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_client_private.h?rev=1303016&r1=1303015&r2=1303016&view=diff > ============================================================================== > --- subversion/trunk/subversion/include/private/svn_client_private.h > (original) > +++ subversion/trunk/subversion/include/private/svn_client_private.h Tue Mar > 20 17:15:22 2012 > @@ -100,6 +100,51 @@ > +svn_error_t * > +svn_client__find_symmetric_merge(svn_client__symmetric_merge_t **merge, > + const char *source_path_or_url, > + const svn_opt_revision_t *source_revision, > + const char *target_wcpath, > + svn_boolean_t allow_mixed_rev, > + svn_client_ctx_t *ctx, > + apr_pool_t *result_pool, > + apr_pool_t *scratch_pool); > + > +/* Perform a symmetric merge. > + * > + * Merge according to MERGE into the WC at TARGET_WCPATH. > + */ > +svn_error_t * > +svn_client__do_symmetric_merge(const svn_client__symmetric_merge_t *merge, > + const char *target_wcpath, > + svn_depth_t depth, > + svn_boolean_t ignore_ancestry,
What does IGNORE_ANCESTRY mean in the context of symmetric merge? In particular, is it meaningful for the second merge in a 'sync A->B, sync A->B' scenario? > + svn_boolean_t force, > + svn_boolean_t record_only, > + svn_boolean_t dry_run, > + const apr_array_header_t *merge_options, > + svn_client_ctx_t *ctx, > + apr_pool_t *scratch_pool); > + > +#endif /* SVN_WITH_SYMMETRIC_MERGE */ > + > #ifdef __cplusplus > } > #endif /* __cplusplus */ > > Modified: subversion/trunk/subversion/libsvn_client/merge.c > URL: > http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/merge.c?rev=1303016&r1=1303015&r2=1303016&view=diff > ============================================================================== > --- subversion/trunk/subversion/libsvn_client/merge.c (original) > +++ subversion/trunk/subversion/libsvn_client/merge.c Tue Mar 20 17:15:22 2012 > @@ -10864,3 +10864,409 @@ > +/* */ > +static svn_error_t * > +find_symmetric_merge(repo_location_t **yca_p, > + repo_location_t **base_p, > + repo_location_t **mid_p, > + source_and_target_t *s_t, > + svn_client_ctx_t *ctx, > + apr_pool_t *result_pool, > + apr_pool_t *scratch_pool) > +{ > + repo_location_t *yca, *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; > + > + /* Find the latest revision of A synced to B and the latest > + * revision of B synced to A. > + * > + * base_on_source = youngest_complete_synced_point(source, target) > + * base_on_target = youngest_complete_synced_point(target, source) > + */ > + SVN_ERR(find_base_on_source(&base_on_source, s_t, > + ctx, scratch_pool, scratch_pool)); > + SVN_ERR(find_base_on_target(&base_on_target, &mid, s_t, > + ctx, scratch_pool, scratch_pool)); > + > + if (base_on_source) > + SVN_DBG(("base on source: %s@%ld\n", base_on_source->url, > base_on_source->rev)); > + if (base_on_target) > + SVN_DBG(("base on target: %s@%ld\n", base_on_target->url, > base_on_target->rev)); > + > + /* Choose a base. */ > + if (base_on_source > + && (! base_on_target || (base_on_source->rev > base_on_target->rev))) > + { The last part of this condition seems arbitrary: in the criss-cross scenario, the order in which the 'criss' and the 'cross' are committed shouldn't affect the base the algorithm chooses. > + *base_p = base_on_source; > + *mid_p = NULL; > + } > + else if (base_on_target) > + { > + *base_p = base_on_target; > + *mid_p = mid; > + } > + else > + { > + /* No previous merge was found, so this is the simple case where > + * 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; > + *mid_p = NULL; > + } > + > + return SVN_NO_ERROR; > +}