Where do I fix a production defect?

Question from a customer of the Rangers Branching Guidance (https://tfsbranchingguideiii.codeplex.com )

“My company has a major release every 3 months.  In between major releases we have monthly maintenance releases. (Similar to the "Advanced Branching Plan")

Our monthly release usually is limited to high priority bugs based on customer complaints and business needs.

Scenario:
Lets say there is a production bug reported by a customer shortly after a major release.  It hasn't been determined if this bug will be included in a hotfix, the next maintenance release, or the next major release. What branch should the developer make their changes?

We currently work bugs in our development branch if we don't know if the fix will be part of the next maintenance release.

The problem is that this often leads to cherry picking changesets to separate fixed bugs from new development work.

We are thinking about creating a new branch called "Bugs" from the parent "Main". The thought was that this would help isolate sprint development work (new features) from production bug fixes to released code. 

                                                        Main
                                         -----------------------------------------------
                                         |                          |                |
                                         Development   Bugs        Release           

I am seeing the advantage of having production bug fixes in the Hotfix branch of the Release Vehicle, however I am still a little confused on how to handle multiple service packs.

So for example lets say we had a major release in February with SP1 planned for March and SP2 planned for April. Release branch is locked down and (RI) back to Main. Post February release there are 8 production bugs reported. Developers fix bugs in Hotfix branch.

Major Release - February
SP1 - March
SP2 - April
HotFix - contains fixes for bugs 1,2,3,4,5,6,7,8

After bugs have been completed in the Hotfix branch Management determines that:
bugs 1, 2, 3 need to be in SP1 (March)
bugs 4, 5, 7 need to be in SP2 (April)
bugs 7, 8 will go with the next version

Is there a branching strategy that can encompass all this in the Release Vehicle?

My Response:

In the Rangers Branching Guidance, the Release branches have a specific relationship to each other. In each of the plans, the Release branch is locked down (made read-only) to capture each major and / or minor release shipped to a customer. Since the Release branch is read-only it must be at the lowest level in the release branch hierarchy (with Main at the top). If you are doing post-release servicing, then we suggest having a Servicing branch between Main and Release or even a Service Pack branch (as child of Main) and a Hotfix branch (as child of ServicePack) with Release as child of Hotfix (and then made read-only.

Your Bugs branch (as a child of Main corresponds to the HotFix or Servicing branch in the advanced or standard branch plan, respectively. The primary difference is that the Release branch is a child of the hotfix or servicing branch, rather than in a separate branching structure. This allows you to have multiple active release sets (consisting of Service Pack, Hotfix, Release branches) for each of the minor or major releases you need to support in parallel. The hotfix would be applied to the specific release the bug is found in, and then merged (RI) to Main and possibly into vNext development branches.

The branching plans in the Rangers branching guidance do, in fact, separate your sprint work (in a sprint development branch) from the Release and Post release bug fixing. It also allows Main to remain as stable as possible. It also means you won't need to cherry pick changes (avoid cherry picking if at all possible).

Since the development branches are working on vNext work after vCurrent is released, I discourage you from fixing defects found in vCurrent (post-release) in the vNext development branch. After you release Sprint 1, you should fix defects (post-release) in Sprint 1 on the release side, and fix bugs (pre-release) in Sprint 2 on the development side (vNext).

Some have suggested making the HotFix branch a child of the Release branch. I never make a hotfix branch a child of release (for reasons stated above). To the contrary Release is a child of hotfix. At the time you create the release, the contents of hotfix and release are the same. Release is made read-only and Hotfix is available for making defect fixes against what was released.

The problem with inverting the structure, is you cannot move a hotfix to Main without going through Release, and doing so means you no longer have a copy of the code as released. If you don't want a locked-down read-only release branch, then skip the hotfix branch altogether, make the hotfixes in the release branch directly (obviously you would not be able to make release read-only in this scenario).

Let's use the following scenario:

In February, you release v1.0, that has been under development. While it was being developed, v1.0 was vNext. Once it is released, it now becomes vCurrent, and development begins on v2.0 (the new vNext)

So when you release vNext, you create (all at the same time) Service Pack branch for Release 1.0 (child of Main), Hotfix branch for Release 1.0 (child of Service Pack) and Release branch for Release 1.0 (made read-only)

Presumably you have some post-release fixes to production for vCurrent. You fix bugs 1,2, and three in the Hotfix branch. You decide to roll-up these fixes into a Service Pack.. so you Merge (Reverse Integrate) bugs 1,2, and 3 into the Service Pack branch for Release 1.0. After thorough testing you release this Service Pack to customers.

AT THIS POINT (March), you could choose to make a new branch for the Released Service Pack (for example, branch Service Pack 1.0 to Hotfix 1.0.1 and Release 1.0.1 and make Release 1.0.1 read-only.

Now you find more bugs to fix, so you fix these bugs in the hotfix branch (for wither Release 1.0 or Release 1.0.1 depending on whether the bug is in the original release (1.0), or the service pack (release 1.0.1)

Note that you do not need a new branch for the service pack ... it continues, once Service pack 1 is shipped in March to be available for stabilizing Service pack 2.

bugs can be fixed in either the Hotfix branch for Release 1.0 or the Hotfix branch for Release 1.0.1 (SP1).

Now (April) you decide to ship SP2 (so you merge any changes in either hotfix branch below the Service Pack branch for Release 1.0.x up to the Service Pack branch (RI). You stabilize the bugs (4,5,6) and ship Service Pack 2.

Same process as in March, you make a new HotFix branch for this new Service Pack, and a new Release branch for Release 1.0.2 (SP2). Make the Release branch Read only.

At this point you have ONE Service Pack branch and three Hotfix branches (1.0, 1.0.1, and 1.0.2), and three Release branches (1.0, 1.0.1, and 1.0.2).

Bugs 7 and 8 get fixed in one of these three hotfix branches. They get merges (RI) to the Service Pack Branch and either stabilized for another SP (SP3) or merged again (RI) to Main where they are part of the next Major/Minor release.

From Main they get merged (FI) to the vNext development branches.