A successful git branching model

Time:2021-5-6

The first translation, light spray, if there are errors, please point out in the comments area, I will revise as soon as possible.

Here is the text


In this article, I’ll introduce the development model I introduced a year ago for some of my projects, including work projects and private projects. This model is very successful. I want to write this article for some time, but I haven’t had enough time to write it seriously. Now I have this opportunity. I won’t talk about any project details, just about branch strategy and release management.

A successful git branching model

Why git?

See this article for an in-depth discussion of the pros and cons of GIT over a centralized source control system. This often involves a lot of controversy. As a developer, I love git more than any other tool. I used to use the old CVs / subversion, and merging / branching has always been considered a bit scary (“be careful with merging conflicts, they bite”), there are things you just want to experience once.

But with git, these operations are very convenient and simple, they will become one of the core parts of your workflow. For example, in the CVs / subversion manual, branching and merging are first discussed in later chapters (advanced usage), while in each git manual, Chapter 3 (Basics) is introduced.

Because of its simplicity and repeatability, branching and merging are no longer terrible things. Version control tools should be more helpful for branching / merging than any other tool.

That’s all for the discussion of tools. Let’s go into development mode. The model I’m going to introduce here is essentially a set of processes that each team member must follow to enter a managed software development process.

Scattered but concentrated

The warehouse setup and branch model we used worked well, mainly because there was a “real” central warehouse. Please note that this warehouse is onlyAsCentral warehouse (because Git is a DVCS, there is no central warehouse on the technical level). We call this warehouseoriginBecause all git users are familiar with the name.

A successful git branching model

Every developer pulls and pushes code from the origin repository. However, in addition to the centralized push-pull relationship, each developer can also pull modifications from other peers to form a sub team. For example, it would be useful to work with two or more developers to develop a more complex new feature and push the ongoing work to the origin repository ahead of time. The picture above shows three sub teams: Alice and Bob, Alice and David, Clair and David.

Technically, it’s just that Alice defines a remote warehouse named Bob that points to Bob’s warehouse, and vice versa.

Main branch

In the core aspect, the development model is greatly inspired by the existing models. The central warehouse has two main branches with infinite life cycle.

  • master
  • develop

Every git user is familiar with the master branch of origin repository. Another branch parallel to the master branch is called thedevelop

A successful git branching model

We use origin / master as the main branch of source code for production.

The source code in origin / Master always represents the next release. Some call this the “integration branch.”. This is the place for any automatic nighttime build.

When the source code in the development branch reaches a stable point and is ready for release, all changes should be merged back into the main program in some way, and then marked with a release number. How to deal with it in detail will be further discussed.

Therefore, each time a change is merged into the master branch, a new production version is defined. At this point, we are very serious, so in theory, we can use git hook script to automatically build and roll back our software on the product server every time we submit the maser branch.

Auxiliary branch

Next, our development model uses various auxiliary branches to help team members develop in parallel, to facilitate the tracking of new features, to prepare for production release, and to help quickly fix existing online product problems. Unlike the main branches, these branches always have a limited lifetime because they will eventually be removed.
The different branches we may use are:

  • Feature branch
  • Release branch
  • Hotfix branch

Each branch has a specific purpose and must abide by strict rules, that is, which branches can be their starting branches and which branches must be their merging targets. We’ll see them in a minute.

From a technical point of view, these branches are by no means “special”. Branch types are classified according to the way we use them. They are still familiar git branches.

Feature branch

May be created in:

develop

Must be merged into:

develop

Branch naming convention:

Except for master, development, release - *, or hotfix - *

Feature branching (or sometimes called topic branching) is used for new features developed for upcoming or distant future releases. When you start developing a feature, you may not know the target version of the feature that will be merged at this time. The essence of feature branching is that features exist as long as they are in development, but they will eventually be merged back into the development branch (to ensure that new features are added to the upcoming release) or discarded (if the experiment is disappointing).
The feature branch only exists in the developer’s warehouse, not in the origin warehouse

Create a feature branch

$ git checkout -b myfeature develop
//Create and switch to the myfeature branch

Merge the completed features into the development branch

$ git checkout develop
//Switch to the "development" branch

$ git merge --no-ff myfeature
//Merge new features into the "development" branch

$ git branch -d myfeature
//Delete attribute branch

$ git push origin develop
//Push change

–no-ffMake the merge always create a new commit object, even if the merge can be performed through quickin. This avoids losing information about the existence of feature branch history, and organizes all submissions with added features together. Comparison:

A successful git branching model

In the second case, you cannot see from git history which commit objects implement the feature together, and you will have to read all log messages manually. In the second case, it’s really a headache to restore the whole function (that is, a set of commits), but it’s much easier to use — no FF.

Of course, this will result in some extra (empty) submissions, but the benefits are much greater than the costs.

Release branch

May arise from

develop

Must be merged into

Development and master

Branch naming conventions

release-*

The release branch supports the release of a new production version. They allow last minute modifications. In addition, they allow for minor bug fixes and version metadata preparation (version number, build date, etc.). By performing these actions on the release, development will be ready to release the next big release.

