11 minute read

Git Workflows for Pros: A Good Git Guide

A Certified Scrum Master and lead full-stack developer with over a decade of experience, Joe's a Git pro, RoR veteran, and TDD enthusiast.

Git can support your project not just with version control, but also with collaboration and release management. Understanding how Git workflow patterns can help or hinder a project will give you the knowledge to evaluate and adapt your project’s Git processes effectively.

Throughout this guide I will isolate software development process patterns found in common Git workflows. Knowledge of these will help you find a direction when joining, creating or growing a development team. The pros and cons for certain types of projects or teams will be highlighted within the workflow examples we explore, so that you can pick and choose what might work well for your scenario.

This is not an introduction to using Git. There are fabulous guides and documentation for this out there already. You will benefit from this Git workflow guide if you already have experience within an application development team and have faced workflow snags, integration implosions or git-tastrophes - these patterns may shed some light on how to avoid those situations in the future.


In terms of Git process, collaboration is often about branching workflows. Thinking ahead on how you will intertwine commit trees will help you minimize integration bugs and support your release management strategy.

Integration Branch

This is the integration branch, a Git workflow for a team working towards a single entity deploying to production at the same time.

Use an integration branch with software development teams who work towards deploying a collection of contributions into production as a single entity. This is opposed to teams that focus on deploying features individually. Often teams may want to be doing the latter but practical limitations impose a process that groups their efforts, and the team ends up doing the former, so be sure to review your actual Git usage to see if you would benefit from using this type of collaboration pattern.

This workflow pattern is a useful staging point for when the risk of integrating multiple branches is high enough to warrant testing the combined contributions as a whole.

An integration branch usually consists of a major feature and several smaller contributions to be deployed together. Put an integration branch through your development team’s process (Q&A and acceptance testing, for example). Push minor commits onto it to bring it close to production ready, and then use an environment branch or release branch (discussed below) to prepare it for deployment.

Be aware that the contributions on the integration branch need to be merged into the next release stage before another major feature can be merged into the integration branch - otherwise you are mixing features at different stages of completion. This will inhibit your ability to release what is ready.

Topic Branches

Another Git workflow example is known as “topic branches.”

Teams will want to use topic branches if it is important to keep their commit trees in a state that can be easily read or have individual features reverted. Topic branches signify that the commits may be overwritten (using a force push) to clean up their structure and be shrunk down to a feature commit.

Topic branches are often owned by an individual contributor but can also be a designated space for a team to develop a feature upon. Other contributors know that this type of branch could have its commit tree re-written at any moment, and should not try to keep their local branches synchronized with it.

Without utilizing topic branches in your Git workflow you are restricted to sticking by the commits you push to a remote branch. Force pushing a new commit tree to a remote branch could anger other contributors who rely on the maintained integrity of the branch that they synchronize with.

Chances are that you use this workflow pattern already without realizing it, but it’s worth having a shared set of definitions amongst teams to reinforce the practices behind them. For example, you may find the convention of prefixing the branch name with the initials of the branch creator helps to signal which are topic branches. Either way, it’s up to your team to decide on internal conventions.

DO NOT use topic branches on public repositories, you cause a myriad of conflicts for anyone who has synchronized their local branches with a topic branch that has had it’s commit tree re-written.


The fork facilitates collaboration in your software development team’s Git workflow.

Open source projects thrive using this Github-originated feature. The fork empowers the repository maintainers with an enforced gateway over pushing directly to an origin repository branch, but more importantly it facilitates collaboration. Wahoo!

You may find yourself in the scenario where creating a fork of a private repository suits your needs too. Setting the origin repository to read-only for the contributors of the fork repository and rolling with pull requests gives you the same benefits that the open source community experience. Teams from different organizations can work effectively using a fork which can be the platform for communication and project policy adherence.

The fork workflow pattern gives teams their own space to work in whatever way they are used to with a single integration point between the two repositories - a pull request. Over communicating is imperative within the pull request description. The teams have had separate communication streams before a pull request has been issued, and highlighting the decisions that have already made will speed up the review process.

Of course one benefit of the fork workflow is that you can direct comments to contributors of the origin repository, as the permissions cascade downwards. From the point of view of the origin repository, you have the control to delete forks when they are no longer needed.

Make sure you are using a tool that facilitates forking and pull requests to take advantage of this pattern. These tools are not limited to Github: other popular choices are Bitbucket and GitlLab. But there are quite a few other Git workflow hosting services that will have these features (or similar). Pick which service works best for you.

