Welcome to End Point’s blog

Ongoing observations by End Point people

Git Workflows That Work

There was a significant blog post some years ago. It introduced a “successful” workflow for using Git. This workflow was named Gitflow. One of the reasons this blog post was significant is that it was the first structured workflow that many developers had been exposed to for using Git. Before Gitflow was introduced, most developers didn’t work with Git like that. And if you remember when it was introduced back in 2010, it created quite a buzz. People praised it as “the” way to work with Git. Some adopted it so quickly and full heartedly that they dismissed any other way to use Git as immature or childish. It became, in a way, a movement.

I start with this little bit of history to talk about the void that was filled by Gitflow. There was clearly something that drew people to it that wasn’t there before. It questioned the way they were working with Git and offered something different that worked “successfully” for someone else. I supposed many developers didn’t have much confidence or strong feelings about their use of Git before they heard of Gitflow. And so they followed someone who clearly did have confidence and strong feelings about a particular workflow. Some of you may be questioning your current Git workflow now and can relate to what I’m describing. However, I’m not going to prescribe a particular workflow for you as “the” way to do it.

Instead, let’s talk about the purpose of a workflow. Let’s reword that so we’re clear- the purpose of a software development workflow using Git. What is the purpose? Let’s back up and ask what is the purpose of software? The purpose of software is to help people. Period. Yes it can help servers, and networks, and robots, and telephones, etc. But help them do what? Help people. They are tools to help us (people) do things better, faster, simpler, etc. I submit to you that the purpose of a software development workflow using Git should be the same. It should help people release software. Specifically, it should help match the software development process with business expectations for the people responsible for the software. That list of people responsible for the software should include more than just the developers. It also includes operations engineers, project managers, and certainly business owners.

Does your Git workflow help your business owners? Does it help your project managers or the Operations team? These are questions you should be thinking about. And by doing so, you should realize that there is no “one size fits all” workflow that will do all that for every case. There are many different workflows based on different needs and uses. Some are for large complex projects and some are extremely simple. What you need to ask is- what will best help my team/project/organization to develop, release, and maintain software effectively? Let’s look at a few workflow examples and see.

GitHub Flow

GitHub’s own workflow, their internal workflow, is quite different from what everyone else does who uses GitHub. It is based on a set of simple business choices:

  • Anything in the master branch is deployable
  • To work on something new, create a descriptively named branch off of master (ie: new-oauth2-scopes)
  • 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 signed off on the feature, you can merge it into master
  • Once it is merged and pushed to ‘master’ on the origin, you can and should deploy immediately

They release many times per day to production using this model. They branch off master for every change they make, hot fixes and features are treated the same. Then they merge back into master and release. They even have automated their releases using an irc bot.

Skullcandy’s workflow

When I worked for Skullcandy we used a workflow loosely based on the GitHub Flow model, but altered a bit. We used a Scrum Agile methodology with well defined sprints of work and deliverables at the end of each sprint. The workflow followed these business choices:

  • A userstory or defect in our tracking system represented a single deliverable, and a Git branch was created for each userstory or defect. We used a naming convention for branches (skdy/schristensen/US1234-cool-new-feature, for example). Yes, you can use ‘/’ characters in branch names.
  • Everything branches off master. Features and hot fixes are treated the same.
  • After code review, then the branch was merged into a QA branch and deployed to the QA environment where business owners tested and approved the changes.
  • The QA branch is just another branch off master and can be blown away and recreated when needed at any time.
  • We released once a week, and only those changes that have been approved by the business owners in QA got merged into master and released.
  • Since branch names and items in our issue tracking system were tied together we could easily verify the status of a change, the who, when, and what, and why of it, and even automate things- like auto merging of approved branches and deployment, auto updating tickets in the tracking system, and notifying developers of any merge issues or when their branch got released.

Master only workflow

Not every team or project is going to work like this. And it may be too complicated for some. It may be appropriate to just work on master without branching and merging. I do this now with some of the clients I work with.

  • Each feature or hot fix is worked on in dev environment that is similar to production, that allows business owner direct access for testing and approval. Changes are committed locally.
  • Once approved by the business owner, commit and push changes to master on origin, and then deploy to production immediately.

You may not be working for a business, and so the term “business owner” may not fit your situation. But there should always be someone who approves the changes as acceptable for release. That person should be the same one who requested the change in the first place.


On the other end of the spectrum from a master only workflow, is Gitflow. Here there are at least three main branches: develop (or development), release, and master. There are other branches as well for features and hot fixes. Many of these are long running. For example, you merge develop into the release branch but then you continue working on develop and add more commits. The workflow looks like this:

  • All work is done in a branch. Features are branched off develop. Hot fixes are treated different and are branched off master.
  • Features are merged back into develop after approval.
  • Develop is merged into a release branch.
  • Hot fixes are merged back into master, but also must be merged into develop and the release branch.
  • The release branch is merged into master.
  • Master is deployed to production.

Backcountry workflow

When I worked for we used a similar workflow, however we used different names for the branches. All development happened on master, feature branches were branched off and then merged back into master. Then we branched master to create a new release branch. And then we merged the release branch into a branch called “production”. And since master is just a branch and doesn’t have to be special, you could use a branch named whatever you want for your production code.


