Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Git/GitHub branching standards & conventions

Branching

Quick Legend

Instance Branch Description, Instructions, Notes
Stable stable Accepts merges from Working and Hotfixes
Working master Accepts merges from Features/Issues and Hotfixes
Features/Issues topic-* Always branch off HEAD of Working
Hotfix hotfix-* Always branch off Stable

Main Branches

The main repository will always hold two evergreen branches:

  • master
  • stable

The main branch should be considered origin/master and will be the main branch where the source code of HEAD always reflects a state with the latest delivered development changes for the next release. As a developer, you will be branching and merging from master.

Consider origin/stable to always represent the latest code deployed to production. During day to day development, the stable branch will not be interacted with.

When the source code in the master branch is stable and has been deployed, all of the changes will be merged into stable and tagged with a release number. How this is done in detail will be discussed later.

Supporting Branches

Supporting branches are used to aid parallel development between team members, ease tracking of features, and to assist in quickly fixing live production problems. Unlike the main branches, these branches always have a limited life time, since they will be removed eventually.

The different types of branches we may use are:

  • Feature branches
  • Bug branches
  • Hotfix branches

Each of these branches have a specific purpose and are bound to strict rules as to which branches may be their originating branch and which branches must be their merge targets. Each branch and its usage is explained below.

Feature Branches

Feature branches are used when developing a new feature or enhancement which has the potential of a development lifespan longer than a single deployment. When starting development, the deployment in which this feature will be released may not be known. No matter when the feature branch will be finished, it will always be merged back into the master branch.

During the lifespan of the feature development, the lead should watch the master branch (network tool or branch tool in GitHub) to see if there have been commits since the feature was branched. Any and all changes to master should be merged into the feature before merging back to master; this can be done at various times during the project or at the end, but time to handle merge conflicts should be accounted for.

<tbd number> represents the project to which Project Management will be tracked.

  • Must branch from: master
  • Must merge back into: master
  • Branch naming convention: feature-<tbd number>

Working with a feature branch

If the branch does not exist yet (check with the Lead), create the branch locally and then push to GitHub. A feature branch should always be 'publicly' available. That is, development should never exist in just one developer's local branch.

$ git checkout -b feature-id master                 // creates a local branch for the new feature
$ git push origin feature-id                        // makes the new feature remotely available

Periodically, changes made to master (if any) should be merged back into your feature branch.

$ git merge master                                  // merges changes from master into feature branch

When development on the feature is complete, the lead (or engineer in charge) should merge changes into master and then make sure the remote branch is deleted.

$ git checkout master                               // change to the master branch  
$ git merge --no-ff feature-id                      // makes sure to create a commit object during merge
$ git push origin master                            // push merge changes
$ git push origin :feature-id                       // deletes the remote branch

Bug Branches

Bug branches differ from feature branches only semantically. Bug branches will be created when there is a bug on the live site that should be fixed and merged into the next deployment. For that reason, a bug branch typically will not last longer than one deployment cycle. Additionally, bug branches are used to explicitly track the difference between bug development and feature development. No matter when the bug branch will be finished, it will always be merged back into master.

Although likelihood will be less, during the lifespan of the bug development, the lead should watch the master branch (network tool or branch tool in GitHub) to see if there have been commits since the bug was branched. Any and all changes to master should be merged into the bug before merging back to master; this can be done at various times during the project or at the end, but time to handle merge conflicts should be accounted for.

<tbd number> represents the Basecamp project to which Project Management will be tracked.

  • Must branch from: master
  • Must merge back into: master
  • Branch naming convention: bug-<tbd number>

Working with a bug branch

If the branch does not exist yet (check with the Lead), create the branch locally and then push to GitHub. A bug branch should always be 'publicly' available. That is, development should never exist in just one developer's local branch.

$ git checkout -b bug-id master                     // creates a local branch for the new bug
$ git push origin bug-id                            // makes the new bug remotely available

Periodically, changes made to master (if any) should be merged back into your bug branch.

$ git merge master                                  // merges changes from master into bug branch

When development on the bug is complete, [the Lead] should merge changes into master and then make sure the remote branch is deleted.

$ git checkout master                               // change to the master branch  
$ git merge --no-ff bug-id                          // makes sure to create a commit object during merge
$ git push origin master                            // push merge changes
$ git push origin :bug-id                           // deletes the remote branch

Hotfix Branches

