At my work, we have been using a Git branching strategy based on Vincent Driessen’s successful Git branching model. Over all, the strategy that Vincent proposes is very good and may work perfectly out of the box for many cases. However, since starting to use it I have noticed a few problems as time goes on:

a LOT of branches – Since Vincent’s model has a branch for each release version, over time you get a lot of branches lying around.

– Since Vincent’s model has a branch for each release version, over time you get a lot of branches lying around. Redundant - At any given time, we will have 3 identical entities: release branch A master branch (after release-1.0 has been merged in) A version Tag ( 1.0 )

- At any given time, we will have 3 identical entities: Changes to every build – We use Jenkins CI and we currently have to change each job to point to the new tag or branch. It get’s a little tedious and won’t scale in the long run.

Fortunately, these problems are easy to fix. In fact, the fixes simplify the model and allow simpler automation.

So, with these points in mind, here is my modified model:

As you can see here, We have four main components:

develop branch – A local development branch. release branch – The Release Candidate (RC) branch, available on the staging environment. master branch – Identical to what is on production. This branch is what we use for hotfixes. Tags – The production environment is built from the tags. Tagging also gives us the ability to rollback if necessary.

Workflow

The workflow for this model is similar to Vincent’s process but I find that my model allows for a bit more automation. Having the following two distinct build jobs on your staging environment helps this process immensely:

Build Release – Build the staging environment with the latest release branch.

– Build the staging environment with the latest release branch. Merge and Build – This job should be the same as the Build Release job except it will first merge the develop branch into the release branch. This job can be automated to run at a short interval.

Once these jobs are created, the general flow will consist of two parts I call Development Mode and Release Mode.

Development Mode

Development mode is simple and probably almost identical to what you do now. You and your team develop on a local environment based on the develop branch. The automated Merge and Build job allows you to push new code to your staging environment easily.

Release Mode

When you are ready to do a release, a few small changes are all you need to do to enter “Release Mode”:

Disable the Merge and Build job – During “Release Mode”, you will only run the Build Release job. Fix the bugs – Any fixes that need to be done should be made directly on the release branch. Important! Any changes made on the release branch should be merged back into the develop branch. Test The release - Last round stress tests, acceptance tests and general QA can now be done.

Once you are satisfied that your release branch is fit for production, you should:

Merge the release branch into the master branch. Tag the master branch. Build the production environment using the newly created tag.

If you are wondering why we don’t just build our production environment from the master branch, it is because the tags give us the option of rolling the server back in the rare chance something goes wrong.

Hotfix Mode

With this model, you can easily apply hotfixes to the production environment.

Create a hotfix branch based on the master branch Commit your changes to the hotfix branch as necessary. Merge the hotfix branch back into the master branch. Create a new tag on the master branch. We use letters to signify a hotfix. Build the production environment again with new hotfix tag. Merge the master branch back into the develop branch.

Conclusion

Most developers can tell you, in a small team there is rarely time to waste. This git branching model allowed my team to stop wasting time building servers and focus on what matters: development.

As always, let me know what you think!