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

Re: issue-2897(reflective merge solution)

From: Kamesh Jayachandran <kamesh_at_collab.net>
Date: Fri, 08 Aug 2008 20:53:56 +0530

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

>>>> Available solution:
>>>> - ------------------------
>>> Solution 0: If you were to use Subversion 1.5's plain "svn
>>> merge /feature_branch /trunk" command, then Subversion would omit rY
>>> entirely, which is wrong because we need the conflict-resolution part of
>>> the change. Without that part, the merge would throw up those same (or
>>> similar) conflicts again, which the user would have to resolve again.
>> I believe you mean 'svn merge trunk_wc ^/feature_branch'
>
> No; the source comes first: 'svn merge ^/feature_branch trunk_wc'. I
> expect that's what you meant :-)
>

Yes source comes first, my typo :(.

>> This would *not* leave rY rather it would do a 'mad' merge
>> possibly(mostly) causing repeat merge problem.
>
> OK, Mark explained that my assumption there was wrong and the current
> merge algorithm attempts to apply rY in this case so as not to throw
> away all the "logical conflict" resolution work that may have been
> included, even though the "physical conflict" parts will conflict again.
>
>> Only instance it would not cause conflict is when there is enough
>> distance between 'trunk' and 'feature_branch' hunks.
>
> I don't understand this. Each hunk from rY that conflicted and was
> resolved when rY was created from rX is almost certain to conflict
> again, is it not? I don't see how there can be any distance between
> where this hunk existed in rX and where it is going to be applied to the
> trunk again. It will be applied to the same place where it already
> exists.

Yes you are correct, it will conflict again.

When I mentioned distance between changes (hunk am I correct in my usage
of word hunk?) of synced revs of trunk and /fb changes, I had the
'simple case in mind'(no conflict in sync up) as described below.

/trunk_at_1 has test.c with the following content.
line1
line2
line3
line4
line5
line6
line7

i.e if you copy /fb from /trunk_at_1 and commit at r2, consider the
following sequence of events.

r3 - Modify /trunk/test.c 'line3->line3-changed'
r4 - merge ^/trunk fb_wc
r5 - Modify /fb/test.c 'line4->line4-changed'
merge ^/fb trunk_wc
This should not give a conflict.

But gives a conflict as below with normal merge(no reintegrate) as of
1.5.1 like follows,

<snip>
line1
line2
<<<<<<< .working
line3-changed
line4
=======
line3-changed
line4-changed
>>>>>>> .merge-right.r5
line5
line6
line7
</snip>

Both 'reintegrate' and 'issue-2897' should work well here without conflict.

>
>
> [...]
>>> I know solution 2 can handle many more general cases, but, in the simple
>>> cases that "--reintegrate" is intended to handle, does your solution 2
>>> achieve the same result, or does it have a different concept of what is
>>> the right result?
>> It has no special cases, it just segregates a range of revisions to
>> merge as
>> [ordinary_range-1]...[reflective_rev-1]....[reflective-rev-2]...[ordinary_range-N]...
>>
>> Existing merge call backs are used for 'ordinary_ranges.
>>
>> Reflective call backs are used for 'reflective revs'.
>>
>> Purpose of Reflective call backs is 'extract non-reflective change and
>> merge the same'.
>
> That doesn't really answer my question. I'm looking for a high-level
> end-user's perspective on what the merging process achieves. I think the
> answer is that, in the simple cases that "--reintegrate" is intended to
> handle, Solution 2 has the same concept of what is the right result
> (i.e. that the trunk should end up looking exactly like the
> feature_branch does) but does not achieve that result without manual
> conflict resolution.

Yes.

>
> I wonder if it would be possible to make Solution 2 understand how to do
> the right thing in this simple case and avoid the need for conflict
> resolution. If we could do that, then it would win in every way.
>

I somehow think it should be possible in most of the cases, though I
don't have any algorithm in mind right now.

>>>
>>> * Each conflict resolution performed on /feature_branch will correctly
>>> be included in the re-integration.
>> Yes, after annoying with the user with the conflict again as mentioned
>> above.
>
> Oh, yes, I suppose so. I was thinking here that changes made by the user
> for conflict resolution would not conflict again when merged back, but I
> suppose that would be highly unusual.

As said above it should be possible to make conflict-resolutions of
/feature_branch non-conflicting on the trunk.

>
>>> * Each revision from /trunk that conflicted when merged
>>> into /feature_branch will wrongly be included in the re-integration,
>>> creating new conflicts.
>>>
>> Yes. May be we can be bit more smart here once we have this stuff working.
>
> I have tried drawing the merge scenario (case 3) on paper. There is a
> good way of representing merges, using tokens like "A" to represent a
> hunk of text and "Aa" or "A13" to represent a modified version of that
> hunk. This diagram shows one file starting in r9 containing three hunks
> of text "A", "B", and "C", and developing in trunk and on the branch:
>

Good.

> (You need a fixed-width typeface to display this nicely.)
>
> /trunk /feature_branch
> ____
> r9 |A
> |B
> |C
>
> svn copy ^/trunk ^/feature_branch
> ____ ____
> r10 |A |A
> |B |B
> |C |C
>

It could have been better if we have this /feature_branch r12 change at
r11 instead as r12 has commits in two branches(cross branch commit). No
problem though as technically this is possible.

> # Now various modifications are committed...
> ____ ____
> r12 |Aa << |A
> |B |B
> |C |Cc <<
> ____ ____
> r13 |Aa |A
> |B13 << |B
> |C |Cc
> ____ ____
> r17 |Aa |A
> |B13 |B
> |C17 << |Cc
> ____ ____
> r20 |A20 << |A
> |B13 |B
> |C17 |Cc
> ____ ____
> r29 |A20 |A
> |B29 << |B
> |C17 |Cc
>
> svn merge -c13,17,29 ^/trunk feature_branch_wc
> .... ____
> WC .... |A
> .... |B29 << auto-merged
> .... |<C17=C=Cc> << conflict
>

I believe you did more than one merge with subset of revisions from
above to merge. Or else it would conflict first at r17 which if you
choose to resolve later will cause r29 to conflict too.

> # Manually resolve.
> svn commit
> ____ ____
> r40 |A20 |A
> |B29 |B29 << auto-merged
> |C17 |C40 << manually resolved
>

However you did merge, final merge resolution is fine.

> svn merge ^/feature_branch trunk_wc
>
> # phase 1: a normal merge of r10:39.

Phase1 would do bulk merge so r10:40

> # (The only operative change is r12 of /feature_branch.)
>
No r40 also is operative.

     ____
> WC |A20
> |B29
> |<C17=C=Cc> << conflict
>

Above conflict is wrong, Conflict will be as follows,

     ____
 WC |A20
     |B29 <--Even this may give a conflict as changes(see the
explanations given above for 'simple case in mind') are close.
     |<C17=C=C40> << conflict

> # Oops: it conflicts already. (Is that what we expected?)

Yes.

> # Manually resolve.
> ____
> WC |A20
> |B29
> |C40
>
> # phase 2: a reflective-merge of r40
>

OLDER = /feature_branch/test.c_at_39(Though you have not mentioned test.c,
I presume it has some file like test.c)
                ____
> ( OLDER = |? )
> |?
> |?
>

OLDER = A
              B
              Cc

                 ____
> ( OLDER + |? )
> c13,17,29 = |?
> |?
>

OLDER_DASH = OLDER + c13,17,29
OLDER_DASH = A
               B29
               Cc

> ( MINE = |? )
> |?
> |?
> ____

I believe MINE is WC, YOURS is the actual name as per
subversion/libsvn_client/merge.c:merge_file_changed

YOURS = /feature_branch/test.c_at_40
YOURS = A
               B29
               C40

diff(OLDER_DASH, YOURS) =
- -Cc
+C40

And hence a conflict. As I told above we can be smart here.

Thanks

With regards
Kamesh Jayachandran
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFInGUM3WHvyO0YTCwRAlilAJ4z0avYICioACdVLUKyJlOsINQtRwCeIACl
Ypr5DNHEsZPxA9Ty7smmTTE=
=H75x
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe_at_subversion.tigris.org
For additional commands, e-mail: dev-help_at_subversion.tigris.org
Received on 2008-08-08 17:25:08 CEST

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

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.