DEV Community

James Eastham
James Eastham

Posted on • Originally published at

Branching & Merging – Git Flow

If you missed part one of my series of articles on branching, merging and the general organization of git repositories; you can find it here

An Introduction To Git Flow

I’d used branching and merging in the past, but it had been a very manual process. Git Flow changed my life as far as the management of a repository goes. Previously, I was using commands like this:

git checkout -b my-new-branch
git add "mynewfile.txt"
git commit -m "Add mynewfile"
git checkout master
git merge my-new-branch

Whilst this is ok, it does get a little tedious sometimes.

Enter, GitFlow

GitFlow is a workflow design first proposed by Vincent Driessen at nvie. The general idea is that there is one central ‘truth’ repo. In most cases, and for the remainder of this post, that will be master.

From there, developers pull and push their changes to the master branch. Developers also may need to pull changes from other developers branches (if multiple people are working on the same feature for example).

Once a developer is finished working on a feature, it is pushed back to the master branch.

Simple, right?

Branch Strategy

The strategy for when and how a branch should be created is quite straightforward. There are two branches, that have an infinite lifetime.


The master branch should always be production-ready.

Always keep the master branch exactly mirroring the state of the current live system

Production releases are only made from the master branch, which keeps it perfectly aligned with any code that is currently in a live environment.

If using continuous delivery pipelines, you can trigger production releases every time a commit is made to master.


It’s easiest to think of the develop branch as a collection of all the features that are ready for the next release.

Any new features that are going to be added should be branched from develop, not from the master.

Which leads us quite nicely on to the three types of supporting branches.

Supporting Branches

There are three types of supporting branches that sit alongside the two core ones. These branches should have a finite life, meaning once work is completed the branch should be merged back to a core branch and deleted.


Feature branches are only ever branched from and merged back into develop. A feature branch should never directly relate to master.

There are probably grounds for an entire article on the naming convention of branches, but I tend to keep things nice and simple. Something like feature/description of feature.

I know a lot of bigger organizations also tend to add specific developer names to the branches, giving a branch name of jeasthamdev/feature/description of feature. If I was working in an environment with more than a couple of devs I would advocate this practice.


Hotfixes are an interesting one, as most of the time a hotfix needs to get to live quickly instead of waiting for the next release cycle. Because of that, hotfix branches are always branched from master.

When a hotfix is completed, it should be merged back into both master AND develop. This is a really important step. The merge into develop ensures that come the next release, the hotfix isn’t re-introduced into the system.


The release branch is best seen as a staging ground between develop and master.

When the decision is made to create a release, a branch is created from develop. This then allows for last-minute changes, documentation updates, version numbering and any final bug fixes needed before release.

By doing all this work on a release branch, it instantly clears the develop branch up for work on new features.

Once a release branch is ready to be pushed to production, it is merged back into both develop and master.

So that’s the boring theory done, now let’s see how this works on a day to day basis.

Git Flow – In Practice

Before getting started, there are an excellent set of tools Vincent himself put together that extend the standard git commands to support git flow. I’ll be using them for the remainder of this article, I’d highly recommend installing them as well.

To keep this article as git focused as possible, you can clone the sample repository I have put together here The repo contains an extremely simple and largely useless node.js REST API, the code itself is largely irrelevant for this article but it’s good to have something tangible to work with.

Once you have the repo locally, it’s time to initialize the git-flow tools. You can do that by typing

git flow init

When you enter the command, you’ll be asked a set of questions regarding the naming of branches and which branches you are going to use for master and develop. Accepting the defaults is fine in most cases.

Adding a new feature

So, we want to extend our useless REST API to have another completely useless feature, to return a list of numbers from 1-20.

git flow feature start numbersonetotwenty

Running the above command will create a new branch locally, named feature/numbersonetotwenty and check it out to be your active branch. We can then go off and make the changes we need to.

If you’re following along, you can edit the server.js file to be the following

var express = require("express");
var app = express();

app.get("/branches", (req, res, next) => {
res.json(["master", "develop", "features", "hotfix", "release"]);

app.get("/numbers", (req, res, next) => {

app.listen(3000, () => {
console.log("Server running on port 3000");

Now that we are finished working on the feature, we commit the change and finish the feature

git stage server.js
git commit -m "[FEATURE] Add numbers one to twenty endpoint
git flow feature finish numbersonetotwenty

This command will merge your changes back to develop, delete the feature branch and checkout the develop branch.

Releasing a feature

We now want to get our numbersonetotwenty feature out into production, but first, we need to update our documentation. To create a release branch, we run

git flow release start 1.1.0

I always like to name my release branches with the version number that the production release will become, but that’s personal preference.

Once we are finished making any release changes, we can run

git flow release finish 1.1.0

On running this command, the following things will happen:

The release branch will be merged into master
The master branch will be tagged with the name of the release branch
The release branch will be merged into develop
The release branch will be deleted locally
If you were using CI/CD pipelines, this would now trigger your live release.

But there’s a bug

The eagle-eyed among you may have spotted the bug I introduced in the addition of the feature, if you didn’t then I’ll show you the response from the GET /numbers endpoint and see if you can spot it.


So, let’s create a hotfix

git flow hotfix start fixnumbering

This command will create a new branch named hotfix/fixnumbering and check it out.

We can then apply the hotfix, namely replacing line 9 in server.js with the following


Now that I’m sure I can actually count, I can commit the change and complete the hotfix.

git stage server.js
git commit -m "[HOTFIX] Fix numbering"
git flow hotfix finish fixnumbering

Running ‘git flow hotfix finish fixnumbering’ runs a very similar set of steps to completing a release branch, namely, it will:

The hotfix branch will be merged into master
The master branch will be tagged with the name of the hotfix branch
The hotfix branch will be merged into develop
The hotfix branch will be deleted locally


So, that’s Git Flow in detail. Hopefully, you can see the real power of fully embracing a high-quality branching and merging strategy. Using the git flow specific tooling makes it even easier, a bit of a no brainer really.

If you have any experience using git flow, I’d love to hear about your successes and failures in the comments.

Next up in the series, a deep dive into the Microsoft model of branching and merging – Release Flow.

Top comments (0)