On Wed, Jan 18, 2012 at 8:45 AM, Julian Foad <julianf...@btopenworld.com> wrote:
> Hi Paul.
>
> Paul Burba wrote:
>
>> Julian Foad wrote:
>>> I (Julian Foad) wrote:
>> I think I understand now.  Your patch works fine when the only cyclic
>> merges are done via reintegrate (i.e. r24).
>
> [...]
>
>> I thought you were going to tackle more complex reflective merge
>> cases, such as this example:
>
>
> Yes, exactly!
>
>> A@1---r4---r5---r6---r7----------------r11----------->
>>  |\                                     ^          |
>>  | \                                    |          |
>>  |  \                              reintegrate     |
>>  |   V                                  |          |
>>  |   A_COPY_2-----------------r9---r10---          |
>>  |                            ^                sync merge
>>  |                           /                     |
>>  |                  cherry-pick merge of r8        |
>>  V                         /                       V
>>  A_COPY-------------------r8------------------------->
>
>
> Thanks for this good example of a more complex use case.  I've included it in 
> <http://wiki.apache.org/subversion/KeepingReintegratedBranchAlive> and 
> written up a discussion of the options there.
>
> What do we want in this case?  The options are basically:
>
>   (1) try to merge (as we do now), despite knowing it will conflict;
>   (2) skip r11 (not usually good in this kind of case);
>   (3) figure out what really "should" be merged and merge it;
>
>   (4) stop and tell the user what's up.
>
> I'm not aiming for (3) because I think that's much more complex than it 
> sounds.

Actually it *sounds* pretty complex ;-)  Seriously, if you solve #3
then I think you will also have solved issue #2897.

> With any other option, I believe it is essential to tell the user why 
> Subversion can't simply include or exclude r11, with details.
>
>
> Any of these options could be best for the user.  It is not at all the case 
> that (1) is best.  It depends how big the changes in r8/r9 are compared with 
> those in r10, and how much they conflict, and how the user prefers to resolve 
> the situation.
>
> I'm aiming for:
>
>   * Detect whether we have the simple case (the rev is effectively already 
> merged) or the complex case (partially merged).
>   * Simple case: Do The Right Thing which is skip it but record it as merged.
>
>   * Complex case: let user choose (1) or (2) or (4), in advance or 
> interactively.

+1

>   * Complex case: always issue a diagnostic message that clearly explains 
> what's up.
>
>> As your patch stands, the above use-case causes some serious problems.
>
> Sure, my last patch only detects a Go/No-go and chooses No-go because that's 
> sufficient for the simple use case.  But now we can get to the interesting 
> bit: how to detect the "Partially merged" situation.

Sorry, I was initially unclear on how far you intended to take this.
I'm with you now.

> The principle that we are grasping as humans but haven't yet codified 
> formally is that we want the merge to know whether all the "original changes" 
> have been made already (directly or via any series of merges) in the target 
> branch.
>
> I describe the idea of "logical changes" in 
> <http://wiki.apache.org/subversion/MergeTrackingIdeas>.

Most of the ideas there make sense, though I'm a bit foggy as to how
the mergeinfo format will change and how we'll migrate existing
repositories.

> Briefly:  When we make a new change in A@10 and merge that into B as B@12, we 
> get two physical changes in the repository.  B@12 is a physical manifestation 
> of the same logical change as A@10, but it looks a bit different because it 
> is adjusted (automatically and/or manually) to fit the physical form and 
> logical requirements of branch B.  I say that there is one "logical change" 
> there, which we refer to by the co-ordinates where it originated, A@10.
>
> Whenever we ask Subversion to track merges, although the current 
> implementation just tracks physical changes from the immediate source branch, 
> I believe that what we (as users) really expect is for it to track logical 
> changes.  The "partial merge" use case above is an example of where we have 
> to make a distinction and explicitly ask whether all the required logical 
> changes are present.
>
> ALGORITHM
>
> Purpose: To determine whether all logical changes comprising a given physical 
> change (e.g. A@11) are already present in the target.
>
> Step 1: build a tree of merged revisions (i.e. mergeinfo changes), recursing 
> until we reach "logical changes".

I know you are still early in the proof-of-concept phase, but have you
given much thought to performance?  In particular I'm thinking of how
mergeinfo_graph_populate recursively scans the history of reflective
merges to build the mergeinfo graph.  In doing so it ultimately calls
svn_client__get_repos_mergeinfo twice for each revision (operative or
not) described in the reflected mergeinfo.  That could get slow in a
hurry.

> Step 2: traverse the tree of merged revisions, seeing whether all of the 
> logical changes that comprise A@11 are recorded in the mergeinfo of the 
> target (A_COPY).
>
> While doing this we need to ignore no-op revisions because we don't care 
> whether they are recorded in the target or not.
>
> I've written code for step 1  (the attached 'merge-avoid-reflective-5.patch' 
> is my current state) and am starting on step 2.

I look forward to see what you come up with for step 2.

Paul

>> (The attached patch is an update of yours with a new
>
>> merge_reintegrate.py test #20, which demonstrates the above use case)
>
> Thanks; that's very useful.
>
>
> - Julian

Reply via email to