The
best approach is to leave the Master branch as the latest stable
version of your repository and develop the branching system around it.
Git Flow [1] and
Branch Per Feature (BPF) [2] are two models based on this approach.
Git Flow
In 2010, a Dutch iOS developer, Vincent Driessen, published the
article Git flow. In this article, he presents how he sets up his branch
model. His branching strategy starts by creating two main branches:
The
master branch is the main branch of the project and will be
in the ready-for-production state. They are on the remote repository
(origin).
So, whenever you clone the repository on the master branch,
you will have the last stable version of the project, which is very
important.
The
develop branch reflects all the
new features for the next release. When the code inside the develop
branch is stable (this means that you have done all changes for the next
releases and tested it), you reach the stable point on the develop
branch. Then, you can merge the develop branch into Master.
Around these two branches, Vincent Driessen also used other branches that can be categorized into three types:
- Feature branches
- Release branches
- Hotfix branches
Feature branches

A feature branch is named based on what your feature is about and will
exist as long as the feature is in development.
Feature branches only
exist in local developer repositories; do not push them on the remote
repository.
When your feature is ready, you can merge your branch
feature to develop and delete the branch.
Execute the following steps:
- Go back to the develop branch;
- Merge the branch to develop by creating a new commit object;
- Delete the branch (the branch explains a feature that is now part of the develop branch, so there is no reason to keep it);
- Push your changes on the remote dev repository.
The steps described above can be made with the following git commands:
# step 1
$ git checkout develop
# step 2
$ git merge --no-ff featureBranch
# step 3
$ git branch -d featureBranch
# step 4
$ git push origin develop
Release branches
You
will use the release branch to update your code for minor changes
between two big releases. It's named the version number of the project.
At
this point, an example will be necessary to explain the process. Let's
imagine that we released our website and it is tagged as Version 1.0. We
are working on the next big release that will include a blog. While
developing your next great feature on a feature branch called "blog",
you have a minor bug on production. So, we create a release branch from
the dev branch, which we will name "release-1.1":
$ git checkout -b release/1.1 develop
We can fix this bug, but before releasing it, there is a tricky part. Fortunately, this is easy to understand.
First, you have to merge this branch release into master:
$ git checkout master
$ git merge --no-ff release/1.1
Then, you can tag your project to the new release version:
You will probably notice that your dev branch didn't include the changes!
To fix this, you have to merge it into the dev:
$ git checkout develop
$ git merge --no-ff release/1.1
When it's done, delete the release branch:
$ git branch -d release/1.1
Hotfix branches
These kinds of branches are very similar to release branches. It will respond to fixing a critical bug on production.
The goal is to quickly fix a bug while the other team members can work on their features.
For
example, your website is tagged as 1.1, and you are still developing
the blog feature on the blog branch. You find a huge bug on the slider
inside the main page, so you work on the release branch to fix it as
soon as possible.
Create a hotfix branch named:
$ git checkout -b hotfix/1.1.1 master
Fix the bug and merge it to master (after a commit, of course):
$ git checkout master
$ git merge --no-ff hotfix/1.1.1
$ git tag -a 1.1.1
Similarly, like the release
branch, merge the hotfix branch into the current release branch (if it
exists) or dev branch. Then delete it:
$ git checkout develop
$ git merge --no-ff hotfix/1.1.1
$ git branch -d hotfix/1.1.1
Branch Per Feature (BPF)
As mentioned earlier, Git flow might suit your project when you use a GitHub project, but the is not always the case.
This model was described by Adam Dymitruk in 2012. He tried to combine the power of Git with Continuous Integration.
He gave some tips for a more efficient branching strategy:
- Divide your project into several sprints.
- For each sprint, there are several features to develop.
- The
features should be small. Develop a small part of the feature, and for
each of them, create a dedicated feature branch. So, there will be a lot
of branches with few commits in it.
- Merge your branch to the dev branch when it's ready.
- Use
a Continuous Integration tool on a Quality Assurance branch so that you
will be notified sooner when something is wrong on your feature.
- When it passes the tests, your QA branch is merged into master and you just have to tag the new version.

Ideally every time you start a sprint, create the feature branches and QA.
The aim of this strategy is:
- All your work is split under feature branches.
- All feature branches start from master (from the last release). When
you start a sprint, you create your feature branches at the same time.
- Test your code sooner.
The QA branch is like the develop branch from Git flow; you shouldn't deploy it, but you have to recreate it on every release.
Links:
[1] Git Flow:
http://nvie.com/posts/a-successful-git-branching-model/
[2] Branch Per Feature:
http://dymitruk.com/blog/2012/02/05/branch-per-feature/