DO NOT use a fork of a private repository for each member of a team. The numerous forked repositories can make it difficult for multiple members to collaborate on the same feature branch, and keeping all of these repositories in sync can become error prone due to the sheer number of the moving parts. Open source projects have core team members with push access to the origin repository that lessen this overhead.


The clone Git workflow has multiple seats on a project that co-contribute.

A common outsourcing strategy is to have contribution “seats” on a project that can be filled by multiple software developers. It’s up to the outsourcing company to manage their resource pipeline to deliver contracted hours, the issues they face are how to on-board, train and maintain a pool of their developers for each client’s projects.

Using a clone of the project’s repository lays out an isolated training and communication ground for the outsourced team to manage their contributions, enforce policies and take advantage of knowledge sharing - all out from under the watchful eye of the client’s development team. Once a contribution is deemed up to standard and ready for the main repository it can be pushed to one of the origin repositories remote branches and integrated as usual.

Some projects have high expectations for following their coding conventions and defined Git workflow standards to contribute to their repository. It can be daunting working in this environment until you have learnt the ropes, so work together as a team to optimize both parties’ time.

DO NOT create a hosted copy of the client’s repository without their permission, you could be breaking a contractual agreement, verify up front that this practice will benefit the project with the client.

Release Management

The steps between going from collaboration to release are going to start at different points within the development process for each team. Generally, you would not want to use more than one release management Git pattern. You want to have the simplest possible workflow that will enable your team to deliver effectively.

Environment Branches

Maintaining environment branches in Git is a simple and productive workflow pattern for software releases.

Your software development process may be supported by several environments to help with quality assurance before being deployed into production. Environment branches mimic the stages of this process: each stage corresponds to a branch, and contributions flow through these in a pipeline.

Teams running with these processes often have application environments set up for each stage in the pipeline, for example “QA”, “Staging” and “Production”. In these cases the infrastructure is in place to support personnel who are responsible for signing off a feature or contribution for their slice of what it means to be production ready (e.g. exploratory testing, QA, acceptance testing), before moving it onto the next person’s stage. This gives them their own place to deploy, test, and evaluate against their requirements, with a Git workflow to record its journey through the sign-off tunnel.

Having a branch for each stage of the process is OK for small teams that can work towards a release as a unit. Unfortunately, a pipeline like this can too easily bottleneck or bunch up and leave gaps. It couples your Git process to your infrastructure which can cause issues when feature demands ramp-up and both processes need to scale.

DO NOT use this pattern without considering the long term benefits of other patterns first.

Release Branches

A release branch Git workflow has a shorter lifespan than an environment branch and is destroyed after its commit tree is deployed to production.

A team that pushes a collection of contributions out to their production application as a unit in successive sprints can find release branches a favorable fit.

A collection of near “production ready” commits are given minor bug fixes on a release branch. Use an integration branch to combine and test the features before moving its commit tree onto a release branch. Limit the responsibility of a release branch to being a final check before deployment to the production application.

Release branches differ from environment branches in that they have a short lifespan. Release branches are created only when needed and destroyed after its commit tree has been deployed into production.

Try to prevent coupling release branches to your software development road map. Restricting yourself to following a pre-determined plan delays deploying a release until all of the planned features are production ready. Not assigning a version number to the roadmap before creating a release branch can alleviate these types of delays, by allowing the features that are production ready to be put onto a release branch and deployed.

Do use a version number naming convention for the release branch name to make obvious what version of the repository has been deployed into production.

Deploy the master branch and not the release branch. To encourage making minor fixes on release branches prior to merging with the master branch, use a Git hook on the master branch to trigger after a merge has happened to automatically deploy the updated commit tree into production.

Allowing only one release branch to exist at given moment in time ensures you will avoid the overhead of keeping multiple release branches in sync with each other.

DO NOT use release branches with multiple teams working on the same repository. Even though release branches are short lived, if the final checking of it takes too long then it holds up the other team from releasing. A team piggy backing on another team’s release branch is likely to introduce bugs and cause delays for both teams. Look at the timestamped release pattern below, which works better for a larger number and groups of contributors.

Timestamped Releases

 This workflow is a great solution for timestamped releases.

Applications with infrastructure restrictions commonly schedule their deployments during low traffic periods. If your project is faced with regular queues of features ready to be deployed then you may benefit from using timestamped releases.

A timestamped release relies on the deployment process to automatically add a timestamp tag to the last commit on the master branch that was deployed into production. Topic branches are used to put a feature through the development process before being merged into the master branch to await deployment.

The timestamp tag should include an actual timestamp and a label to indicate that it represents a deployment, for example: deployed-201402121345.

