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.
- Redundant - At any given time, we will have 3 identical entities:
release
branch- A
master
branch (afterrelease-1.0
has been merged in) - A version Tag (
1.0
)
- 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.
- Merge and Build – This job should be the same as the Build Release job except it will
first merge the
develop
branch into therelease
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 thedevelop
branch.
- Important! Any changes made on the
- 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 themaster
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 themaster
branch - Commit your changes to the
hotfix
branch as necessary. - Merge the
hotfix
branch back into themaster
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 thedevelop
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!