This project has moved. For the latest updates, please go here.

Completely independent bug-fix releases?

May 4, 2011 at 8:20 AM

Hi,

currently I'm migrating our source code from several versioning systems to TFS. Our management told us to use your branching guide to restructure our branching strategy. We are building factory machine. New machines are usually delivered with the current stable software version. We don't do regular updates because our customers prefer stability over new features.

After reading the main guide I have some questions. I understand the need for the main and the development branch, we had a similar thing using feature branches for feature development merging the finished feature into trunk/main.

But one need we have is that we must be able to create an independent bugfix for every version we ever delivered. Because we have customers using our machines in a specific version perfectly optimized for their production process. If they find a bug or need a change they don't want to get any other bugfix or feature we added in the meantime. So my idea is to create a label for every released/delivered version of the software. Whenever a customer requests a fix for instance for version v6.5, I create a "Release v6.5.1" branch from main, fix the bug, create a release/label for v6.5.1.0 and reverse integrate the fix into main. If this customer needs another fix I can do the next fix on the same branch (v6.5.1.1). If a different user with the same base version needs a different fix I can create a "Release v6.5.2" branch.

Can I achieve this with one of your strategies. I didn't find a way, but maybe I'm missing something.

Developer
May 5, 2011 at 7:01 PM

One characteristic of labels in TFS to be aware of - they are not immutable. You can probably achieve your goals by labeling your code with each release (6.5, 6.5.1, etc.). But TFS will not prevent you from modifying the *contents* of a label after it is applied to a branch. This may cause problems with auditors who want the contents of release *locked down*. This is one reason we recommend creating a release branch for each release, and locking it down. Since you need to be able to apply bug fixes to any prior release, you would need perhaps two branches for each release. Branch Main -> Servicing and then branch Servicing -> Release each time you do a release.

Lets say you have just released version 6.5.0. You could branch Main to create a Servicing 6.5. Label the code Release 6.5.0, but also branch Servicing 6.5 to create Release 6.5.0 and lock it down.

Now you need to create a bug fix against Release 6.5.0 - apply this bug fix in the Servicing 6.5 branch and release it to your customer. Label the code in Servicing 6.5 as Release 6.5.1 but also Branch Servicing 6.5.0 (with the hot fix) to Release 6.5.1 and lock it down.

Now if you need to apply a second bug fix to Release 6.5.1 make this fix in Servicing 6.5 (which now has the code for 6.5.1 as latest version). Make the fix in Servicing 6.5. Label the code in Servicing 6.5 as Release 6.5.2 but also branch Servicing 6.5 to create Release 6.5.2 and lock it down.

Each time you get a new bug fix for Release 6.5.x the fix would be made in Servicing 6.5 branch, but you need to decide which sub-version of the code to apply the fix to. It could be either 6.5.0, 6.5.1, 6.5.2. You should have a label you can roll back to if you do not want the bug fix against the latest version.

Later when you release version 7.0.0, you would branch Main to Servicing 7.0 and then branch Servicing 7.0 to Release 7.0.0 and lock it down.

If you are concerned about the overhead of creating a new lock-down branch for major Release and each minor hot-fix you could probably get by with only creating Release branches for the major releases and not each hot fix. Nevertheless, read my latest blog to gain a better understanding of the actual overhead involved in creating a new branch: http://www.tinyurl.com/tfsversioning.

Normally when you have a one-to-many relationship in a hierarchy (such as a branch hierarchy), you would make the *one* the parent and the *many* children of the parent. You might think you want to invert the relationship between the Release branch and the Servicing branch, since you have many possible bug fixes for a given release. But if you invert the relationship in this way: Branch Main to Release 6.5.0 and then branch Release 6.5.0 to Servicing 6.5.1 and later branch Release 6.5.0 to Servicing 6.5.2. But when you put the servicing branch(es) as a child of the Release branch, you cannot merge the bug fix back to Main without merging it into the Release branch first. You would no longer have a copy of Release 6.5.0 (as released) since you would have merged post-release bug fixes into it in order to get them all the way up to Main.

Thoughts?

Bill Heys
VS ALM Ranger

 

 

 

 

 

May 9, 2011 at 7:02 AM

Thank you for the feedback! The servicing branch seems to be a good thing. But there is one thing that your structure didn't address. Multiple independent versions branched from the same base release.

This is a very common thing in our business. Two customers having the same version of the software are requesting two different changes/fixes independently. They don't want any other changes because the machine is running well in their specific process.

In my label based scenario this is easy to accomplish by creating two release branches. In your scenario I will have to create two servicing branches and two release branches. But based on what (if I don't use labels again). Before I'm getting the request from the customer I don't even know if I will ever need any hotfix release and I don't know how many I  will need.

I think when we restrict the change access to labels we could be safe. Additionally we could document the repository version for each release we are labeling. So even if we loose a label we will be able to branch from the right version.

Any ideas? This maybe is not the perfectly save way (because of the mutable labels), but we are having less overhead, less branching and less merging.

So our structure will look like this:

-Main (with labels for each release, e.g. v6.5, v6.8, v7.0)
--Dev01
--Dev02
--Dev...
--Release v6.5.1 (branched from label v6.5, branch number 1, with release labels like v6.5.1.0, v6.5.1.1 ...)
--Release v6.5.2 (branched from label v6.5, branch number 2, with release labels like v6.5.2.0, v6.5.2.1 ...)
--Release v7.0.1 (branched from label v7.0, branch number 1, with release labels like v7.0.2.0, v7.0.2.1 ...)

All changes in the release branches can be reverse integrated into Main. There should be no need to branch from the Release branches again, so there is no problem merging to main.

Developer
May 9, 2011 at 12:22 PM

If you read my response, above, I thought this was EXACTLY the approach I was recommending. There I said:

"Lets say you have just released version 6.5.0. You could branch Main to create a Servicing 6.5. Label the code Release 6.5.0, but also branch Servicing 6.5 to create Release 6.5.0 and lock it down. Now if you need to apply a second bug fix to Release 6.5.1 make this fix in Servicing 6.5 (which now has the code for 6.5.1 as latest version). Make the fix in Servicing 6.5. Label the code in Servicing 6.5 as Release 6.5.2 but also branch Servicing 6.5 to create Release 6.5.2 and lock it down."

I am recommending a *combination* of labeling and branching. The primary distinction, is I have a servicing branch where I apply the label and do the hot fixes. This allows development for vNext to continue unhindered on the Main branch (since you won't have to rollback the code in Main).

As I mentioned in my blog, the overhead of creating a branch is minimal. Not until you make changes to files in branch will you have new content (or deltas) to store.

Finally, since your approach is virtually the same as my approach there is NO difference in merging. On the release side, the only merging necessary is when you make a hotfix and wish to merge it up to main (Reverse Integration). This is EXACTLY the same for our respective approaches.

Regards,
Bill Heys
VS ALM Ranger

May 9, 2011 at 12:35 PM

Great! So I guess we are done here. Thank you for your ideas, comments and quick responses! I will discuss this internally now.