13
votes

We have been experimenting with a new technique to manage our release branches.

Generally, we maintain our current release on the trunk, and create release branches for each release. The release branch is where active development usually occurs, and the trunk is used for bug fixes on the current release.

We have been periodically merging the bug fixes from the trunk into the release branch (weekly).

Now that we are ready for another release, we would like to merge the release branch into the trunk. Unfortunately, this leads to many conflicts (> 50). At first I was surprised, but now I understand that Subversion cannot easily rectify the changes in the branch with what exists in the trunk.

Is there a way to tell Subversion to use all of the versions of the files in the branch when integrating back into the trunk? We know that the branch versions of files are 'correct'.

As an alternative, we could theoretically abandon the trunk and just work off of the branch(es) - branching from the branch for releases.

We use TortoiseSVN and Subclipse.

4

4 Answers

12
votes

From the output of svn help merge:

--accept ARG

specify automatic conflict resolution action ('postpone', 'base', 'mine-conflict', 'theirs-conflict', 'mine-full', 'theirs-full', 'edit', 'launch')

To accept the branch changes when merging to the trunk, you need the "--accept theirs-full" option.

I don't think TortoiseSVN 1.6.2 has an equivalent option in the GUI. You can still interactively resolve conflicts by selecting "use repository" as each conflict is encountered during the merge.

6
votes

I believe what you were doing by copying bug fixes from the trunk to your release branch is sometimes known as rebasing. All rebasing means in this case is that you take a branch which was normally based as say revision r49 of the trunk and merge changes from say r50-r57 of the trunk into the branch so that afterwords you can now consider that branch as based on revision r57 of the trunk instead of revision r49.

The problem in practice is that when merging a range of revisions from the trunk, or any other base, into one of it's branches it does not reset the base revision in which that branch was created but instead leaves the normal mergeinfo properties as the only way of knowing what has been merged. In order to be able to reintegrate the changes from a branch back into it's base (such as trunk) without unintentionally replaying the merged base changes say from r50-r57 in my previous example would be to merge changes from the branch to the base by cherry picking particular revisions in a way that any revisions caused by rebasing (merging from the base to the branch) are not included.

Unfortunately other than that it would be up to the Subversion developers to implement a way to automate this so that only revisions that do not contain a mergeinfo property that describes a merge that contains only revisions between the original base revision and the target revision of the base (generally HEAD). This gets more complicated in that merges often include manual changes that are commited allong with the merge commit on a branch that would be lost and also the origin of any given object would have to be tracked down to it's common ancestor in order for this to work properly on staircased branches. Other than that, a feature that would allow a branch to be replaced by a newer copy of the base or trunk with all previous commits reapplied in as a series of separate commits would also make this possible and however awkward would behave more like a true rebase.

These comments are not a definitive answer but represent my understanding as a long time Subversion user. If anybody has any other points to add or can pick something out that may be incorrect in my statements please let me know by all means so that we can get a real understanding of the capabilities and limitations of the current implementation of Subversion are.

Update: According to the Subversion documentation it appears that when using the --reintegrate option that Subversion should be able to properly reintegrate work done in a branch in a way that minds any possible refresh merges that may have been done to bring base changes into the branch. Of course this is is technically a little different than rebasing but i think it is similar enough in usage that it could be referred to as rebasing. The main question now is whether --reintegrate option works when changes from the base have been merged into the trunk in a cherry picked fashion instead of merging everything from BASE+NEXT to HEAD.

Update: It appears that cherry picking should be supported as well when using the svn merge --reintegrate option for Subversion 1.5 and up. Following these instructions should allow you to reintegrate without causing unintented conflicts due to reintroduction rebase change revisions.

For more information read the Subversion book under the section titled Keeping a Branch in Sync.

0
votes

Maybe I'm missing something here, but it sounds like the easiest option would be to delete trunk and re-create it by branching from your newer release branch.

0
votes

In theory you could do a "merge two different trees" from the head of trunk to the head of the branch. This should avoid any odd conflicts due to reintegrate.