Freeze Yogurt, not Code!

8 בנובמבר 2010


It never ceases to amaze me, that to this day, I come across so many development teams that still initiate code freezes every time they release software. In this post I will show you why this is wasteful and how the need can be avoided altogether!

Code Freezing is the act of temporarily stopping all new development while focusing all of the resources on maintenance of the latest release. While releasing the latest feature set is usually the highest priority, it is often the case that the development team must divide their efforts between fixing the latest version (V-latest) and developing the next version (V-next).

Development teams and managers initiate code freezes because they cannot find a good, simple way to handle both development efforts at the same time.

Code freezes waste valuable time and resources. Each code freeze means that developers working on new features must either delay checking-in their code (until the freeze is lifted), or avoid working on the features altogether. Adding up the amount of time each developer is not working, or spending on complex check-ins & merges is the total amount of time wasted for each code freeze!

Fortunately, with most modern version control systems (TFS, SVN, etc.), it is possible to solve this problem, with a proper branching plan!

The following branching plan is just the core plan, which may be refactored to allow for multiple development and testing configurations, as well as more complex release mechanisms (e.g. releases, service packs, hot-fixes, etc.):


The plan consists of (at least) the following branches:

  • Main – On this branch the latest features are developed and tested. Your nightly build or cutting-edge version is built from this branch.
  • Release / Version – Whenever it is time to release a version, or before beginning to work on a feature for the next version, a new branch is made from Main. A release branch is made for each release version.

Working with the Basic Plan

  1. The development team develops new features on the Main branch.
  2. When it is time to release a version (to QA, end of sprint, etc.), and before developing features for the next release / sprint, make a Release branch (branch off main).
  3. From this point on, the team keeps developing new features only on Main.
  4. The team fixes issues with the latest release, only on the Release branch.
  5. Important fixes from the version branch are reverse-integrated (RI) – i.e. merged back – into Main.
  6. This process is repeated for each new version to be released.

Simple, isn’t it? I showed a friend of mine a draft of this post, and he asked “Isn’t this trivial? Why are you talking about this?”. I had to agree. It is trivial. But too few teams do this. I personally think that most teams simply do what they always did, because that’s how their managers did it when they were developers, a long, long time ago…

If you keep this up (dare I say religiously?) you will never have to freeze your code again; new features will never affect older versions. Developers can maintain old versions and develop new ones at the same time.

I think that once you try this, you will agree that this is a simple easy win.

If you want to learn more about branching plans for version control systems, a group called the VSTS Rangers (catchy, eh?) put together a great guide for branching with TFS. This guide can be easily applied to any VCS.

As for freezing yogurt, Please make mine with strawberries. It tastes great.

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>



  1. Maor10 בנובמבר 2010 ב 12:57

    I fail to understand…
    most places (employers) I know, will go to great lengths to save time and money, even when it is done at the expense of the programmers.
    So how does this coincide with their inability to assimilate these simple processes?

  2. Tal10 בנובמבר 2010 ב 14:25

    Wouldn't it be wiser to never actually develop on Main and only develop on RI branches?
    What about Customer specific features? Some features should never make it back to the Main, would that create a Customer specific main?

  3. Assaf Stone10 בנובמבר 2010 ב 14:55

    LOL. Unfortunately it is the time (and time is money) that must be spent on coming up with a good branching plan that gets saved. Too many teams think of their version control systems as nothing more than a central repository to save their code at.

  4. Assaf Stone10 בנובמבר 2010 ב 14:58

    First, you could treat the customer specific features as a private release, and thus it would be no different from any other release, except that you'd avoid RIs that you don't want to put back in the main code. This however would introduce problems in cases where your customer-release contains both code that should not be RIed and code that should.

    To solve that, I would suggest that you develop your code in such a way that you can easily separate customer-specific code from main (common) code. the simplest method to do so would be to use the Strategy pattern, and have the diverging code stored in a different module, so that you can easily avoid merging it back into the main code, or better yet, not care whether you do so or not, because you can, at run-time decide whether to use customer-specific features or not.

    Does this make sense for your scenario?

  5. Yuval12 בנובמבר 2010 ב 18:23

    As we began discussing in person – how do we handle a situation where we have an infrastructure team serving two or more application teams?
    We would have to open a branch for every combination of infra + application + release versions, i.e., infra-app1-release1, infra-app2-release2, etc. This would get unwieldy very soon with multiple applications.

  6. Assaf Stone13 בנובמבר 2010 ב 9:39


    Assuming that the two applications you mentioned, are separate modules (Visual Studio solutions, or Eclipse projects, or what-have-you), I would suggest that the shared infrastructure would be a separate module as well; This will allow (without forcing) you to have the applications and common infrastructure to run in separate development and release tracks (i.e. each has its own "Main" and "Release branches), as necessary.

    Once you've separated the release tracks, each application will use the common infrastructure's successful builds (as opposed to the latest sources). This will make sure that changes to the infrastructure will not break the applications (or one of them), because each application will advance to accept the latest changes when it is ready for them.

    In essence, the applications will treat the common infrastructure as if it was a 3rd party module (the fact that they know the developers, who may be sitting in the next room is just incidental).

    In this way, the number of releases is the number of components (i.e. increases linearly) or modules you have in the entire suite, and not a product (i.e. polynomial increase) of them.

    Does this help?