[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: svn commit: r1303016 - in /subversion/trunk/subversion: include/private/svn_client_private.h libsvn_client/merge.c svn/cl.h svn/main.c svn/merge-cmd.c

From: Julian Foad <julianfoad_at_btopenworld.com>
Date: Thu, 22 Mar 2012 08:54:09 +0000 (GMT)

Hi Daniel.á Thanks for reviewing...

(Dropping commits@ from the CC.)

Daniel Shahaf wrote:
> julianfoad_at_apache.org wrote:
>> 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
>> +++ subversion/trunk/subversion/include/private/svn_client_private.h
>> +/* 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?

Clearly I need to fill in the doc strings.

IGNORE_ANCESTRY doesn't affect the high level operation of the merge, it only affects how file diffs are shown -- even if the source and
target file are not historically related it will show a diff rather than
 a delete and an add of the file -- or something similar to that.á From svn_client_merge4():

á* Use @a ignore_ancestry to control whether or not items being
á* diffed will be checked for relatedness first.á Unrelated items
á* are typically transmitted to the editor as a deletion of one thing
á* and the addition of another, but if this flag is TRUE, unrelated
á* items will be diffed as if they were related.

>> +á á á á á á á á á á á á á á á 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);

>> 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
>> +++ subversion/trunk/subversion/libsvn_client/merge.c
>> @@ -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));
[...]
>> +á /* 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.

Yes, that's true for a criss-cross.á However, it's not a problem for normal cases; criss-cross is a rare case.á As I wrote in the criss-cross merge section of <http://wiki.apache.org/subversion/SymmetricMerge>, in that case we probably should consider the relative ages of A1, B1, A3, B3, and A2, but I haven't yet thought about what's the best way to compare them.

>> +á á á *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;
>> +}

Thanks.

- Julian
Received on 2012-03-22 09:54:47 CET

This is an archived mail posted to the Subversion Dev mailing list.