Including deployment meta-data, in the form of the timestamp tag within the commit tree of the master branch, will assist you in debugging regressions released into the production application. The person charged with hunting down the cause of the issue is unlikely to know a great deal about each and every line that is deployed into the production application. Running a git diff command on the last two tags can quickly give a snapshot of what commits were last deployed and who are the commit authors who could help resolve the issue.

Timestamped branches are more than they appear on the surface. A simple mechanism for recording a deployment of queued features requires a surprising amount of good process to drive it. The process is one that can scale and works well with a small team of contributors too.

For this Git workflow pattern to be truly effective it needs the master branch to always be deployable. That could mean different things for your team, but essentially all commits must have gone through your projects development process before ending up on the master branch.

New commits landing on the master branch are going to happen multiple times a day. This is an issue for topic branches that have been through the development process and have not been synchronized with the master branch during this time. Unfortunately such a scenario can introduce regressions into the master branch when merge conflicts are incorrectly dealt with.

If merge conflicts do arise between a topic branch and the master branch, then the risk of introducing a new bug should be discussed with your team before updating the remote master branch. If there is any doubt that a regression could occur then the topic branch can be put back through the quality assurance process with the merge conflicts resolved.

To reduce integration bugs, developers who are working on related parts of the repository can collaborate on when best to merge and synchronize their topic branches with the master branch. Integration branches work well to resolve conflicts from related topic branches too - these should be put through the testing process before being merged into the queue on the master branch pending deployment.

Software developement projects with many contributors have to deal with collaboration and release management processes with practical and efficient approaches. The additional meta-data on the commit tree we gain from using timestamped releases is a pointer to the foresight of the teams who are preparing to respond to production issues.

Version Branch

Use a version branch in your Git workflow to stay on the bleeding edge.

If you have a repository that you not only run in production but others use for their own hosted applications, then using version branches can give your team the platform to support users who do not, or cannot, stay on the bleeding edge of your application’s developments.

A repository using version branches will have one branch per minor version of the application. Major, minor and patch versions are explained within the Semantic Versioning documentation. Version branches typically follow a naming convention to include the word “stable” and drop the patch number from the application version: e.g. 2-3-stable to make their purpose and reliability obvious to end users.

Git tags may be applied down to the patch version number of the application, but version branches are not that fine grained. A version branch will always point to the most stable commit for a supported minor version.

When security patches or the need to backport functionality come along, put together the commits necessary to work for older application versions that you support, and push them to your version branches respectively.

DO NOT use version branches unless you support more than one version of your repository.


When your team changes size, or your project develops its processes through continuous evaluation, don’t leave out evaluating your Git process too. Use the patterns in this tutorial as a starting point to help direct you down the path of Git workflow righteousness.

The pattern in this guide can help to arm you with some foresight in adapting your distributed version control system to work for you. If you would like to read up on Git workflows be sure to check out Gitflow, Github Flow, and most importantly the amazing git-scm documentation!