A hotfix branch comes from the need to act immediately upon an undesired state of a live production version. Additionally, because of the urgency, a hotfix is not required to be be pushed during a scheduled deployment. Due to these requirements, a hotfix branch is always branched from a tagged stable branch. This is done for two reasons:

  • Development on the master branch can continue while the hotfix is being addressed.
  • A tagged stable branch still represents what is in production. At the point in time where a hotfix is needed, there could have been multiple commits to master which would then no longer represent production.

<tbd number> represents the Basecamp project to which Project Management will be tracked.

  • Must branch from: tagged stable
  • Must merge back into: master and stable
  • Branch naming convention: hotfix-<tbd number>

Working with a hotfix branch

If the branch does not exist yet (check with the Lead), create the branch locally and then push to GitHub. A hotfix branch should always be 'publicly' available. That is, development should never exist in just one developer's local branch.

$ git checkout -b hotfix-id stable                  // creates a local branch for the new hotfix
$ git push origin hotfix-id                         // makes the new hotfix remotely available

When development on the hotfix is complete, [the Lead] should merge changes into stable and then update the tag.

$ git checkout stable                               // change to the stable branch
$ git merge --no-ff hotfix-id                       // forces creation of commit object during merge
$ git tag -a <tag>                                  // tags the fix
$ git push origin stable --tags                     // push tag changes

Merge changes into master so not to lose the hotfix and then delete the remote hotfix branch.

$ git checkout master                               // change to the master branch
$ git merge --no-ff hotfix-id                       // forces creation of commit object during merge
$ git push origin master                            // push merge changes
$ git push origin :hotfix-id                        // deletes the remote branch

Workflow Diagram

Git Branching Model
gitflow-model.src.key

@pradeepgmishra

This comment has been minimized.

Copy link

pradeepgmishra commented Aug 22, 2014

It would really help if we can give names to branches and those names get displayed in the branch list. When no of branches becomes larger it becomes difficult to know which branch contained what

E.G.
git checkout -b branch/0912013 "Branch for Adding More Graphs"
git checkout -b branch/0912012 "Branch for Table Analysis"

While running git branch, these names can be displayed for clarity

git branch:
branch/0912013 "Branch for Adding More Graphs"
branch/0912012 "Branch for Table Analysis"

@JonasDralle

This comment has been minimized.

Copy link

JonasDralle commented Dec 19, 2015

I love that Workflow Diagram

@spookiecookie

This comment has been minimized.

Copy link

spookiecookie commented Jan 18, 2016

Another syntax for deleting remote branch http://git-scm.com/book/ch3-5.html#Deleting-Remote-Branches .
git push origin :feature-id could be changed to git push origin --delete feature-id

@jgroesser

This comment has been minimized.

Copy link

jgroesser commented Jun 23, 2016

Hi, I have seen this diagram somewhere where all the git actions were annotated - anybody know where i can find it again ?

@giantas

This comment has been minimized.

Copy link

giantas commented Jul 1, 2016

very comprehensive 👍

@sfoulston

This comment has been minimized.

Copy link

sfoulston commented Jul 4, 2016

