As the unofficial CM / release manager at my current position, I’ve learned quite a bit about SVN and release management – typically by making mistakes. I won’t pretend that this is the one best practice to rule them all – any practice should be tailored for your company – this has worked out well for us.
We have a fairly typical agile/scrum based environment, with the exception that we release to production monthly instead of having weekly releases. If you’re releasing weekly then your feature sets and branches are typically quite small, and you can get away with hardly paying any attention to your branching strategy.
Furthermore – we branch often. Very often. Most of our development with is integrations with other companies, so it’s not uncommon to make a branch and spin up an integration for every partner’s project. It’s not uncommon to have more branches than we have developers, with most branches being used for integration testing – release date unknown.
The strategy we have adopted is to have one main release line, with a branch for each monthly release. The majority of our development happens in this line, and all releases happen from this line. We do not release from trunk. trunk represents an exact copy of the code that is in production, and is reserved only for emergency support or critical bug fixes. Immediately after a release, that branch is reintegrated back into trunk, and the branch is shut down for commits. Feature branches are typically branched from trunk, since their release date is unknown:
Before subversion 1.6, this pattern of branch-merge-reintegrate was very difficult, since subversion didn’t support merge tracking and you had to manually record every revision that was recording into every branch. Fortunately, this is much easier today. Here’s how:
Before proceeding, make sure that :
- All changes from trunk have been merged into the feature branch. This is absolutely required before a reintegrate.
- Ensure that all changes from the feature branch have been merged to any subsequent branches. Or, all changes from “MonthlyRelease” are merged to “NextMonthlyRelease”
- Ensure that all changes from trunk have been merged to any other feature branches, as needed. Or, all changes from “trunk” are merged to “Feature Branch”
For the purposes of this example, I’ll assume you are using TortoiseSVN on windows (the same can be accomplished via the svn command line options, and you can even automate it via that route).
Switch your local working copy to trunk, or check out a copy of trunk into a new folder if you don’t want to switch. Right click on the working copy of trunk, select Tortoise SVN, and then the “Merge” option.
In the dialog that pops up, select “Reintegate a branch”
In the reintegrate merge dialog, enter the URL of the feature branch that you wish to reintegrate. In our example, that would be the url for “MonthlyRelease”
As with any big merge, you should do a “test merge” first to identify any problems. But if the feature branch contains all merges from trunk and no merges from any other branches, the reintegrate should be easy.
After testing, click “Merge” on the merge options dialog and all changes from the feature branch will be applied to your local working copy of trunk.
Immediately commit all changes to the repository. Do not make any other changes before committing the reintegration. Use a prefix or easily identifiable commit message so you can easily find this commit later.
Trunk now contains all commits from the feature / release branch. You can safely set the MonthlyRelease branch to read-only and close it to any further commits.
Finally, we need to address the reintegrate in our other living branches:
“Next MonthlyRelease” already has all of the commits that were in “MontlyRelease”. We do not want to apply these commits into this branch again, because they have already been applied. We can do this with a “record only” merge, which tells subversion that a commit has been applied to a branch, without actually applying any changes from that commit.
Switch to the “NextMonthlyRelease” branch, and then select “Merge” from the TortoiseSVN menu. Use trunk as the URL to merge from, and select a range of revisions by clicking the “Show Log” button. Since the feature branch has already been merged to this branch select that commit from the log (you remembered the comment for that commit, right?).
Click “Next” and on the merge options dialog, select “only record the merge”. The one commit that includes all changes from “MonthlyRelease” will be marked as merged into this branch, and subversion won’t try to re-merge the changes later.
Merging trunk into our “Feature Branch” is just a standard merge – we do NOT want to do a record-only merge, because we want all the changes from MontlyRelease to be applied to this branch.
After trunk has been merged to any and all feature branches – the reintegrate is complete.