You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@subversion.apache.org by Julian Foad <ju...@wandisco.com> on 2011/08/30 18:30:44 UTC

Support for reverse merges?

Philip and I were discussing the other day...

It seems that we don't consistently record a reverse merge.  Sometimes
we do, sometimes we don't.

  * Iff this branch's mergeinfo mentions the change that we're
reverse-merging, then we remove the mention from the mergeinfo and so
merge tracking can notice that the change is no longer recorded as being
there.  (And a further catch-up merge will bring in that original change
again.  For the purposes of this discussion, let's assume that that's
what the user expects.  We don't expect Subversion to remember that the
change is "permanently unwanted, and dealt with by rejecting it"; that
would be a different issue.)

  * If we reverse-merge a change that *isn't* recorded in the target
branch's mergeinfo, then we silently proceed without recording anything.

Am I understanding this correctly?  If so, then, we're thinking, that
inconsistency is where things start to go wrong when you next try to use
"automatic" merges between the branches.

I suppose this is a known limitation.  The book says you can undo an old
change by reverse-merging it, and it is briefly mentioned under the name
"rollback merge" in
<http://svn.apache.org/repos/asf/subversion/trunk/notes/merge-tracking/requirements.html#rollback-merge> and <http://svn.apache.org/repos/asf/subversion/trunk/notes/merge-tracking/func-spec.html#repeated-merge>, but it seems in practice that although you can perform a reverse-merge once it is not consistently tracked thereafter.  I don't know if we have anywhere a user-facing description of what merge scenarios are really supported by merge tracking.

What Philip and I were thinking is that we can improve the support for
reverse merges by always recording a reverse merge when it happens.  At
the moment, all changes in a branch's own line of history are implicitly
part of its mergeinfo, they are not stored explicitly, and therefore
there is no way to record that one of those changes is now missing.  But
if we stored the branch's own history explicitly then a reverse-merge
from its own-history could be recorded in just the same way as a
reverse-merge from any other branch.

Of course that's hand-wavey as regards implementation details, but does
that sound sane in broad terms?  For a start, the assumption that this
is a known deficiency?

- Julian



AW: Support for reverse merges?

Posted by Markus Schaber <m....@3s-software.com>.
Hi,

Von: Julian Foad [mailto:julian.foad@wandisco.com]
> 
> But then I realized that's totally unnecessary.  We don't need and
> shouldn't even attempt to record anything other than 'We have change C'
> or 'We don't have change C', for each change 'C'.  The only new thing that
> I think we want here is the ability to record 'We don't have change C'
> when C is in our own history; where currently we always assume that we DO
> have each such change.

If you do exactly this, you cross the road between a revision based and a changeset based VCS.

Maybe that is the future of svn, or maybe that is well beyond the scope of svn...

Best regards

Markus Schaber

___________________________
We software Automation.

3S-Smart Software Solutions GmbH
Markus Schaber | Developer
Memminger Str. 151 | 87439 Kempten | Germany | Tel. +49-831-54031-0 | Fax +49-831-54031-50

Email: m.schaber@3s-software.com | Web: http://www.3s-software.com 
CoDeSys internet forum: http://forum.3s-software.com
Download CoDeSys sample projects: http://www.3s-software.com/index.shtml?sample_projects

Managing Directors: Dipl.Inf. Dieter Hess, Dipl.Inf. Manfred Werner | Trade register: Kempten HRB 6186 | Tax ID No.: DE 167014915 

Re: Support for reverse merges?

Posted by Mark Phippard <ma...@gmail.com>.
On Wed, Aug 31, 2011 at 7:18 AM, Julian Foad <ju...@wandisco.com>wrote:

