23

My development team has worked with subversion for quite some time. The way that manage the trunk and branches is as follows:

  • We (almost) always release from the trunk

  • Each release gets its own branch.

  • When a release is ready for QA, we merge the branch back into the trunk and create a new branch for the next release.

  • Developers work off of either the trunk or the branch, but there are no developer-specific branches.

Lately, we have had some nightmare merging sessions, in part due to some major changes to the application. These don't always go smoothly and issues sometimes pop-up during QA where subversion did not merge quite right.

One solution might be to merge trunk changes into the release branch on a regular basis, say weekly, to ensure that the most up-to-date trunk changes are in the branch. Conflicts can then be fixed in closer to real-time.

What is your experience with this issue? Is there a standard best practice? Also, do you have a good way of keeping track of which revisions have been merged into the branch (decent comments in subversion could probably handle that).

Paul
  • 16,255
  • 3
  • 33
  • 25
jonstjohn
  • 59,650
  • 8
  • 43
  • 55

5 Answers5

15

Firstly, I don't think there's a one-size fits all solution when it comes to managing code branches and releases. But to touch on a few of your points from my perspective:

  • Yes, I would merge changes from trunk into the release branch more often. Smaller chunks are always going to be more manageable than one large integration. And of course this means you're working against the latest most stable code.

  • Proactively teach people how to merge well. The developer who made the change should be doing (or be closely involved with) the merge. Understand what it is you are taking and what it should look like when it is finished. I too often see people run a integration without really knowing what they are doing and what they are expecting as the result.

  • Perhaps you want to have an integration branch that isn't trunk. This can be tested daily and any issues caught here before they go and break trunk and scare everybody.

Andy Hume
  • 40,474
  • 10
  • 47
  • 58
  • We're a relatively small team (4 developers), so we always involve everybody in the merge (at least those relevant). Sounds like an integration branch might be the way to go. – jonstjohn Feb 20 '09 at 16:00
  • 1
    I disagree. I've always branched every feature and bug on teams I've been on and it simply is the best choice. It works for many reasons. There's no reason not to. – PositiveGuy Feb 10 '12 at 07:06
  • If you've using a version control tool that makes branching very light-weight, such as Git, I'd agree. With Subversion or Perforce, etc. there is definitely more overhead when branching for a simple bug fix. Yeah - my advice now would be migrate your SVN repo to Git. :) – Andy Hume Mar 04 '12 at 22:35
13

So assuming I've got your model right here: You develop major changes to the project in a branch (off of trunk) which can get quite old.

You continue to do other development on trunk which always holds the 'live' software, so these changes are minor updates and bug fixes. You're getting problems when you merge the monumental development branch back into trunk.

You can only effectively manage 2 concurrent product versions with that model, which may be enough for now, but might bite you in other ways anyway and will get worse if you ever need to manage 3 or 4 versions. Can I suggest inverting the way you work?

Have a Version branch for each release. This should be branched from trunk (at any revision). The only way you modify the version branch is to merge in revisions from trunk.

This means you can work primarily on trunk instead of in a large development branch. You also apply your bug fixes directly to trunk - so you've got no major integration issues being stored up for the next release. To release bug fixes to the previous versions, just merge the required trunk revisions into the appropriate Version branch.

This way you can keep everything you want to release in branch, but only actually ever release what you're happy with, because that's all you merge in to the version branch.

You can still take development branches if you need, but you can keep them targetted and small, perhaps individual features rather than large projects.

This will allow you to manage multiple versions in a sane way and keep a good track of what's in each release using svn's merge-info.

Jim T
  • 12,336
  • 5
  • 29
  • 43
  • That's a very interesting way of looking at it. The only downside seems like you would have to do a lot of merging of the trunk to the branch. Suppose I'm working on release x and it is in QA, every time I do a fix, I commit to the trunk, then have to merge that revision to the branch, right? – jonstjohn Feb 20 '09 at 18:52
  • That's exactly it. By doing that, you'll have a merge record in the release branch saying that the fix in trunk has been merged into that release. We use this information at work to build a matrix of revisions and versions, marking visually exactly what revisions are in which versions. – Jim T Feb 20 '09 at 19:16
  • Thanks, Jim. Interesting perspective and may be a good solution for us. – jonstjohn Feb 20 '09 at 20:45
  • Hey Jim, do you mind taking a look at my question here: http://stackoverflow.com/q/4934610/34022. I like your concept but I'm not sure how to correctly integrate feature branches into the trunk and the release branches. Thanks a lot. – Marc Feb 08 '11 at 15:28
5

