Git – Appropriate Workflow for Multiple Active Releases and Hotfixes

gitversion control

I'm trying to choose a Git workflow that is most appropriate for our product. Here are the parameters:

  • We do a few major releases a year, let's say 10 at the most
  • We have multiple versions of our product active at the same time (some people are on v10.1, some on v11.2, etc.)
  • We need to be able to work on multiple releases at the same time (so we could be working on v12.1, but as we get to the end of the release we start working on v12.2 at the same time)
  • We need to be able to hotfix releases when critical bugs are found

So far, here's the way I think it could work:

  • Single remote repo is used
  • Create branch 12.1 from master
  • Create feature branches based on 12.1, commit them and merge back into 12.1, push
  • Once we need to start working on future release, create a new branch 12.2 based on 12.1
  • From then on, when working on a feature for 12.1, create branch from 12.1, commit changes, and merge into both 12.1 and 12.2, push
  • If working on a feature for 12.2, create branch from 12.2, commit changes, and merge only into 12.2, push
  • When release 12.1 is completed, merge it into master and tag master branch with 12.1
  • If a hotfix is needed, create a hotfix branch from oldest release branch that needs it, commit changes, and merge back into all release branches for that release and future releases that could be affected; if the latest stable release branch was affected, merge it into master.

I have a few concerns:

  • I'm not sure that merging hotfixes from old branches into new branches will be a smooth process, especially if there have been a lot of overlapping changes; would it be smarter to just hotfix manually in each branch in cases where it looks like there will be conflicts
  • The workflow models I've seen seem to not keep release branches alive much, once done the release gets merged into master, tagged, and removed. My problem with that is that I don't have a good idea how to manage the state of the release if all I have are tags in master, seems easier to hotfix in a branch and then I have a release I can always go back to that has the latest hotfix (I can even tag the hotfixes in the release). Not sure there's a way I could go back within master and somehow have a copy of the release with hotfixes applied and update that tag.

Comments are appreciated on things I may have overlooked or better ways of accomplishing things given the requirements I've specified.

Best Answer

You seem to be branching off on every major release (12.0.0), then having possible minor updates to each (12.1.0), and hot fixes (12.2.1). Correct?

There's no specific reason why you cannot keep release branches alive in GitFlow after a release is out, other than the fact that coordinating changes between multiple diverging branches for a long time is hard with any model. I suppose GitFlow was also modeled more for products that maintain a single live release while developing the next.

I would stick with GitFlow and make a few amendments;

Skip the master branch. I've had no practical use of it so far, and it would lose its linearity the way you work. Keep development on the next major release on develop. If you decide to keep master, don't put release tags on master, put them on the last commit on the release branch that produced the binary you're shipping.

Don't throw away the release branches after you merge them back to develop. Instead keep them around for the next minor release and possible hot fixes. If you ever stop supporting a release, I suppose it's fine to delete them. You could name release branches after their main component, release/12, and then create sub-release branches, release/12.1, release/12.2 off of it. I've not had to worry too much about this level of parallelism, but that's probably what I'd try. You can think of each major release branch as its own sub-GitFlow environment in this case.

If you must be working in parallel on features for several future major releases at the same time, perhaps you have to keep the next one (13) on develop and anything for later versions (14, 15) on additional "develop-N" branches. That does seem very hard to maintain in general, but would be possible.