> On Tue, 2011-08-30 at 18:00 +0100, Philip Martin wrote:
> > Paul Burba <pt...@gmail.com> writes:
> >
> > > Could you provide some examples of when 'things start to go wrong when
> > > you next try to use "automatic" merges between the branches'?  Was
> > > there a particular use-case (or cases) you had in mind, or just a
> > > general sense that maybe this is/could be a problem?
> >
> > Here's one (shorter recipes are possible):
>
> Yes, this is exactly the sort of thing I mean.  What I expect in general
> is that if I have merged the same change into both branches, then an
> automatic (catch-up) merge would do nothing with that particular change.
> But here we reverse-merge the same change into both branches, and then a
> catch-up merge raises a conflict on that change.
>

Wouldn't that be entirely expected given the cyclic merge problem?  You made
a change in the source branch and committed it.  Instead of merging that
commit to the target branch as you would any other change, you made the same
change on the target branch.  But when you synch the target with the source
it is of course going to still try to merge this same change and create a
conflict.

In at least this specific scenario, I do not think the reverse merge is
relevant.  Suppose it is just a bug fix.  You make the fix in the source.
 You are supposed to merge that to the branch.  If you instead make the same
fix in the branch, as opposed to merging the fix, then it would be expected
that you get a conflict later when you synch merge.

As long as the merge algorithm is based on merging revisions, I do not see
how you change this.

-- 
Thanks

Mark Phippard
http://markphip.blogspot.com/

Re: Support for reverse merges?

Posted by Philip Martin <ph...@wandisco.com>.
Julian Foad <ju...@wandisco.com> writes:

> The only new thing
> that I think we want here is the ability to record 'We don't have change
> C' when C is in our own history; where currently we always assume that
> we DO have each such change.
>
>
>> #!/bin/sh -e
>> 
>> svn=svn ; svnadmin=svnadmin ; svnlook=svnlook ; svnmucc=svnmucc
>> repo=repo ; wc=wc ; url=file:///`pwd`/$repo
>> rm -rf $repo $wc
>> $svnadmin create $repo
>> 
>> # Create first branch
>> $svn mkdir -mm $url/A
>> $svn co $url/A $wc
>> 
>> # Create second branch from first
>> $svn cp -mm $url/A $url/X
>> $svn sw $url/X $wc
>> $svn merge ^/A $wc
>> $svn ci -mm $wc
>> 
>> # Change on second branch
>> $svn mkdir -mm $url/X/x
>> R1=`svnlook youngest $repo`
>> 
>> # Catchup merge first-to-second
>> $svn sw $url/X $wc
>> $svn merge ^/A $wc
>> $svn ci -mm $wc
>> 
>> # Reintegrate merge second-to-first
>> $svn sw $url/A $wc
>> $svn merge --reintegrate ^/X $wc
>> $svn ci -mm $wc
>> 
>> # Keep-alive merge first-to-second
>> R=`svnlook youngest $repo`
>> $svn sw $url/X $wc
>> $svn merge --record-only -cr$R ^/A $wc
>> $svn ci -mm $wc

I did try setting svn:mergeinfo here:

svnmucc -mm propset svn:mergeinfo '/A:2-4,6
/X:2-7' $url/X

as that allows the following merge to be recorded, by removing X:4.

I don't think this is practical.  Should I record X:7 the current HEAD
or X:8 the HEAD created by the propset?  Or X:N for some big N?  Or some
sort of symbolic revision?  Or some way of just storing the reverse
merges: a "magic" path meaning the current branch followed by a list of
reverse merged revisons, something like ':reverse:4'.

>> # Reverse merge change on second NOT RECORDED
>> $svn sw $url/X $wc
>> $svn merge -c-$R1 ^/X $wc
>> $svn ci -mm $wc
>> 
>> # Reverse merge change on first RECORDED
>> $svn sw $url/A $wc
>> $svn merge -c-$R1 ^/X $wc
>> $svn ci -mm $wc
>> 
>> # Catchup merge CONFLICT
>> $svn sw $url/X $wc
>> $svn merge ^/A $wc
>> 
>
>

-- 
Philip

Re: Support for reverse merges?