it's useful! thx.
After reading your article, it seems to me that you've missed the most basic workflows that add the smallest complexity to your branching model. After a bit of searching, I've found a very short summary of some that I consider to be the basics. I hope that this adds to your listing: The workflows presented in the linked article are full workflows that do not discuss deployment and feature development separately, but look at your worklow as a whole.
Adam Bratt
What about rebasing?
Atikul Islam
Joe James
Thank you for reading and commenting, kudos to you! Those basic workflows are the foundations to my writing and application development experience, gotta share some love for those! :-) I do view integration, release management and deployment as having their own workflows after seeing many teams tripping up at these stages when applying these full featured workflows. Mixing and matching these smaller workflows has made it easier to find an efficient 'full' workflow that are a better fit for individual teams. If you had to highlight a part of the Git workflow for others to 'mind their step' for a certain scenario what would that look like for you?
Joe James
"Rebasing" is one of those words you can share with another developer who have felt the magic from it, and you get one of the spontaneous 'we are totally on the same wavelength' type of experiences :-) It was first on my list to write about, but I found that it was more of a technique that can be applied to many workflows rather than one in itself. It does feel a shame not to write about it :-( Are there any traps that you would want to highlight that you see people falling into when using rebasing regularly?
Joe James
Thanks for reading!
Mine would be to: keep it simple!
Thanks, that was an interesting insight.
Lubomír Štork
Great article, thank you. We're using "Release Branches" approach with huge success - it is extended a bit, with several rules for temporary branches and tags - What is the issue in long term is that it requires a lot of typing, and even with few powerful git/bash aliases in place, one have to think about order of steps (s)he needs to do. So, just like GitFlow from Vincent Driessen has its extension for Git at Github, we will opensource our extension soon too - here are slides with some screenshots how it works and looks like
Joe James
Amen to that! Thanks for starting a discussing, I love to hear what people think, criticism is always welcome - it is the start of knowledge sharing :-)
Joe James
Thanks for sharing the link to CakeDC workflow, I enjoyed reading through it! It looks like you have rolled with 'Environment Branches' to incorporate the QA process, but I can't see separate branches for the releases - but if tagging the master branch is an effective for you, then that's great! :-) Gitflow is great! I derived smaller patterns from it's workflow as I found their 'develop' branch a great feature, but often saw things get messy for projects for multiple teams or many individual contributors - the QA process was a contributing factor this the issues they faced.
Lubomír Štork
Right, we have no use for separate release branches as they're outlined by Vincent Driessen in his branching model, where release branch is getting bugfix updates... One of issues we successfully resolved with our approach is - separate not only qa process from development (which could start another milestone while previous one is in the qa) but also staging site, where are milestones previewed by the client (and stashed until new release is ready, because release can consist of 1-x milestones). It practically allows us to have 3 active (unreleased) milestones at once - one in development, one in qa, and one tagged and staged for client's preview. "When your team changes size, or your project develops its processes through continuous evaluation, don’t leave out evaluating your Git process too." Exactly. In reality, not every project needs stage, some (like small plugins) even don't have use for qa branch... So, our GitWorkflow extension uses ini file for its configuration, which is supposed to be committed to the repository - this is the main difference in compare to Gitflow from Github, as we wanted to be sure that every developer uses the same workflow configuration (which is not guaranteed by Gitflow's approach).
Lubomír Štork
"It looks like you have rolled with 'Environment Branches'..." Yes, sorry, s/Release/Environment
Joe James
Good quote! ;-) It would be nice to find where the sweet spot for applying the CakeDC workflow for a team or project is, sounds like you have that with your team now? If you doubled or tripled in size do you think you could extend the workflow to support the larger pipeline? When I ran with a team using Gitflow we used the gem to reduce typing (which is definitely an issue!) and to keep the team using uniform workflow usage.
Lubomír Štork
I'm not sure if it answers your question - our workflow does have some iron rules (--no-ff merges only, which permanent branch could be upstream for child temporary branches and how these are supposed to be named etc) and it is still flexible enough for other collaborative tasks like debugging and code review - see slide 6 of that GitWorkflow presentation, there are links to 3 blogposts I wrote about usage of our branching model in real life.
Great article. You can check this one too.. this o
Biju UI Developer: www.bijudes
Joe James
You are welcome :-)
Joe James
Fantastic Lubomir, thank you so much for sharing this, it's great to find out what works for yourself and others. I can see the benefits you have gained from going in this direction from the original workflow.
Joe James
Thank you for reading!
brendan murphy
Totally with Joe here, Rebasing is an implementation tool over a process. Release Branches, Management are a typical format for using rebasing effectively in a team env, and the stories features are in general time conflicting per developer, rebasing is a win. ``rebase -i remove all of the 4am "$*@-work" commits`` - better description of rebasing perhaps? :-)
Joe James
That is a most excellent definition of rebasing - THE main use case I would say ;-) However, my favourite part is the `-i` to leave out context switching to a GUI, which is wondrously productive. I roll with the `git add -i` for that reason too. At 4am I can't trust what I put into the commit tree, getting a visual is a must. Thanks for reading Brendan!
This article is... incredible! Most excellent.
Great article! I've linked it to a similar one I've written a while back that focuses on implementing the git flow with git commands:
Joe James
Thank you for reading and the kind words :)
Markus Stein
Hi! Interesting article! Any suggestions for good tooling which support those processes and ease the process? Like when accepting a deploy merge request (from staging to production) automatically create a corresponding tag... I'm already trying to check up with: * GitLab * GitHub (Enterprise) -- suggests first install in production, then merge back to branch * BitBucket * TFS But didn't find any more features than the standard ones * create branches * merge requests/pull requests with rights management * tag management * release management * git hooks * issue management (currently not needed at our place due to other tool) I saw BitBucket seems to have more events where hooking is possible. Even like GitLab EE - force that someone else checks the MR. But I miss some more helpful features: * create tags on deployment-merges in one step with merge * automatic creation of multiple merges (maybe with cherry pick) to get changes into RELEASE branch and automatically to i.e. MASTER/DEVELOP * remind user on old not-merged feature/dev/bugfix branches .. maybe other helpful features to ease the developer's daily work. We currently use GitLab CE.
comments powered by Disqus