On Tue, Oct 16, 2012 at 06:35:21PM +0200, Stefan Sperling wrote: > Again, sticking to simple branching/merging patterns where all merges > happen between directly related branches makes things a lot easier.
Hi again Sven, I've looked at this some more trying to come up with a simpler solution. It turns out that the root of all evil really is the mixed-revision copy you've made to create the first branch. If the branch is created by copying URLs the add vs. add tree conflict problem disappears. Also, a 2-URL merge is not strictly required to run the merge between the two unrelated (or "cousin") branches. But you need to sync the branch you're merging from to trunk first, which moves the common ancestor point forward in history, beyond the creation of the file which is causing the add vs. add tree conflict. This requires a record-only merge to work around the mixed-revisionness of the branch but is otherwise straightforward. Below is a unix shell script I used to reproduce the problem. See the comments inside the script for more details. #!/bin/sh set -e cwd=`pwd` basename=`basename $0` scratch_area="`echo $basename | sed -e s/\.sh$//`" repos=$scratch_area/repos trunk=$scratch_area/trunk branch1=$scratch_area/branch1 branch2=$scratch_area/branch2 trunk_url=file:///$cwd/$repos/trunk branch1_url=file:///$cwd/$repos/branch1 branch2_url=file:///$cwd/$repos/branch2 set -x rm -rf $scratch_area mkdir -p $scratch_area mkdir -p $trunk echo alpha > $trunk/alpha echo beta > $trunk/beta mkdir $trunk/gamma echo delta > $trunk/gamma/delta mkdir $trunk/epsilon echo zeta > $trunk/epsilon/zeta svnadmin create $cwd/$repos svn import $trunk $trunk_url -m "importing project tree" rm -rf $trunk svn checkout $trunk_url $trunk echo foo > $trunk/foo svn add $trunk/foo svn ci $trunk -m "add new file" # mixed-rev copy! svn copy $trunk $branch1_url -m "creating branch 1" # doing this instead would prevent tree conflicts below: # svn copy $trunk_url $branch1_url -m "creating branch 1" svn checkout $branch1_url $branch1 echo bar >> $branch1/alpha svn ci $branch1 -m "change alpha on branch 1" echo foo >> $trunk/foo svn ci $trunk -m "change foo on trunk" svn copy $trunk_url $branch2_url -m "creating branch 2" svn checkout $branch2_url $branch2 # merge branch1 into branch2 -> tree conflict # "local add, incoming add upon merge" svn merge $branch1_url $branch2 svn status $branch2 # remove merged changes and tree conflict svn revert -R $branch2 # # sync branch1 to trunk, moving the common ancestor used for the merge # beyond the creation of 'foo' to avoid the above tree conflict # # r2 created 'foo' which exists on branch1 because of mixed-rev copy. # Mark r2 as merged into branch1 to avoid another add vs. add tree-conflict. svn up $branch1 svn merge --record-only -c2 $trunk_url $branch1 # Now merging trunk -> branch1 works fine svn merge $trunk_url $branch1 svn status $branch1 svn commit -m "sync branch 1 to trunk" $branch1 # Now merging branch1 -> branch2 works fine svn update $branch2 svn merge $branch1_url $branch2 svn status $branch2 svn diff $branch2