Our experience is to clearly differentiate:

  • development branch
  • consolidation branch (branch used to consolidate development we are sure to go into production

Trunk is only for recording stable released version, from which we can branch.

In the "development branch", we can manage important changes, included some which will not end up in the next release (because too complex, not ready in time, dependent on other late developments, ...)

The consolidation branch represents the final steps (note the plural) needed to finalize the release. It happens after a meeting where all the features needed to be delivered are validated.

We only merge into the "consolidation branch" what we are sure to put into production. We go on that branch until the final release.

Wolf
  • 9,679
  • 7
  • 62
  • 108
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • thanks - do you keep the development branches updated from the consolidation branch? or is the consolidation branch a 'final' step when all of the development branches are ready? – jonstjohn Feb 20 '09 at 15:55
  • - "final step": I try to complete my answer but my PC is frozen! – VonC Feb 20 '09 at 15:57
  • Sounds like a nightmare. What do you do when a feature that needs to go into production has modified a file that has already been modified by a feature that is not ready for production? – dan carter Aug 15 '13 at 03:47
  • @dancarter I don't see the issue. If the two modifications are done by different commits, you will revert, in the consolidation branch, the commit with the modif not ready for prod: that will remove that modification while leaving the other. Revert as in http://stackoverflow.com/a/933344/6309. – VonC Aug 15 '13 at 09:17
  • @VonC how can you revert the change you don't want in the consolidation branch? I thought you only merged into the consolidation branch the changes that were ready, therefore the unwanted changed wont be in the consolidation branch. This is where the trouble starts because the change you do want to deliver is on top of a change that hasn't been delivered. Therefore the change you do want will fail to merge because it's merging into lines/files that don't exist on the consolidation branch. – dan carter Sep 02 '13 at 21:26
  • @VonC Consider an example, you have class A on development branch, someone wants to add some behaviour as a specialisation, so they rename A to ABase and create new subclasses B & C, B takes some existing behaviour from A, C creates an alternate behaviour, and all the common behaviour is in ABase. Now someone working on a different task changes the existing behaviour that now lives in B. You want to deliver to the consolidation branch the second change (to B) without the first change, but B does not exist there. – dan carter Sep 02 '13 at 21:28
  • @dancarter you are right in general, even though I don't see "consolidation" as being the definitive list of features going into production: the integration of those features together can sometime reveal incompatibilities which makes a revert necessary. That list evolves until a "freeze", at which point the pre-prod is validated one last time, and the prod is built from it. – VonC Sep 03 '13 at 05:18
  • @dancarter I would however disagree on the specifics of your last example, which mixes evolutions and refactoring. I don't see refactoring as a dev effort compatible with the very next release, but more as a longer term effort, meaning: that "second change" to `B` in `dev` (while only `A` exists in consolidation) would need to be backported in consolidation to `A` (or in a dedicated dev branch with `A` in it, and then merged to consolidation). Trying to do both at the same time (evolutions on `A`, and refactoring on `A` both for the next release) doesn't seem sustainable. – VonC Sep 03 '13 at 05:22
  • @Vonc good luck merging Abase, B & C to the consolidation branch after you have manually backported the second change already. I guess you would just resolve the conflicts by overwritting the consolidation version with the development version. Problem is any good developer is going to be doing these sorts of changes constantly to keep the code in good shape as they extend it to add new features. So every release is going to have dozens of merge conflicts. – dan carter Sep 03 '13 at 22:42
  • @VonC For this reason i prefer to keep main development on trunk, and branch only once things go into UAT. Any fixes that need to go in during UAT or for prod support can be merged from trunk to the release branch (or vice versa). this way the overall amount of merging is very small. Any features that have been developed, but you don't want to release yet can exist in the trunk code base, but be disabled. e.g. you could do the refactoring of A to ABase/B/C but not have anything configured to use C yet. – dan carter Sep 03 '13 at 22:49
  • @dancarter "For this reason I prefer to keep main development on trunk, and branch only once things go into UAT" yes! I agree :) See also http://stackoverflow.com/a/16384644/6309 where I had a similar debate. I just realized that I am discussing over a 4-years old answer of mine, at a time where I was doing ClearCase UCM, with a structure of "Stream" which influenced my answer at the time: see the second half of http://stackoverflow.com/a/5636931/6309, or http://stackoverflow.com/a/9880266/6309. – VonC Sep 04 '13 at 05:35
  • @dancarter if you keep developing on trunk, there might be cases where you will have to revert some changes from trunk if they are NOT ready. Am I correct? – Vamsi Nerella Jun 26 '15 at 12:07
  • @user942640 yes, that can happen. – VonC Jun 26 '15 at 12:16
  • @user942640 I personally would not commit code that is not able to be released. You are following TDD right? That doesn't mean it will be active if it is released though. A new feature may be partially implemented, but if nothing other than tests invoke the feature then it is not exposed. I could imagine simple configuration changes being reverted, if we go into UAT planning to release feature X, and 1 week into UAT the business decide to delay the release, then we revert configuration to disable/hide the feature. – dan carter Jun 29 '15 at 02:27
  • Thanks @VonC and dancarter. say it is a bug fix, and UAT failed. it can get murky if other fixes are dependent on this and passed UAT. or lets say it can't be configured to 'disable' even if there are no dependencies, i guess they will have to be reverted. if we are facing these kind of things many times, should we be better off creating another development branch and merge to trunk/release branch only if UAT passes? I read the answer again, and this is what Vonc suggests :-) – Vamsi Nerella Jun 29 '15 at 07:27
2

Totally agree with Andy: There's no "one-size fits all solution", but the issue shouldn't be keeping your release branch up to date, rather the other way around.

Good change control should keep your branch from being volatile. Gating issues should be fixed on the release branch and then merged to the trunk immediately. Be ready for this "merge" to be non-trivial, the release gating issue may not even exist on the trunk but you need to do an analysis and test for it anyawy.

It sounds from what you say that you are developing on your branch and then merging all at once to your trunk just before you release and just crossing your fingers. I wonder how many bugs you are introducing by doing this.

user24881
  • 258
  • 2
  • 8
2

First, I wholeheartedly agree with the previous responders that there is no one-size fits all solution.

In our case, we have many relatively small applications, with each application normally having only a single developer. When we do engage in collaborative development, there tends to be only 2 to 4 developers.

Our general policy is:

  • The trunk contains the current project state;
  • We use branches for developing new features, bug fixes, etc. Branches are merged back to the trunk when complete;
  • To release, we create a tag from the current trunk and release the tag.

Andy also made an important point that needs emphasizing: "Proactively teach people how to merge well." Many, if not most of our problems seem to arise from poor merging practices.

John Watts
  • 359
  • 1
  • 5