The biggest difference between using Git, and other version control systems, is that Git is a distributed system, and in each copy of the repository, there is a full amount of code, so conflicts are common in collaboration. Let’s look at three Git development models.

git flow

git flow is part of the first generation of the git development process. It is divided into two branches, develop and master, where all development is branched on develop and then periodically merged into master. The master represents the production ready code. The main problem with this model is that the code needs to be constantly merged from the develop branch to master, so it is easy to miss.

  • checkout from develop when new features need to be developed, merge back to develop when development is complete
  • When a release is needed, checkout from develop and merge the release-* branch back to the develop and master branches respectively when the feature is stable.
  • When hotfix is needed, checkout from master. When the fix is complete, merge the hotfix-* branch back to the develop and master branches.

github flow

Github proposes the github flow, which simplifies the above situation. When you need to do anything, you checkout from master, do development, then commit PR, and finally merge it into master for release.

This model is particularly suitable for continuous deployment, because we assume that master is always the latest production ready code.

gitlab flow

Gitlab proposes their own flow. gitlab proposes two models.

Continuous Delivery Model

We branch by environment. For example, we usually have three environments: a development environment, a staging environment, and a prod environment.

When the code is ready, we checkout from master, deploy to staging, and when a hotfix is needed, we fix it in master and then cherry-pick it to the corresponding branch. When we release, we tag the corresponding commits.

Version release model

For example, for iOS applications, we usually have to do release operations, so the process suggests that when we want to do a release, we checkout from msater and cherry-pick to the corresponding release branch when there is a hotfix.


As mentioned above, we often need to pick or revert, and both of these operations can only operate on one commit at a time, and in PR we usually have more than one commit. I suggest turning on the squash merge option in Github, which will merge multiple commits in PR into one, so that when we need to do cherry-pick or revert, the operation will be very convenient.


In this article we introduced three git workflows, looked at how they each work, and finally we introduced squash so we can do cherry-pick and revert more easily.