Search code examples
svnmergetags

Can SVN copy and override the target branch or merge and keep the source branch?


I am new to SVN. I found when you merge branch A to branch B, SVN moves all content in branch A to B, not copy. And when you copy branch A to branch C and when you do the same thing again, it gave you an error branch C already exists.

What I want to accomplish is:

  • first I have a branch/dev – for development
  • then copy branch/dev to branch/test – for function test
  • then copy branch/test to trunk – for stage
  • then tag to production.

Since I cannot override the existing branch, when I want to copy branch/dev again, I need to delete test first, which is inconvenient.

Is there a way to do it?


Solution

  • svn merge does not "move all content". In fact, "merging" and "copying" is in Subversion to very different operations. Merging will take the changes made in a branch and merge them into a working copy:

    $ cd my/working/copy
    $ svn merge ^/branches/myfeaturebranch .
    

    Will merge all (unmerged) changes from ^/branches/myfeaturebranch into my/working/copy. This will leave you with a working copy containing all the changes from /branches/myfeaturebranch which you are attempting to merge. At this point you may also have conflicts which you need to resolve before committing. (Note that the final act of merging is simply committing a bunch of changes.)

    Copying, on the other hand, is like cp -r SRC DST, where SRC and DST may either be local filesystem paths or repository URLs. When doing a repo-to-repo copy, Subversion will copy (not merge) all changes from SRC to DST. For example:

    $ svn copy ^/trunk ^/tags/1.0.0
    

    This will copy (or "tag") the current trunk to ^/tags/1.0.0. If the destination already exists, Subversion will refuse to overwrite it.

    So, what you want to do is probably something like

    $ svn copy ^/trunk ^/branches/dev # create dev branch from trunk
    $ svn co ^/branches/dev # checkout dev branch
    $ cd dev
    $ .... hack away ....
    $ svn commit .... # commit your development changes
    $ svn copy ^/branches/dev/ ^/branches/test # create testing branch
    $ svn switch ^/branches/test # switch to testing branch
    $ .... perform tests ....
    $ svn commit .... # commit your changes in the testing branch
    $ svn switch ^/trunk # switch back to trunk
    $ svn merge ^/branches/test . # merge testing changes into working copy for trunk
    $ .... resolve any conflicts ....
    $ svn commit .... # commit merge
    $ svn copy ^/trunk ^/tags/1.0.0 # final production tag
    

    Hope this straightens out things a little.