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

Re: Fixing merge - Subtree, Cyclic, and Tree Change cases

From: Stefan Sperling <stsp_at_elego.de>
Date: Wed, 20 Jul 2011 16:24:02 +0200

On Wed, Jul 20, 2011 at 09:41:48AM -0400, Andy Singleton wrote:
> The non-special merge case is also common even in projects that use
> Subversion. For example, consider the case where we have a release
> branch and a development trunk. I see this in almost every serious
> subversion project. We move some bug fixes to the release branch.
> So, it only has selected changes from the development trunk. We we
> also make bug fixes on the release branch, or on branches that
> developers make to fix and test the release version. We should be
> able to merge those into the development trunk.

I am not sure what you want to fix for this use case.
This works today. You can merge bugfixes into either direction.
Those merges are all cherry-picking merges.
There is no intention to ever reintegrate the release branch into
trunk, nor to reintegrate the trunk into the release branch.
So there are no problems with cycles.

As an aside, note that Subversion can track such cherry-picking
merges, while git and mercurial cannot. So Subversion already
has an advantage in this area.

To get cycles you need to do stupid things like fixing a bug in
a feature branch, cherry-picking this bug fix to trunk, and then
have the same feature branch sync to trunk so the bugfix bounces
back to it. This anti-pattern doesn't work well in git either,
you will always be able to create a scenario where the tool cannot
resolve a conflict automatically.
If the bug fix was made on trunk the feature branch would simply
soak it up in the next sync merge, without conflict.
The key thing to realise is that the location where changes enter
your branching/merging pattern does matter.

I would say that most cyclic merge problems happen because people
do not plan their branching/merging upfront, but just commit whatever
changes they like anywhere they want, and then expect their tool
to sort out the mess they've created. They don't realise that
separate branches have separate purposes for a reason.
"Fixing" merge for such users is really, really, hard, in any
version control system.

Consider this problem:

Your merge policy says you want to commit all your bugfixes to the
main branch before they get backported to the release.
You can do this in Subversion, just get working copy of the release
branch and run something like 'svn merge -cN ^/trunk' to merge
the fix committed in revision N.

Now, enter git or mercurial. You cannot do it this way.
Your policy does not fit the tool. You are required to commit your
bugfixes to the release branch first because every merge you run
always merges the entire branch. So if you run 'hg merge default'
in your release branch, you are merging lots of destabilising changes
into the release branch that are supposed to go into the next release.

Effectively, you only have what Subversion calls "reintegrate".
You can cherry-pick, but this won't be tracked as a merge because
the parent/child relationship between commits that git and mercurial
use for merge-tracking cannot represent this case.
So instead, you commit your bugfixes to all your active release
branches (maybe transfer changes from one release branch to another
via automated cherry-picks betwen the release branches), and then
get a working copy of your main branch, and run something like
'hg merge release-1.x' to merge all the bugfixes that have accumulated
in your release-1.x branch into the main branch. You do this merge
just once, possibly from the most recent release to minimize conflicts.

This is a good example of how the merge models used by a tool
influence the merge policy. You cannot expect any given tool
to support an arbitrary merge policy out of the box. It needs to
be planned around the capabilities of the tool.

> Stefan, thank you for explaining reintegrate merge. It makes more
> sense to me now. I also see how with the current 2-URL merge,
> "merge <branch>" can be ambiguous. If merge were redefined to mean
> "grab all changes", and that were calculated internally, then you
> would not specify two URL's, and the command "merge <from branch>"
> would not be ambiguous.

So I suppose your effort is focused on trying to replace the 2-URL
merge model with something better.
I would suggest to create a list of specific use cases that are
not well supported in the 2-URL merge model Subversion uses, and
then discuss each one separately. Without specific use cases to
talk about we won't be getting anywhere in this discussion.
Received on 2011-07-20 16:24:46 CEST

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