Git branching model for maintaining different versions

Viewed 1112

I read a lot lately about different branching models and always ended up with Vincent Driessen's approach as the best setup for my development team.

One thing which bothers me is the problem when different versions deployed at different customers should get hotfixes. In this model each hotfix should be tagged and merged into master.

But this could imply the timelime on master gets messed up as the one hotfix would be merged on master after a newer version was tagged...?

4 Answers

One thing which bothers me is the problem when different versions deployed at different customers should get hotfixes. In this model each hotfix should be tagged and merged into master.

Your definition of hotfix differs from Git Flow's definition. What you want are support branches, for example support/1.0, branched off of the commit tagged 1.0, while continuing work on your next release.

On this support branch, which you start for each version as soon as you have a change for that particular version, you apply what you call hotfixes for that particular version. If the main branch just had a 2.0 release and the same fix has to be applied there, it becomes a Git Flow hotfix which gets merged back to main (and develop) when finished, but not merged back to your support branches.

If the exact same change applies to multiple versions, you apply them to each support branch by rebasing or cherrypicking.

Each customer has his own server. Customer A uses version 1.0, customer Bversion 1.1 and they only want hot fixes, no version upgrades. Does that answer your question?

Yes. You have a maintenance nightmare on your hands. I hope they're paying you well.

Basic Gitflow supports finishing up the current release while continuing to develop the next one. It does not support hotfixing multiple versions simultaneously. You will need to supplement it.

In basic Gitflow, hotfixes branch off the latest version tag on master. Once complete they are merged back into master and tagged to form a new release. They are also merged back into develop to incorporate the hotfix into future work. This works fine if you're only supporting one released version at a time.

To hotfix multiple releases, you need a branch for each older supported release. When you move from v1.1 to 1.2, you would create support/1.1 off the last v1.1.x tag.

Hotfixes are developed the same way as above, but you'd also rebase it into the release branches and tag the result. Rebase, not merge, because you don't want to drag along all the other new stuff.

Let's say you made a hotfix to v1.2 on the branch hotfix/123. Now you want to apply it to v1.1 and v1.0.

# Copy the hotfix commits to support1.1
# Tag it as v1.1.1
git rebase --onto support/1.1 v1.2 hotfix/123
git tag v1.1.1 support/1.1

# Copy the hotfix commits to support1.0
# Tag it as v1.0.1
git rebase --onto support/1.0 v1.2 hotfix/123
git tag v1.0.1 support/1.0

This will copy only the hotfix commits to each release branch. As this code was written on a newer version of the software, it is likely there will be conflicts. As you gain more versions the conflicts will get worse.


Anything is preferable to maintaining multiple releases. If it were me, before I committed to this I would ask why my customers want to stay on old versions, and if they're worth the extra time and money.

Usually its because they perceive their version to be "stable"; version 1.0 works for them and they don't see the need to upgrade and risk bugs and breaking features they rely on. Sensible for the short term, but disastrous for the long term. As they fall further and further behind, when they do need to upgrade it will become increasingly difficult.

Sometimes this view of stability is imagined, and sometimes it is real. Regression testing can ensure each new version does not break existing features. You could even survey your customers to find out what features they particularly rely on and ensure they are well tested.

You could provide them with test servers to try their systems on with the new version so they can be sure it will work.

Finally, as a business, ask if supporting old versions is worth the cost.

In this model each hotfix should be tagged and merged into master.

That sounds like a broken model. Fixes need to be applied to whatever versions they apply to. master (or any other branch) may or may not need any given fix.

Moreover, "tagging the hotfix" does not make sense. Tags are names for commits, not for patches/diffs.

But this could imply the timelime on master gets messed up as the one hotfix would be merged on master after a newer version was tagged...?

Hotfixes should be cherry-picked/rebased. It does not make sense to merge another version's branch into master just to fix a bug.

Below is not an exhaustive explanation of every approach, but it should answer the heart of the question. I'll happily modify if anyone comments with suggestions for improvement.

Hotfixes should be deployed to any software versions that you are maintaining as part of your commitment to users. If you're supporting three minor versions behind latest, then you'll push patches to each of those supported versions when a vulnerability or bug is being corrected.

However, new features and non-critical patches will only be going to your latest version.

For example:

If my latest version is 2.3.0, and I've committed to supporting three versions behind latest, my users will expect that versions 2.2.x, 2.1.x, and 2.0.x will all receive bug and vulnerability patches.

If I commit a new non-critical patch, that puts my latest version to 2.3.1, and nothing else gets changed.

Then lets say a bug is identified. I take a quick look and find that the latest patches for the previous three minor versions are 2.2.9, 2.1.12, and 2.0.15.

All three of these past versions have divergent git histories due to them receiving different features and non-critical patches. But that doesn't mean I can't make a new commit to them individually.

Armed with that information, I will create a commit that solves the current bug and I'll push it to each of the different branches. Depending on code state, I may be able to use the same commit and push it to all branches... or I may need to customize it for each version. Regardless, all three past versions that I support will get the hotfix alongside my latest version.

The version numbers that have received the fix are 2.3.2, 2.2.10, 2.1.13, and 2.0.16

With that done, I've now managed to keep my commitment to users that all supported versions will receive bug and vulnerability patches.

Related