At BUZZWOO!, we manage our code using Git. Git is a free and open-source distributed version control system designed to handle everything from small to very large projects with speed and efficiency. It features things like cheap local branching, convenient staging areas, and multiple workflows.
In this article, I will get into branches, merge requests and flows. You will see, how these three topics are tightly related and work together.
Branches represent an independent line of development. They are an integral part of your everyday workflow when using Git. You can think of them as a way to request a brand new working directory, staging area, and project history.
Usually you create a new branch when you start working on a new functionality, and you merge it back with your main branch (the branch that holds the stable code) once you're done with it.
You are free to name your branches whatever you want.
At BUZZWOO! we have decided that the branches should always start with feature/ or hotfix/ if the functionality being written is a new feature or a bug fix.
This makes it easier to other developers to know what we are doing and why we are doing it.
We will keep the definition as simple as possible. We define a merge request as a way to submit a piece of code from a branch to another branch of the same repository. Merge requests can be more complicated and involve forks and other repositories, but we don't really need to cover these cases in this article.
How does it work?
When you start working on a new functionality, or a bug fix, the first thing you do is create a new branch with the command
git branch name-of-the-branch.
Then you make one or multiple commits and push the branch back to the repository.
Before merging your branch back to the main branch (usually the master branch), you open a merge request in Gitlab and choose the origin branch and the destination one. If you are using Github to host your code, the merge request is called a pull request.
Other developers can comment on your code via the Gitlab interface and you can make as many updates as you want to your code, until you're finally happy with your merge request.
You can then accept your merge request. This will merge your branch with the destination branch on the Git-repository.
Now that we have quickly explained what branches and merge requests are, (and I know, we've barely scratched the surface, but there are tons of tutorials on the Internet that will explain these functionalities better than us), we can talk about the two flows that we are using at BUZZWOO!: the Github Flow and the Git Flow.
Branching is a core concept in Git, and the entire GitHub Flow is based upon it. There's only one rule: Anything in the master branch is always deployable.
That is why it’s extremely important that your new branch is created off of the master branch when working on a feature or a fix. Your branch-name should be descriptive so that others can see what is being worked on. For example you can name it feature/refactor-authentication, feature/user-content-cache-key or feature/make-retina-avatars.
When you are done with your changes in the branch you have created, you start a merge request in Gitlab. The destination branch must be the master branch.
The other developers will review and discuss your code. You can also continue to add to your branch in light of discussion and feedback about your commits. If someone comments that you forgot to do something, or if there is a bug in the code, you can fix it in your branch and push up the change.
Once your merge request has been reviewed, it's time to merge your code with the master branch for deployment.
Once processed, merge requests preserve a record of the historical changes to your code. Because they're searchable, they let anyone go back in time to understand why and how a decision was made.
The Git Flow is more complex because it uses an extra branch called the develop branch. This means in the Git Flow, we use two main branches: the master branch and the develop branch.
The main branches
We consider origin/master to be the main branch, where the source code of HEAD always reflects a production-ready state.
We consider origin/develop to be the branch where the source code of HEAD always reflects a state that includes the latest delivered development changes for the next release. Some would call this the "integration branch". It is what any automatic nightly builds result from.
The feature branch must be created from the develop branch and be merged back with the develop branch.
Branch naming convention: anything except master, develop, release/* or hotfix/*.
Feature branches (or sometimes called topic branches) are used to develop new features for the upcoming or a distant future release. When starting development of a feature, the target release, in which this feature will be incorporated may well be unknown at that point. The essence of a feature branch is that it exists, as long as the feature is in development. It will eventually be either merged back with develop to definitely add the new feature to the upcoming release, or discarded in case of a disappointing experiment.
The release branch must be created from the develop branch and be merged back with both develop and master branches.
Branch naming convention: release/*.
Release branches support preparation of a new production release. They allow for last-minute small fixes, minor bug fixes and preparing metadata (f.ex., version number, build dates, ...). All targeted features for the release must be merged with develop. The version number is assigned at the start of a release branch.
The hotfix branch must be created from the master branch and be merged back with both, the develop and master branch.
Branch naming convention: hotfix/*.
When a critical bug in a production version must be resolved immediately, a hotfix branch may be branched off from the corresponding tag on the master branch that marks the production version. The essence is that work of team members (on the develop branch) can continue, while another person is preparing a quick production fix.
Using branches, merge requests and flows may seem like too much work that will slow down your company's development speed, but you will realize over the time that it will actually help you win time :
- Branches are a nice way of separating your work in progress from the stable code
- Merge requests force developers to interact, exchange information and talk to each other. They are also a good way to improve everybody's skills, as comments from other developers can only be beneficial to you.
- Flows are used to keep the work clean and make sure only stable code is being used. It also prevents you from mixing apples and oranges (features and hotfixes).