Stefan Sperling wrote:
On Sun, Dec 20, 2009 at 06:02:22PM +0000, William S Fulton wrote:
Hi,
We have been doing regular two way merges from trunk to branch and
vice-versa using svn 1.5. In 1.6 this results in tree conflicts. Is
there any guidance on how to deal with this scenario?
I think you should try to avoid doing this.
It's possible but it makes it very hard to know what changes really went
where and when. My favourite branching strategies only use a one-way
street between any two given branches. Such strategies tend to be simpler
to understand for both humans and for Subversion, and in my experience
it's usually possible to melt down even the most complex branching
strategy to a pattern where merges are one-way streets.
All I can find
is the svn book, which only talks about tree conflicts wrt to
working copies. I have a script attached demonstrating the general
problem. It simply adds/deletes files on trunk, merges to mybranch,
then merges back to trunk. In my possibly naive view, there really
isn't a tree conflict at all as there have been no changes on the
branch (other than what was merged from trunk!!). Perhaps we are not
merging correctly? Although using --reintegrate when merging back to
trunk removes the tree conflict problem, this can't be right option
as we want to keep the branch going in order to make further
releases.
You need to use --reintegrate.
After reintegrating a branch, there are two options for keeping the
branch going. An easy one, and one that requires a bit of understanding
about how Subversion implements merge tracking.
The easy one is that you 'svn remove' the branch after re-integrating it,
and then create it again by simply copying trunk to the branch name again.
That will work fine but you'll have to use the peg revision notation
to get at the branches you deleted in the past.
The other way is to do a record-only merge.
Let's say you created your branch in revision A, and now you just
committed revision B which made the final change to your branch
before reintegration. As you do the reintegrate merge, you commit
revision X which affects trunk -- it puts all changes you made on the
branch between A and B into trunk. So we can say that, from a semantic
point of view, the changes made on the branch between A and B are the
same changes as the ones that were made on trunk in revision X.
The thing is that Subversion doesn't know this. All it knows are paths
and revisions. It does not remember that trunk:X corresponds to the
revisions branch:A-B. You need to tell Subversion about this yourself,
to avoid the next catch-up merge from trunk to the branch to merge
revision X (the branch already has all the changes made in X).
You can do this using the --record-only option.
In a working copy of the branch, do:
svn merge --record-only -cX ^/trunk
This will only affect mergeinfo. Now after committing those mergeinfo
changes, you can run
svn merge ^/trunk
in a working copy of the branch again to soak up further changes made
on trunk.
Stefan, this works well, thanks very much for the suggestion. I have
also just come across this blog which gives more insight and limitations
into what you mentioned:
http://blogs.open.collab.net/svn/2008/07/subversion-merg.html
Personally, I think the svn documentation needs to have some more
information on bidirectional merging, tree conflicts when merging and
the background information given in that blog.
William