Posted by Julian Foad <ju...@wandisco.com>.
On Tue, 2011-08-30 at 18:00 +0100, Philip Martin wrote:
> Paul Burba <pt...@gmail.com> writes:
> 
> > Could you provide some examples of when 'things start to go wrong when
> > you next try to use "automatic" merges between the branches'?  Was
> > there a particular use-case (or cases) you had in mind, or just a
> > general sense that maybe this is/could be a problem?
> 
> Here's one (shorter recipes are possible):

Yes, this is exactly the sort of thing I mean.  What I expect in general
is that if I have merged the same change into both branches, then an
automatic (catch-up) merge would do nothing with that particular change.
But here we reverse-merge the same change into both branches, and then a
catch-up merge raises a conflict on that change.

The description of issue #2881 "Support negated mergeinfo revision
ranges" says it's concerned about a missing child in the merge target,
but what I'm talking about is more general.

When I first started thinking about recording reverse merges I worried
about crazy complexities: "How would we record a reverse-merge of some
change that isn't already in the target's mergeinfo because it wasn't
brought in by a merge in the first place?  Isn't that rather like trying
to teach the merge tracking to record an arbitrary diff that might come
from anywhere and might not share ancestry with the target?  What if we
reverse-merge a change that Subversion doesn't know is there, only the
human knows it's there - does the number-of-merges of this change go
from 0 to -1?  Then if we forward-merge and reverse-merge that same
change several times, between each merge doing more hand-editing that
Subversion doesn't know about, does the count go from -1 to 0, -1, 0, 1,
0, -1, -2, -1, 0, 1, 2, 3, 2, ...?"

But then I realized that's totally unnecessary.  We don't need and
shouldn't even attempt to record anything other than 'We have change C'
or 'We don't have change C', for each change 'C'.  The only new thing
that I think we want here is the ability to record 'We don't have change
C' when C is in our own history; where currently we always assume that
we DO have each such change.

- Julian


> #!/bin/sh -e
> 
> svn=svn ; svnadmin=svnadmin ; svnlook=svnlook ; svnmucc=svnmucc
> repo=repo ; wc=wc ; url=file:///`pwd`/$repo
> rm -rf $repo $wc
> $svnadmin create $repo
> 
> # Create first branch
> $svn mkdir -mm $url/A
> $svn co $url/A $wc
> 
> # Create second branch from first
> $svn cp -mm $url/A $url/X
> $svn sw $url/X $wc
> $svn merge ^/A $wc
> $svn ci -mm $wc
> 
> # Change on second branch
> $svn mkdir -mm $url/X/x
> R1=`svnlook youngest $repo`
> 
> # Catchup merge first-to-second
> $svn sw $url/X $wc
> $svn merge ^/A $wc
> $svn ci -mm $wc
> 
> # Reintegrate merge second-to-first
> $svn sw $url/A $wc
> $svn merge --reintegrate ^/X $wc
> $svn ci -mm $wc
> 
> # Keep-alive merge first-to-second
> R=`svnlook youngest $repo`
> $svn sw $url/X $wc
> $svn merge --record-only -cr$R ^/A $wc
> $svn ci -mm $wc
> 
> # Reverse merge change on second NOT RECORDED
> $svn sw $url/X $wc
> $svn merge -c-$R1 ^/X $wc
> $svn ci -mm $wc
> 
> # Reverse merge change on first RECORDED
> $svn sw $url/A $wc
> $svn merge -c-$R1 ^/X $wc
> $svn ci -mm $wc
> 
> # Catchup merge CONFLICT
> $svn sw $url/X $wc
> $svn merge ^/A $wc
> 



Re: Support for reverse merges?

Posted by Philip Martin <ph...@wandisco.com>.
Paul Burba <pt...@gmail.com> writes:

> Could you provide some examples of when 'things start to go wrong when
> you next try to use "automatic" merges between the branches'?  Was
> there a particular use-case (or cases) you had in mind, or just a
> general sense that maybe this is/could be a problem?

Here's one (shorter recipes are possible):

#!/bin/sh -e

svn=svn ; svnadmin=svnadmin ; svnlook=svnlook ; svnmucc=svnmucc
repo=repo ; wc=wc ; url=file:///`pwd`/$repo
rm -rf $repo $wc
$svnadmin create $repo

