Our New git Branching Model

With the initial RTM of Embarcadero Prism XE2 (Oxygene 5 for .NET) behind us and as we are preparing to also lock down for our other product releases in September, we have introduced some slight improvements to our internal branching model that I want to share with you, as they will have an impact on how we (can) deliver software, moving forward.

Then

Up until now, ever since we switched to git about a year ago, we have used a fairly straight-forward linear branch model that looked like this:

master <- beta <- develop  

All the development would be done on the “develop” branch, or for major tasks on subbranches off “develop”, such as for example “develop-feature-inlineerrors” for the new error marker support we added in Oxygene 5.

The subbranches keep major ongoing efforts from “contaminating” the main development trunk, until the feature (or fix) is ready to be merged. The nice thing about the (CI) Continuous Integration system we have in place is that it automatically creates new builds of (almost) any branch, as soon as new commits are made. So at any given time, anyone inside the company can just, say, grab the new installers from the oxygene/develop branch to get the latest and greatest, or indeed get oxygene/develop-feature-inlineerrors to test and use that one feature.

As stuff matures, “develop-x” branches get merged into “develop”, and once a week (or so) “develop” gets merged into “beta” and the build gets shipped to testers. And as we’re ready to RTM, “beta” gets merged into “master” and the resulting build goes out to you, our customers.

Now

So far so good, but this system left us with one problem: if we’re, say, 5 weeks after a new release, chances are the “develop” branch (and “beta”, as well) has a hodgepodge of new stuff. Bug fixes. New features. Partially done new features. Maybe even features we don’t want to talk about until the next major release.

But what if we want to ship a new interim release to customers that just wraps the latest and most important bug fixes (maybe there’s been a really critical bug that is affecting some customers badly)? Our model didn’t really let us do that, easily. Sure, we could always “cherry-pick” certain commits to a separate branch, but that’s clumsy and error-prone.

So what we did now is make our branching model a bit (quite a bit) more complex, in order to gain more flexibility. Rather than what I described above, our branch structure now looks like this:

Branch Structure

Everything downward from “beta” remains pretty much unchanged, but we introduced a new level around the “gamma” and “stable” branches that mimics “beta” and “develop”. What’s up with that?

The idea is that the “stable” branch (and its subbranches) will be used for any changes that we consider safe (or important) to be able to ship at any time. This could include:

  • trivial fixes, such as a typo, a missing file in our installer script, or the like.
  • critical fixes, such as those addressing a high profile bug that is biting a lot of customers, or an issue we found internally for that we’d like to get the fix out to customers, soon.

Where “stable” work is more complicated, subbranches can be spawned off to keep that work separate from the core “stable” branch until it is solid, for example in a “stable-tryingtofixthisoneweirdissue” branch.

The idea is that at just about any time we need to or feel like it, we can promote “stable” to “gamma” and then “master” and ship an interim release to you, with minimal chance of side effects or regressions from new work that is being done, and with far less testing and QA overhead than a regular full release brings with it.

All major development will keep going on the “develop” branch and its subbranches. This includes:

  • features, major or minor, for short-term or long-term projects
  • Fixes that are more complex/risky, less time-critical or involve breaking changes.

“Stable” will be up-merged into “develop” frequently, so that “develop” (and with it “beta”) will always get the latest fixes done on “stable” as well. This is important because most people here at RemObjects live on “develop” builds for their day-to-day use of our own products, to dog-food them, test (and enjoy) new features, and find problems soon. And “beta” builds are of course what goes out to our beta testers (our betas are accessible to all active customers, if they are interested).

Results

We adopted this new model for our “oxygene” repository at the start of this week, and the fruits of this are already visible. We RTM’ed Prism XE2 last week, with build 5.0.29.893, but we’re hard at work on more getting a few more bugs squashed and have an even more solid build in the hands of customers by the time the product actually hits the street. This is of course happening on “stable”, from where we already delivered a first build with 19 new fixes to our friends at Embarcadero (who manage the beta program and pass the build on to testers), yesterday. At the same time, the rest of the team is busy adding more features on “develop”, preparing for the “Cooper” release later this Fall. (One of the big features being commited to “develop” this week is Android device deployment and debugging right from the Visual Studio IDE.)

We want to see this system of frequent releases thru for Oxygene, and are planning to release stable update releases for Prism XE2 at the end of every month, for the rest of the year, as we work towards finishing “Cooper”. Prism users will get builds with more fixes, but unaffected by any Cooper feature work, until we actually merge the “develop” up to “gamma”/”master” and ship “Cooper”; “Cooper” beta testers will keep getting weekly beta builds with those fixes and new Java goodness.

For our other products, namely ROFX (Data Abstract, RemObjects SDK & Co) and Hydra, we’ll be switching to the same new model when we lock down our Fall release this week; after the Fall release has gone out in September, we’ll be looking into making “fix-pack” like updates available more frequently (where necessary). We might even – but this goes into the scope of another blog post I have planned that talks about our core CI system in more detail – look at making “stable”/”gamma” releases available to customers in an automated fashion, as part of a Continous Delivery effort.

Summary

Anyhow, I hope this post was interesting and gave you some valuable insight into our internal processes. We want to start talking more about how we work and what internal tools we use here at RemObjects, and I hope you find this useful information, even if it does not pertain directly to your use of our products. Let me know what you think!

Read more about Embarcadero Prism (Oxygene for .NET) at remobjects.com/prism.
Read more about Project Cooper (Oxygene for Java), currently in beta, at remobjects.com/cooper.

marc hoffman

Chief Architect and CEO here at RemObjects Software. Project Manager for Elements and lead developer of Fire, our awesome new development environment for the Mac.

Curaçao