Common Git Workflows

7 minute read

This article aims to expose a few of the approaches on how to work using workflows with git.

If you already work with git as the main version control tool, you may have seen several approaches on how to use and control branches in a production or personal setting.

And if you’re new to git, getting to know a bit about flows will help you become more familiar with how companies and open source projects often structure their workflows.

Git-flow is a model, a strategy that helps groups in versioning a project. Workflows make the maintenance of corrections and introduction of new features more organized and secure.

It is nothing more than a strategy created to improve the coordination of branches in a repository. This provides more fluidity to the process of adding new features and new releases.

The strategy is relatively recent. It was released to the world in 2010 by Vincent Driessen. Git is a code versioning model, where branches can be compared to other branches. That is, it is possible to see the model as something like a tree and its (literal) branches. If you have already used this versioning system, you have probably noticed that, in general, there is an origin branch, which will be referred as the main branch in this article, and it is the one that usually bridges the repository with the production server.

It is very common to see people using only one branch to commit to personal projects. This is not wrong, since it is very easy to control everything in a branch when developing alone, but the scenario changes a lot when we have to interact with more contributors, whether in an open source or private project.

As a way to prevent complications with the main branch, Git-flow brought a more robust solution, mainly for projects that grow in size and which are constantly changing, and also because of the number of people interacting with the repository.

In a project, for example, involving approximately 30 programmers, what would the project look like if everyone made their commits to the main? This might even be a valid strategy, but in conjunction with other strategies so that the team does not fall into the trap of putting something into production that is not fully tested.

At these times, it is extremely important to have total control of what is being produced by your team, since that, at the same time bugs are corrected, new features are being implemented and this whole process should not prevent production code to be fully delivered to the customer or the stakeholders.

In a more generic approach, it is common to use the main as the main branch of the repository, and whenever it is necessary to create a new feature or correct something, a new branch is created for each case. After the task is completed, the branch is merged with the corrections / new features, with the main branch.

The branch would, in this case, be a pointer to the specific commit.

Git-flow

In Git-flow, something similar happens, but with a slightly more complex structure, which can help a lot in the organization and productivity of a team.

We can separate Git-flow into 2 types of branches:

  • The main branches, which are the main, and develop.
  • Support branches, which are the feature, release and hotfix.

For each branch there are some rules and recommendations to be followed.

  • The main branch continues to bridge the release commits to production.
  • The develop branch contains all the stable features that will later be merged into a release branch.
  • It is only from the develop branches that feature branches are created. For each feature, a new branch is created.

The nomenclature for new branches has been standardized over time. For new features, for example, you may want to name: 'feature/feature-name'.

  • The feature branch will always be created from develop, and returned via merge to this one. Once incorporated, it can be removed.
  • After incorporating the new feature, it must be prepared to go into production. For this, another support branch is used, the release. It serves as a support to create a point where it should reflect what is expected from a next project release. In other words, it may occur that only after creating a set of new features, the team has a release ready. Once all the necessary features are ready in develop it will be possible to merge them into a release branch.
  • With the release ready to go to the main, it is time to create a tag, that is an indication where it will contain a new version of the project. This is done in the main branch, right after the merge.
  • Each merge done in the main must be done in the develop as well, to reflect the new tagged release. So, the branch Release can be removed.

This is a standard Git-flow. However, all projects are subject to unexpected production problems, or bugs. It is in this case that another support branch, the hotfix, appears. These have a very similar operation to the Release, with the difference that in this case, it is used for a more critical action. For this reason, when the hotfix is finished, the branch will be merged directly into the main branch. It also receives a tag in the main, after the merge, and the same must be done in the develop branch.

This way it is possible to keep developers working on their features, while hotfixes are created. Then the branch containing the hotfix can be removed.

This is a summary of how Git-flow works. The approach may seem a little far-fetched at first. But with a little practice, the team adjusts to it and the benefits appear.

Other Approaches

There are many other branch management approaches, which can fit perfectly into what you and your team need. Proposed by Github in 2011, for example, Github Flow has the advantage of easy understanding and simplicity in use. The motivation behind this approach is the speed in the deployment phase. As the original Git-flow is focused on releases, there are a series of steps to be followed until deployment. In the case of Github Flow, the application is integrated several times a day, in the form of small implementations.

A few characteristics of the Github Flow:

  • Anything in the main branch is deployable
  • To work on something new, create a descriptively named branch off of main (such as: new-feature)
  • Commit to that branch locally and regularly push your work to the same named branch on the server
  • When you need feedback or help, or you think the branch is ready for merging, open a pull request
  • After someone else has reviewed and approved the feature, you can merge it into main branch
  • Once it is merged and pushed to main, you can and should deploy immediately

Another strategy, released in 2014, is Gitlab Flow. Also a simplified version of the Git-flow proposed by Vincent, in the Gitlab Flow:

  • All features and fixes first go to main
  • It allows for production or stable branches
  • Bug fixes/hot fix patches are cherry-picked from main branch

In short, we learned how to control our branches by separating their responsibilities, without impacting on the main, which is where our stable code remains, and are identified with tags to version our releases and have a much more flexible control.

If you are interested in learning more about how to use Git-flow, I recommend reading Vincent’s original article. There is also an extension) created by git itself, to facilitate the process and thus simplify some steps.