views:

48

answers:

1

Hi,

I've been trying to get my head around SVN merging/reintegrating and have read a these articles/books:

http://svnbook.red-bean.com/en/1.5/index.html
http://blogs.open.collab.net/svn/2008/07/subversion-merg.html

I obviously haven't quite got it, as I can't see why including synched revisions in a merge back to trunk (reflective/cyclic merge) is a problem - I do see the rationale for not excluding the revision.

If a line of file A on trunk is merged in to file A' on branch and then merged back to trunk, then surely there is no difference between A and A', so there is no conflict? Why is "[merging] back changes that already exist in trunk" an issue?

I'm trying to replicate the conflict scenario to try and appreciate what reintegrate is doing for me, but what confuses me even more is this scenario:

  1. Commit a change on trunk (r4)
  2. Merge r4 in to branch and commit (r5)
  3. Commit a change on branch (r6)
  4. Merge back branch to trunk by either:
    • Merging revision range r5-r6 to trunk - Conflicts occur, or
    • Merging r5 to trunk, then merge r6 to trunk - No conflicts occur

I'm using SmartSVN 6.6 and SVN 1.6. Why is there a different outcome when merging a revision range compared to merging each revision individually? And ultimately, why is including reflective merges an issue?

+1  A: 

Short answer based on my observations of subversions merge behavior (not book/source knowledge):

  1. Merges with explicit revisions seem to be completly unaware of earlier merges and will reapply changes as often as you do the merge.

  2. A "regular" merge without any revision range is aware of what revisions were merged allready (to THAT target branch). Usually changes will not be applied twice. However it does not check if a to-be-merged change originated in the same branch that now is the merge target. It has some kind of context-sensitive merging when this happens but conflicts will arise more often nervertheless.

  3. merge --reintegrate is able to detect changes that originate from the past of the merge target and will not reapply those. Unfortunatly reintegration works for feature branches only.

I try to avoid any merges of type 1. for as much as I can. 2. type "regular" merges can be tamed by merging into one direction only. Trouble begins when you merge up and down again. Whenever I need to "cross-merge" like in a feature-branch scenario I use merge type 3. or cherrypicking with revision blocking (explicit revision range merge with --record-only)

SVN is simply not capeable to support a wide range of merge operations "blindly" :). No VCS can ever resolve all conflicting human decisions.

Why svn merge conflicts

The reason for its particular "conflictlyness" can partly be found in subversions history. Pre SVN 1.5 there was only explicit merging. You had to know what range of revisions you allready merged down and base your next merge on that knowledge or else the conflicts you describe would happen.

Merges in pre 1.5 SVN would look like:

(HEAD revision of the branch is 510) svn merge -r500:510 http://server.tld/branches/stable-1.0

the next merge would be:

(HEAD revision of the branch is 520) svn merge -r510:520 http://server.tld/branches/stable-1.0

This syntax is still valid and working.

You can read about what I described in the svn 1.4 best practices: (Attention, legacy link!) http://svnbook.red-bean.com/en/1.4/svn.branchmerge.copychanges.html#svn.branchmerge.copychanges.bestprac.track

With the merge features that were introduced in SVN 1.5, it started to gauge some of your intentions. For example now SVN will do the math of defining the ranges to merge automaticly and keep track of what was merged where. Less overhead, less conflicts due to human mistakes. But when using many branches you still might want to apply a change twice. Subversion preserved that ability.

How to live with it

The cherry picking that you do in your 4-step example keeps your trunk and branch pretty "tight". At step 3 your two branches are identical hense merging in step 4 makes no sense any more. I know you simplified and in a real-world scenario there would be more changes. But the main idea of subversion branches is to separate. Stable from unstable, incompatible development, custom builds ...

The need to cherry pick/cross merge often is only a symptom to not well enough thought through branching and branch-usage policies.

If branches cross-trade changes often, maybe you can make them one.

I'll stop the lecturing ;-) at this point, hoping I didnt confuse you too much.

If you want to know more about svn best practices maybe you'll find some in my SO-Answers or in the SVN Red book. I can post you a diagram about proper cherrypicking if that is an issue for you.

cheers

Christoph Strasen