Julian Foad wrote on Thu, Mar 22, 2012 at 08:54:09 +0000:
> Daniel Shahaf wrote:
> > julianf...@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.
> 

So, IGNORE_ANCESTRY controls how the tree delta is communicated.  Okay.
I was going by `svh help`, and the first mention there was effectively
"Ignore mergeinfo on the source when computing the merge" -- hence my
question.

> >>  +                               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.
> 

In other words, work in progress.  Fair enough.

Cheers,

daniel

> >>  +      *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

Reply via email to