Search code examples
svnsvn-merge

SVN Merging and tree conflicts "local add, incoming add upon merge"


I'm trying to follow the release branching model described at http://svnbook.red-bean.com/en/1.7/svn.branchmerge.commonpatterns.html, but on attempting to do the merge I get a merge conflict.

# Normal SVN Structure
svn-testing2> ls -l
total 12K
drwxrwxr-x 3 xxx yyy 4.0K Jan 13 17:28 branches/
drwxrwxr-x 3 xxx yyy 4.0K Jan 13 17:28 tags/
drwxrwxr-x 3 xxx yyy 4.0K Jan 13 17:28 trunk/

# Create & commit some  data
svn-testing2> echo "line1" > trunk/file1; svn add trunk/file1; svn commit -m "created file1 " trunk/file1
Adding         trunk/file1
Transmitting file data .
Committed revision 2.

# Create the release branch
svn-testing2> svn copy trunk branches/release
A         branches/release
svn-testing2> svn commit -m "created release branch" branches/release
Adding         branches/release
Adding         branches/release/file1

Committed revision 3.

# Make & commit a change to trunk
svn-testing2> echo "line1-file2" > trunk/file2; svn add trunk/file2; svn commit -m "created file2" trunk/file2
A         trunk/file2
Adding         trunk/file2
Transmitting file data .
Committed revision 4.

# Attempt to merge the change to trunk:
svn-testing2> cd branches/release/
svn-testing2/branches/release> svn merge ^/trunk
--- Merging r2 through r4 into '.':
   C file1
A    file2
Summary of conflicts:
  Tree conflicts: 1
bumjvr@mbs-p:~/svn-testing/svn-testing2/branches/release> svn st
 M      .
      C file1
      >   local add, incoming add upon merge
A  +    file2

I can fix this with

svn-testing2> svn resolve --accept=working *

But it seems wrong that I have to do this.

If I then apply a "hotfix" (e.g. create "release/file3") to my release branch, how do I port that back to trunk? If I merge "release" into "trunk" it merges OK but when merging "trunk" back to "release", I get another local add, incoming add upon merge conflict on e.g. "file3"

I'm not trying to "reintegrate" a feature branch, as these are both long running branches.

It's frustrating that the SVN redbook (which is generally excellent) describes this common branching pattern, with no worked examples of what commands to actually run!

What exactly do I need to run to follow this branching pattern without all these incorrect merge conflicts? Or are there any worked examples of this branching pattern anywhere - I can't find any!


Solution

  • This is due to your copy operation being done completely on the client-side. This operation does not include any merge tracking information and so when you attempt the merge it tries to add file1 on top of itself. This behavior is described in the disclaimer in the help for the copy command:

    > svn help copy
    
    copy (cp): Copy files and directories in a working copy or repository.
    usage: copy SRC[@REV]... DST
    
      SRC and DST can each be either a working copy (WC) path or URL:
        WC  -> WC:   copy and schedule for addition (with history)
        WC  -> URL:  immediately commit a copy of WC to URL
        URL -> WC:   check out URL into WC, schedule for addition
        URL -> URL:  complete server-side copy;  used to branch and tag
      All the SRCs must be of the same type. When copying multiple sources,
      they will be added as children of DST, which must be a directory.
    
      WARNING: For compatibility with previous versions of Subversion,
      copies performed using two working copy paths (WC -> WC) will not
      contact the repository.  As such, they may not, by default, be able
      to propagate merge tracking information from the source of the copy
      to the destination.
    

    If you change the copy to a server-side copy, the merge will succeed:

    # This is the difference, the copy happens on the server
    > svn copy ^/trunk ^/branches/release2 -m "Creating release2"
    Committed revision 5.
    
    # Update our working copy to get the new release
    > svn update branches
    Updating 'branches':
    A    branches\release2
    A    branches\release2\file1
    A    branches\release2\file2
    Updated to revision 5.
    
    > echo blah>trunk\file3; svn add trunk\file3; svn commit -m "created file3"
    A         trunk\file3
    Adding         trunk\file3
    Transmitting file data .
    Committed revision 6.
    
    > cd branches\release2
    > svn merge ^/trunk
    --- Merging r5 through r6 into '.':
    A    file3
    --- Recording mergeinfo for merge of r5 through r6 into '.':
     U   .