Over the past few years, I have seen – and implemented – a number of Git strategies, attempting to get source control working for you, in a way that makes sense to everybody yet simple enough that even the most junior or process inept developers can follow and maintain. Admittedly, I am not a stranger to implementing bad or over complex strategies, so I like to think I know what I am talking about. However, what follows is largely my opinion and I know it is a subject that can divide software communities.
If you haven’t already heard of it, the process that I tend to follow – and highly recommend – is GitFlow. This is a very well thought out branching strategy that can help you maintain a stable baseline, a development stream that aides feature development and releases. The problem with GitFlow is that many people implement it with slight quirks and differences to the original specification, some of which have the possibility of introducing issues later on down the line when you may need to rely on the history of your solution.
So, I wanted to share how I use GitFlow. Feedback is welcome and I hope this helps aid understanding for anyone struggling to implement a branching strategy and answer some questions as I have had many conversations and debates about this subject.
The Fundamentals of GitFlow
To start with, let’s take a look at the branches that are absolutely required to get GitFlow going. All implementations should have two main branches available:
So, what are these, exactly?
Master is your baseline, your production code. If you need to obtain the latest version of your codebase without any unreleased code then this is what this branch is for. You will also be able to obtain previous versions of your codebase as you will be using Git’s tagging ability to tag a version against your commits. But I will go into this on more detail later.
Develop is the branch that will contain completed, yet unreleased code. It is the branch that the majority of your feature and bug fix branches will be taken from and, once fully tested and agreed to go into the next release, will merge into. Whatever is in here should be ready to go into production (or close enough).
Branching and Merging
So, you’ve got your master and develop branches and you are now ready to do some work. Developers should never be working in either of these branches directly, and most source control systems (GitLab and BitBucket, at least, and I suspect GitHub will have a similar feature, too) allow you to lock branches down. Ideally, develop can only be merged in to by a pull request; and you should be able to specify who can do the actual merging on a pull request, if needed. Master however, will ideally be locked down to only certain people being able to merge into this branch. This means whoever does the release should ensure that the release branch gets merged into master once the release is live.
It also prevents accidental check-ins occurring on your critical baseline. It happens, and I have done it myself.
Typically (there are exceptions), there are only really three types of branches that should be needed for any development work to occur:
- Bugfixes, and
These should be fairly self-explanatory, however there is also some key points that all of your devs should be aware of. Features and bug fixes should be branched off of develop. Simply put, these are working branches that will need to be in sync with your releases, as you are developing them now to go into an upcoming release. You want your developers to be merging develop into their feature or bugfix branch as often as possible (ideally daily, but at least two or three times a week is fine, unless develop is relatively slow moving).
Hotfix branches, however, are different in as much as these are called for when there is a bug, security flaw or other critical issue in the production environment that needs resolving a as soon as possible; it cannot wait for the next release. You therefore do not want to be releasing work that is in develop as part of a hotfix. For this reason, you will be creating hotfix branches off of master.
In addition, we want to make our branches easy to identify so Git allows you to create branch names that make it easy to organise them, and most Git GUIs (including Visual Studio) will display these branches as if they are in a folder structure. Nice and easy and super useful.
So, how do you do this? Just name your branches using the following convention:
It is as simple as that. Some source control tools even have GitFlow workflows built-in to help you, although I haven’t used any of these so I cannot comment on how well they work.
Once you have completed your bugfix or feature, get it tested and the you may raise a pull request to merge it into develop. At this stage, you should ideally get someone to perform a code review and accept the pull request.
If you are working on a hotfix, then you need to follow the release procedure to get this into production. As per any other release, this then merges into master but you will also need to ensure that master is brought into develop as to ensure this branch is up-to-date with production.
Why not have a look at the Version Management article for more information on a release strategy?