subversion-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stefan Sperling <s...@elego.de>
Subject Re: unexpected tree conflict on merge for same source file
Date Wed, 17 Oct 2012 10:00:44 GMT
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

Mime
View raw message