For my first set of articles on this development blog, I’m not actually going to talk about code directly. Instead, I’ve going to focus my attention on source control and all things related to branching and merging.
We’ve all been there as developers – merrily working away on a new feature only for one of two things to happen:
- There’s a major bug with the live system and you need to apply a new hotfix right this second. You can’t do anything about it because you’re midway through developing a new feature
- You realize you’ve changed some code you shouldn’t have, but can’t undo in your IDE because you’ve closed and re-opened your editor window
Before I found source control, this used to really piss me off.
What is source control?
Primarily, source (or version) control gives you the ability to track changes to your code and also rollback/undo any changes you make that you shouldn’t have. It’s also a fantastic tool to allow multiple developers to collaborate and share the same code base without needing to pass a USB drive around the office (or around the world in today’s remote working environment).
Isn’t that just magic?
Anybody who has done any reasonable amount of development will have heard of and probably stumbled on to GitHub in one form or another. GitHub is probably THE most famous source code repository there is.
I’m using Azure DevOps in my organization at the minute, which is based on Git, so the same commands/features I’m talking about here apply to a lot of the source control systems out there.
Source control sounds cool, but what is branching?
Source control solves most, if not all, of issues arising from changes made to code. Whether that be incorrectly changing a unit test so it now fails, or a simple type.
However, what do you do when there are multiple features being worked on at the same time, by multiple different developers. One single version of the code quickly becomes a nightmare to manage.
You’ll be glad to know, there is an answer!
In the past 12 months, my love for source control has grown exponentially. The main reason? Branching!
So imagine you’re working on a new feature in your app when suddenly an urgent hotfix is required. What do you do?
Even with a basic source control system, you’d still be stuck with some partly committed code that isn’t tested. That leaves your urgent hotfix stuck behind some arbitrary new feature that may take weeks to ship.
That’s where branching comes in.
Branching allows teams of developers to easily collaborate inside of one central code base. When a developer creates a branch, the version control system creates a copy of the code base at that point in time. Changes to the branch don’t affect other developers on the team. Dan Radigan – Atlassian
Merging is simply the process of bringing two branches back together. You merge one branch back into another and in most cases, this will be a feature or hotfix branch back into a more main/long term branch. Hopefully, this is almost always seamless but can sometimes have its headaches.
Headaches caused by merge conflicts.
A merge conflict is if two or more developers have edited the same line of code in the same file. Git is pretty good at working things out for itself, but sometimes a little bit of human intervention is required.
- Merge errors in Visual Studio Code *
This message, or similar, will become the bane of your life There are tonnes of different strategies for branching and merging. Over the next few articles, I’m going to focus on a couple of methods that I have been trialing out recently within my organization.
A quick preface, currently we are a two-man team. The requirement for a branching and merging system isn’t probably quite as high as if you are Microsoft with 300+ devs.
That said, I’m a firm believer in setting a system up for where you want to be rather than where you are right now.
GitFlow is a strategy for managing Git repositories first proposed by Vincent Driessen. It determines how and when a new branch of code should be created, and how the merging back together of said branches should be managed.
Image taken from nvie.com
It includes new branches for features, bug fixes and any new releases. A ‘master’ branch is always kept current with the exact version of the software currently running in production. A development branch is always kept running and any new development work starts from here.
Release flow is the Microsoft model of branching, merging and releasing. It’s one I’ve only stumbled across very recently and I really like its simplicity. You can read much more about it here.
In basic terms, one ‘master’ branch is kept running at all times. Regardless of what the new code is (feature or hotfix), it is branched from master.
Master should always be clean, buildable and testable but not necessarily release ready.
A developer creates a new branch for the work they are doing, completes the work and then pushes back to the repository.
The code is then merged back into the master branch by way of a pull request. In simple terms, a pull request allows the control of the merging of code. Rules can be put in place to control who can commit. A build pipeline can even be started to pre-merge the changes and run a suite of tests.
Once a release is ready, a new branch is created from the master with a sensible name (release/v1.0.1). It is then pushed out to production.
Once no systems are still using an old version, the branch can either be deleted or archived.
Should you use branching and merging?
Even if you’re a one-man developer, working on your own personal projects, getting used to branching and merging is a great addition to your skillset.
When the command to create a new branch is as simple as
git checkout -b feature/mynewfeature
Then who can really decide it isn’t a good idea.
In the next couple of articles, I’m going to take a deeper dive into GitFlow and Release Flow and give my opinion on the pros and cons of both.