IntroductionGit has become the de facto industry standard for version control systems in software development. You should first read my article about what Git is and how to get started. Have you read it? Excellent, let's get going! Like it or not, this tool created by Linus Tovalds is not going to retire. So, it makes sense to talk about how distributed teams work with Git and what branching strategy they should choose for this. This is not an inconsequential question. When assembling a new development team that has not worked together previously, the branching strategy is often one of the first things to decide. And some people will be foaming at the mouth to prove that one strategy is better than another. So, I want to convey to you some general information about them.
Are branching strategies necessary?They are indeed necessary. Very necessary. Because if the team doesn't agree on something, then each team member will do what he or she wants:
- working in whatever branch
- merging into arbitrary other branches
- deleting some branches
- creating new ones
- and so each team member will act in an unmanaged flow.
GitHub FlowThis branching strategy, oddly enough, is preferred on GitHub :) It comes with a set of rules:
- Code in the master branch must not be broken. It should be ready to be deployed at any time. That is, you must not put code there that will prevent you from building the project and deploying it to the server.
- When you plan to work on new functionality, you need to create a new feature branch based on the master branch and give it a meaningful name. Commit your code locally and regularly push your changes to the same branch in the remote repository.
- Open a pull request (you can read about pull requests here) when you think the work is ready and can be merged into the master branch (or if you are unsure, but want to get feedback on the work done).
- After the new feature in the pull request is approved, it can be merged into the master branch.
- When the changes are merged into the master branch, they should be deployed to the server immediately.
GitFlowThe previous strategy (GitHub Flow) is not very complicated at its core. There are two types of branches: master and feature branches. But GitFlow is more serious. At least, the picture above should make that clear :) So how does this strategy work? In general, GitFlow consists of two persistent branches and several types of temporary branches. In the context of GitHub Flow, the master branch is persistent and the others are temporary. Persistent branches
- master: Nobody should touch or push anything to this branch. In this strategy, master represents the latest stable version, which is used in production (that is, on a real server)
- development: The development branch. It could be unstable.
- Feature branches — for developing new functionality.
- Release branches — for preparing for the release of a new version of the project.
- Hotfix branches — for quickly fixing a bug found by real users on a real server.
Feature branchesFeature branches are created by developers for new functionality. They should always be created based on the development branch. After completing work on the new functionality, you need to create a pull request to the development branch. Clearly, large teams can have more than one feature branch at a time. Take another look at the picture at the beginning of the description of the GitFlow strategy.
Release branchesWhen the required set of new features is ready in the development branch, you can prepare for the release of a new version of the product. A release branch, which is created based on the development branch, will help us with this. When working with the release branch, you need to find and fix all bugs. Any new changes that are required to stabilize the release branch must also be merged back into the development branch. This is done in order to stabilize the development branch as well. When testers say that the branch is stable enough for a new release, it is merged into the master branch. Later a tag, which is assigned a version number, is created for this commit. To see an example, look at the picture at the beginning of the strategy. There you will see Tag 1.0 — this is just a tag that indicates version 1.0 of the project. And finally, we have the hotfix branch.
Hotfix branchesHotfix branches are also meant for releasing a new version to the master branch. The only difference is that those releases are not planned. There are situations when bugs get into the released version and are discovered in the production environment. Take iOS: as soon as a new version is released, you immediately get a bunch of updates with fixes for bugs that were found after the release. Accordingly, we need to quickly fix a bug and release a new version. In our picture, this corresponds to version 1.0.1. The idea is that work on new functionality doesn't have to stop when it is necessary to fix a bug on a real server (or as we say, "in prod" or "in production"). The hotfix branch should be created from the master branch, since it represents what is currently running in production. As soon as the bug fix is ready, it is merged into master, and a new tag is created. Just like prepping a release branch, a hotfix branch should also merge its fix back into the development branch.
Forking workflowIn the forking workflow, development involves two repositories:
- The original repository, into which all changes will be merged.
- A fork repository. This is a copy of the original repository, owned by another developer who wants to make changes to the original.
An example of the forking workflowThe forking workflow is applied on GitHub when there is a library that you want to use. It has a bug that prevents you from using it fully. Suppose you dive deep enough into the problem and know the solution. Using the forking workflow, you can fix the problem without rights to work in the library's original repository. To get started, you need to select some repository, for example, the Spring Framework. Find and click the "Fork" button in the upper right corner: This will take some time. Then a copy of the original repository will appear in your personal account, which will indicate that it is a fork: Now you can work with this repository as usual, adding changes to the master branch, and when everything is ready, you can create a pull request to the original repository. To do this, click the New pull request button:
Which strategy to chooseGit is a flexible and powerful tool that lets you work using a wide variety of processes and strategies. But the more choices you have, the more difficult it is to decide which strategy to choose. It is clear that there is no single answer for everyone. Everything depends on the situation. That said, there are several guidelines that can help with this:
- It's best to choose the simplest strategy first. Move to more complex strategies only when needed.
- Consider strategies that have as few branch types as possible for developers.
- Look at the pros and cons of the various strategies, and then choose the one you need for your project.