# Create first branch
$svn mkdir -mm $url/A
$svn co $url/A $wc

# Create second branch from first
$svn cp -mm $url/A $url/X
$svn sw $url/X $wc
$svn merge ^/A $wc
$svn ci -mm $wc

# Change on second branch
$svn mkdir -mm $url/X/x
R1=`svnlook youngest $repo`

# Catchup merge first-to-second
$svn sw $url/X $wc
$svn merge ^/A $wc
$svn ci -mm $wc

# Reintegrate merge second-to-first
$svn sw $url/A $wc
$svn merge --reintegrate ^/X $wc
$svn ci -mm $wc

# Keep-alive merge first-to-second
R=`svnlook youngest $repo`
$svn sw $url/X $wc
$svn merge --record-only -cr$R ^/A $wc
$svn ci -mm $wc

# Reverse merge change on second NOT RECORDED
$svn sw $url/X $wc
$svn merge -c-$R1 ^/X $wc
$svn ci -mm $wc

# Reverse merge change on first RECORDED
$svn sw $url/A $wc
$svn merge -c-$R1 ^/X $wc
$svn ci -mm $wc

# Catchup merge CONFLICT
$svn sw $url/X $wc
$svn merge ^/A $wc

-- 
uberSVN: Apache Subversion Made Easy
http://www.uberSVN.com

Re: Support for reverse merges?

Posted by Paul Burba <pt...@gmail.com>.
On Tue, Aug 30, 2011 at 12:30 PM, Julian Foad <ju...@wandisco.com> wrote:
> Philip and I were discussing the other day...
>
> It seems that we don't consistently record a reverse merge.  Sometimes
> we do, sometimes we don't.
>
>  * Iff this branch's mergeinfo mentions the change that we're
> reverse-merging, then we remove the mention from the mergeinfo and so
> merge tracking can notice that the change is no longer recorded as being
> there.  (And a further catch-up merge will bring in that original change
> again.  For the purposes of this discussion, let's assume that that's
> what the user expects.  We don't expect Subversion to remember that the
> change is "permanently unwanted, and dealt with by rejecting it"; that
> would be a different issue.)
>
>  * If we reverse-merge a change that *isn't* recorded in the target
> branch's mergeinfo, then we silently proceed without recording anything.
>
> Am I understanding this correctly?  If so, then, we're thinking, that
> inconsistency is where things start to go wrong when you next try to use
> "automatic" merges between the branches.

Hi Julian,

Could you provide some examples of when 'things start to go wrong when
you next try to use "automatic" merges between the branches'?  Was
there a particular use-case (or cases) you had in mind, or just a
general sense that maybe this is/could be a problem?

> I suppose this is a known limitation.

Yes, it is a know problem, a very old one at that:
http://subversion.tigris.org/issues/show_bug.cgi?id=2881

> The book says you can undo an old
> change by reverse-merging it, and it is briefly mentioned under the name
> "rollback merge" in
> <http://svn.apache.org/repos/asf/subversion/trunk/notes/merge-tracking/requirements.html#rollback-merge> and <http://svn.apache.org/repos/asf/subversion/trunk/notes/merge-tracking/func-spec.html#repeated-merge>, but it seems in practice that although you can perform a reverse-merge once it is not consistently tracked thereafter.  I don't know if we have anywhere a user-facing description of what merge scenarios are really supported by merge tracking.
>
> What Philip and I were thinking is that we can improve the support for
> reverse merges by always recording a reverse merge when it happens.  At
> the moment, all changes in a branch's own line of history are implicitly
> part of its mergeinfo, they are not stored explicitly, and therefore
> there is no way to record that one of those changes is now missing.  But
> if we stored the branch's own history explicitly then a reverse-merge
> from its own-history could be recorded in just the same way as a
> reverse-merge from any other branch.
>
> Of course that's hand-wavey as regards implementation details, but does
> that sound sane in broad terms?  For a start, the assumption that this
> is a known deficiency?