@jgroesser The diagram above was originally authored by Vincent Driessen (https://github.com/nvie) for his well known article about the gitflow branching model he conceived: http://nvie.com/posts/a-successful-git-branching-model/

@gauravkeshre

This comment has been minimized.

Copy link

gauravkeshre commented Sep 2, 2016

I have a doubt with the branch naming conventions
I created a branch today techdebt/app1/sept2/
and decided to create more specific fix branches from this branch as more than one developers are working on tech debt clearance
so I tried to create techdebt/app1/sept2/ticket-1

I get this error

fatal: cannot lock ref 'refs/heads/techdebt/app1/sept2/ticket-1': 'refs/heads/techdebt/app1/sept2/' exists; cannot create 'refs/heads/techdebt/app1/sept2/ticket-1'

what should I change here? to make it work?

@agrakhov

This comment has been minimized.

Copy link

agrakhov commented Sep 18, 2016

@gauravkeshre this seems to be known GIT issue, please check this:
https://coderwall.com/p/qkofma/a-caution-about-git-branch-names-with-s
As easy fix you can simply use this naming but with dashes instead of slashes.

@nishanthcs

This comment has been minimized.

Copy link

nishanthcs commented Dec 29, 2016

Great article!!. I wanna expose this content (copied) to my team in an internal wiki so that we can follow this approach (with a link to this page of course). What is the license to use this gist? .

@Eido95

This comment has been minimized.

Copy link

Eido95 commented Apr 24, 2017

Great article, thank you very much!

I would like to know, why do you name branches that their purpose is to fix a specific bug as bug and not as bugfix? is it really matters?
I think it is more consistent to use bugfix and hotfix rather than bug and hotfix, because semantically you understand that both bugfix's and hotfix's branches are created from the same reason - to fix issues.

@vjpr

This comment has been minimized.

Copy link

vjpr commented May 7, 2017

At present I just used fix for bugs and hotfixes, but after reading this gist I think its a good idea to use hotfix too - to make it easier to know which commits were hot.

@darkcyber

This comment has been minimized.

Copy link

darkcyber commented Aug 25, 2017

How to work parrelly with 2 or 3 teams? And there is development server n prod server.

Some times developer push while branch not updated, so it will return reject error. How to deal with this?

And what branch that development server should pull? Remote master? Pull or rebase?

And what branch that production server should pull? Remote stable? Pull or rebase?

Would you like to add real case tutorial?

Thanks in advance.

@Pr0methean

This comment has been minimized.

Copy link

Pr0methean commented Nov 9, 2017

What about a parallel-release branch, for when you need different simultaneous versions of the software for different environments? For example, https://github.com/Pr0methean/BetterRandom/tree/java7 is a permanent branch that receives merges from master (which is Java 8) and backports them for Java 7 and Android.

@oychao

This comment has been minimized.

Copy link

oychao commented Dec 12, 2017

Nice post, learned a lot, thanks.

@vijairaj

This comment has been minimized.

Copy link

vijairaj commented Jan 11, 2018

@Pr0methean did you figure out a flow for different simultaneous versions? I have a similar need.

@masonjamali

This comment has been minimized.

Copy link

masonjamali commented Feb 6, 2018

impressive, Thanks

@santuari

This comment has been minimized.

Copy link

santuari commented Feb 16, 2018

@darkcyber: I guess that you should update your local branches (master and/or stable) before pushing.

Said that I prefer to rebase my feature/bug/hotfix on top of the master before merging with --no-ff. So, that I can test my branch with the new changes of the master and the history of the feature/bug/hotfix merge will be cleaner.

// on the  feature/bug/hotfix branch
$ git fetch origin/master          //update the master
$ git rebase -i origin/master   //rebase on top of the master to incorporate the last changes
// test before merging
$ git checkout master                              
$ git merge --no-ff (feature/bug/hotfix branch)                    
$ git push origin master                            
...                   

What do you think? Do you foresee any issues?

@fermius

This comment has been minimized.

Copy link

fermius commented Aug 24, 2018

So useful, Thank you.

@Shashankreddysunkara

This comment has been minimized.

Copy link

Shashankreddysunkara commented Oct 10, 2018

Hello digitaljhelms, Merge my fork(https://gist.github.com/inusasunny/7a9391304ed657ccae77d9cf5abbc996.js) to your gist. I corrected the sentence that's it.

@albisserAdrian

This comment has been minimized.

Copy link

albisserAdrian commented Feb 21, 2019

Thank you for sharing!
Very insightful.

@digitaljhelms

This comment has been minimized.

Copy link
Owner Author

digitaljhelms commented Mar 4, 2019

Hello digitaljhelms, Merge my fork(https://gist.github.com/inusasunny/7a9391304ed657ccae77d9cf5abbc996.js) to your gist. I corrected the sentence that's it.

Thanks @Shashankreddysunkara I have made the correction.

@acrdlph

This comment has been minimized.

Copy link

acrdlph commented May 16, 2019

Very cool, thanks Jeremy

@aadesola

This comment has been minimized.

Copy link

aadesola commented Jul 18, 2019

Thank you very much for this, Jeremy.
I have a question, should branches continue to exist or there has to be a time when they have to be deleted. I'm currently facing some challenges with managing multiple branches.

@sanjiblamichhane

This comment has been minimized.

Copy link

sanjiblamichhane commented Jul 18, 2019

Nice explanation, thank you!

@henngelm

This comment has been minimized.

Copy link

henngelm commented Sep 4, 2019

@jgroesser The diagram above was originally authored by Vincent Driessen (https://github.com/nvie) for his well known article about the gitflow branching model he conceived: http://nvie.com/posts/a-successful-git-branching-model/

Cool. Thx!.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.