Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct way to handle repeated merges of an SVN branch?

Here we have have an SVN repository with a trunk and a branch for development on a new release.

The branch is nearing ready for release now so I decided to reintegrate the branch back down to the trunk. Obviously there were some conflicts. Including quite a lot of tree conflicts from files that had been deleted in the trunk.

I resolved all the conflicts happily enough and committed the trunk.

The problem is that we then made a few more minor changes to the branch, so I went to reintegrate the branch again and all the same tree conflicts occurred. Resolving them isn't a problem, but there are quite a lot and it takes a while to check and resolve them all manually and I don't want to have to go through the same resolution processes every time I make a change and reintegrate. I had expected SVN to recognise that the branch had already been reintegrated once and only merge from the point the last reintegration had occurred.

When I open up the revision graph, it shows the trunk and the point that the branch was split off, but it doesn't show the merge. Should it?

Server: WinServer2003 (R2sp2), VisualSVNServer (1.7.2). Client: WindowsXP(sp3), I've been using TortoiseSVN (1.6.5) to do all of this, but I also have the command line client installed.

I do the merge by making sure I have the trunk up to date, and using TortoiseSVN to do a merge, and I select "Reintegrate a branch" when presented with the option dialog. I set the merge depth to "Working copy"

Am I handling this scenario incorrectly? Should I be doing something differently?

(Perhaps we have our repository layout wrong. We branched from the trunk, made all the changes for the new release in the branch, now the release is due we are merging the branch back down to the trunk. Perhaps this is the wrong approach, I've read about some people doing it the other way round, make all the changes in the trunk, and make the branch only when you are nearly ready for release and the branch becomes the supported release version)

like image 760
Simon P Stevens Avatar asked Oct 23 '09 08:10

Simon P Stevens


3 Answers

The following is from the end of this chapter of the SVN book:

In Subversion 1.5, once a --reintegrate merge is done from branch to trunk, the branch is no longer usable for further work. It's not able to correctly absorb new trunk changes, nor can it be properly reintegrated to trunk again. For this reason, if you want to keep working on your feature branch, we recommend destroying it and then re-creating it from the trunk

like image 163
sbi Avatar answered Sep 27 '22 22:09

sbi


In this situation I would not merge code from the branch to the trunk until after you've completed the development.

I would merge from trunk to branch to ensure your branch is up to date with any fixes applied to the trunk. Carry out this activity periodically to ensure your dev branch contains all fixes. Then at the point at which the development becomes the live release do the merge from branch to trunk as a one off activity.

My answer makes a few assumptions including:

  • You have live trunk and dev branches
  • You have only one live version (i.e. not maintaining legacy versions)

Hope that helps.

like image 27
Tom Duckering Avatar answered Sep 27 '22 23:09

Tom Duckering


It is now actually possible to do repeated bi-directional merging

A word of caution. This answer explains how it is meant to be done, but if you miss any step you will be sorry. For example, the --reintegrate merge must be completely trivial (all differences already resolved in the branch) since else you will silently miss getting the changes you did in the --reintegrate merge step when you continue working in your branch. The alternative is to instead delete and re-create the branch each time after --reintegrate .


In at least svn version 1.6 and later you can do repeated bi-directional merging. You can merge from the 'main' branch to the child branch as many times as you like with just svn merge, but each time you merge the branch back to main, you have to give the option

--reintegrate as mentioned in the other answers.

What you also have to do is to tell your branch that you integrated it in a second manual step (with that branch checked out and updated) with the command

svn merge --record-only -c 391 ^/calc/trunk

391 here represents the merge commit number from the --reintegrate branch commit you just did in calc/trunk .

If you miss it, it may still work, or you may need to re-resolve merge conflicts you already resolved next time you merge. After the record-only step your branches are ready for further work or merging. It's silly (especially if you are spoiled by Git like me, where things just work), but if you do it according to this ritual it works, and both branches are always open for new commits.


The whole thing is documented in the SVN book under reintegrate twice

This merge uses the cherry-picking merge syntax, which was introduced in the section called “Cherrypicking”. Continuing with the running example from the section called “Reintegrating a Branch”, where revision X was revision 391:

$ cd my-calc-branch $ svn update Updating '.': Updated to revision
393. $ svn merge --record-only -c 391 ^/calc/trunk
--- Recording mergeinfo for merge of r391 into '.':  U   . $ svn commit -m "Block revision 391 from being merged into my-calc-branch."
 Sending        .

 Committed revision 394.

Now your branch is ready to soak up changes from the trunk again. After another sync of your branch to the trunk, you can even reintegrate the branch a second time. If necessary, you can do another record-only merge to keep the branch alive. Rinse and repeat.

like image 31
Johan Lundberg Avatar answered Sep 27 '22 22:09

Johan Lundberg