When the development version can reflect the features of the new version, it is a good time to separate the release branch from the development branch. At this point, at least the latest features built for the latest hairstyle version must be merged back into the development branch. All features for future versions don’t need to be merged – they have to wait until the release branch is detached before they can be merged.

You can name this version when you prepare a release branch. It doesn’t need to be too early. Until that moment, the development branch still reflected the change of the “next version”, but until the separation branch started, it was not clear whether the “next version” would eventually become 0.3 or 1.0. Determining the version number starts when a release branch is prepared, and is determined according to the rules of the project on the version number.

Create a release branch

The publish branch is created from the development branch. For example, suppose 1.1.5 is the current production version, and we are about to release a large version. The state of development is ready for the “next release,” and we have decided that it will be version 1.2 (not 1.1.6 or 2.0). So we exit the release and give the release branch a name that reflects the new version number:

$ git checkout -b release-1.2 develop
//Switch to a new branch, release-1.2

$ ./bump-version.sh 1.2
//File modified successfully, version 1.2

$ git commit -a -m "Bumped version number to 1.2"

After creating a new branch and switching to it, I change the version number. ad locumbump-version.shIs a fictitious shell script that can change some files in the working copy to reflect the new version (or manually – the key is that some files change), and then the bump version is submitted.

The new branch may remain for a while until the version is explicitly released. In the meantime, you can fix bugs in that branch, not in the development branch. During this period, it is strictly forbidden to add larger new functions. They have to be merged into the development branch and released in the next big release.

Complete a release branch

When the release branch is ready to publish, you need to do something. First of all, the release branch is merged into the master branch (because every submission of the master branch is a new version, be sure to remember). Next, the next commit on the master branch needs to be marked to review the historical version later. Finally, the changes made on the release branch need to be merged back into the development branch so that future versions will also include these bug fixes.
The first two steps in Git

$ git checkout master
//Switch to master branch

$ git merge --no-ff release-1.2
//Merge

$ git tag -a 1.2
//Tagging

Now the release is complete and tagged.

Suggestion: you'd better use '- s' or' - U < key > 'to encrypt and sign the tag

In order to save the changes made in the release branch, we need to merge it back into the development branch

$ git checkout develop
//Switch to the development branch

$ git merge --no-ff release-1.2
//Merge branches

This step can lead to merge conflicts (we may even change the version number as a result). If so, commit again after the repair.
Now that we’ve really finished the release branch, we can remove it because we don’t need it anymore.

$ git branch -d release-1.2
//Delete release-1.2 branch

Hotfix branch

May arise from

master

Must be merged into

Development and master

Branch naming conventions

hotfix-*

A successful git branching model

The hotfix branch is very similar to the release branch because it’s also for production, even though the hotfix branch is not planned. The reason is that there is a problem in the production version, which needs to be repaired immediately. When a serious bug is found in the production version, hotfix can be separated from the corresponding marked place on the master branch.

In essence, the work of team members (in the development branch) can continue, with another person preparing a quick fix.

Create hotfix branch

The hotfix branch is created from the master branch. For example, version 1.2 is the currently released production version, but it is unstable due to bugs. But the development branch is still changing and unstable. We need to isolate a hotfix branch and fix this problem

$ git checkout -b hotfix-1.2.1 master
//Create hotfix-1.2.1 and switch to the branch

$ ./bump-version.sh 1.2.1
//The version number is modified successfully

$ git commit -a -m "Bumped version number to 1.2.1"
//Submit branch

Don’t forget to add the version number at the end of the branch!
Then fix the bug in one or more commits.

$ git commit -m "Fixed severe production problem"

Complete hotfix branch

After completion, we need to merge the bug fix back into the master branch, but we also need to merge it into the development branch to ensure that the bug fix is included in the next release. This is similar to releasing the release branch.

$ git checkout master
//Switch to master branch

$ git merge --no-ff hotfix-1.2.1
//Merge branches

$ git tag -a 1.2.1
//Tagging
Suggestion: you'd better use '- s' or' - U < key > 'to encrypt and sign the tag

Next, merge the bug fix into the development branch

$ git checkout develop
//Switch to the development branch

$ git merge --no-ff hotfix-1.2.1
//Merge branches

There is an exception,When the release branch still exists, the hotfix branch needs to go to the release branch instead of the development branch. When the release branch is completed, the bug repair will be merged into the release branch, which will also include the bug repair into the development branch (if the development branch needs to fix the bug immediately and cannot wait for the release branch to complete, you can also merge the bug repair into the development branch safely).

Finally, remove the temporary branch

$ git branch -d hotfix-1.2.1
//Delete branch

summary

Although there is nothing really surprising about this branching pattern, the “big picture” at the beginning of this post is very useful in our project. It forms an elegant mental model that makes it easy for team members to understand the branching and publishing process.

Here is a high quality PDF version of the number. You can hang it on the wall at any time for quick reference.

Git-branching-model.pdf