There are many other examples we could go over and discuss, but these should be enough to get you thinking about different possibilities. There are a few guidelines that you should consider for your workflow:

  • Branches should be used to represent a single deliverable request from the business- like a single user story or bug fix. Something that can be approved by the business that contains everything needed for that single request to be released- and nothing more!
  • The longer a feature branch lives without getting merged in for a release, the greater risk for merge conflicts and challenges for deployment. Short lived branches merge and deploy cleaner.
  • Business owner involvement in your workflow is essential. Don’t merge, don’t deploy, don’t work without their input. Otherwise pain and tears will ensue (or worse).
  • Avoid reverts. Test, test, test your branch before a merge. When merging use git merge --no-ff, which will ease merge reverts if really needed.
  • Your workflow should fit how you release. Do you release continually, multiple times a day? Do you have 2 week sprints with completed work to release on a regular schedule? Do you have a business Change Control Board where all released items must get reviewed and approved first? Does someone else run your releases, like the Operations team or a Release manager? Your branching and merging strategy needs to make releasing easier.
  • Complicated workflows drive people crazy. Make it simple. Review your workflow and ask how you can simplify it. In actively making things more simple, you will also make them easier to understand and work with as well as easier for others to adopt and maintain.

These should help you adjust your software development workflow using Git to fulfill its purpose of helping people. Helping you.

Further Reading

There is a lot more you can read about on this topic, and here are several good places to start:


Srđan Šrepfler said...

Scullcandy the headphones company uses git?

Spencer Christensen said...

Hi Srđan. Yes, indeed they do! I worked for them managing server architecture and doing release management for their websites.

Mark Haller said...

git --help workflows

Why is that never discussed? I actually prefer the naming in git flow, but there are some interesting thoughts in there, like always merge upwards.

I also don't understand how github deals with regression. They can't be merging all these branches and not introducing bugs. I assume their tests are so automated and fast, that they can push so often with such confidence.

Spencer Christensen said...

Hi Mark. Thanks for pointing out git --help workflows. I actually wasn't aware of that. I've read through it now and I agree the naming in there is a bit confusing.

One thing that I clearly noticed was that the workflow they describe is used for git itself. So unless you plan to help contribute and work on the git source code, take their recommendations with a grain of salt when applying to some other project. Although, I do think that some of their points are good general guidelines for most projects. For example- create your feature/topic branches off of the oldest branch that you intend to merge back into (meaning, branch off master if you intend for your changes to end up being merged back into master for deployment). I also agree that feature/topic branches should be kept separate from integration branches, and that they are individually merged into testing and release branches (like master)- instead of merging a bunch of features into a common branch and then merging *that* common branch merged into master. Doing it this way limits the risk of changes being deployed that are not ready.

As for GitHub's workflow- I can't say how they test and deal with regressions. I would certainly hope they do regression testing before merging into master and deploying. However, one of the advantages of their very simple workflow is that it is quite easy to revert the latest change or to quickly deploy a fix.

4SN said...

Hi Mark,
In the Git flow, release branch it is branched off from develop. What I don't quite understand is that, develop has lot of on-going development activities. Some of which, for example we want to cut release 1.2, introduce code that is meant for much later release (1.3 and could be 1.4) due to continuous development. Would the release that we are creating 1.2 already be polluted right at the beginning?

I must be missing something very basic here?

4SN said...

Sorry, my question above was meant for Spencer :(. However, I appreciate anyone who could shed some light for me as I am fairly new to Git.


Spencer Christensen said...

Hello 4SN.

Gitflow does has some good points to it, but as you point out there is certainly the possibility that code that is not yet ready for production gets included in a release accidentally. This can be a major problem or it can be an acceptable risk. It all depends on your project and your release management.

When I worked at Backcountry, we had well known schedules for releases and for code reviews to help reduce the chances of something getting in that wasn't ready to go out. Every feature branch was peer-reviewed and tested and approved by a business owner before it got merged into the development branch and then subsequently included in the next release. So we had processes and expectations of each developer to follow to help solve the problem. But that was no guarantee to stop it from happening, it still did every once in a while- and that was "an acceptable risk" that we all knew could happen.

There are other things you can do to try to solve this problem, but in my opinion they add more process and overhead to a release workflow that is already complicated. Instead of trying to add more safety checks and more reviews and meetings and on and on, I'd recommend looking at something like the Github Flow or the Skullcandy workflow which keeps all branches in isolation until deployment. That way you can test and approve changes individually- and keep out changes that are not ready for release.

As I said in the blog post above, the point of your git workflow should be to help you release your software (safely, timely, etc.). So that is more important than following Git Flow "the right way" or any other recommendation. And if your process is too complicated, then that is a red flag that you should make changes to simplify it.

Best of luck!

Marnen Laibow-Koser said...

"GitHub’s own workflow, their internal workflow, is quite different from what everyone else does who uses GitHub."

Really? I've been using this workflow for a long time, on many projects, without knowing that GitHub used it internally.

Stijn Herreman said...

Our team is looking to use a workflow similar to the Skullcandy workflow. The major difference is that we'd have 3 QA branches and they are to be permanent; after a feature branch was merged to the first QA branch and approved, the feature can be merged to the second QA branch, and so on, until they are approved for merging to master.

Ideally, when all feature branches have gone to all QA branches and to master, the QA branches and master branch are identical. However, mistakes could happen during merge conflicts, for example. Should we periodically merge master to the QA branches, as a safeguard/verification?