Choosing a Git Branching Strategy
There are several out there, and a lot of opinions to go with them. Having served in a consulting capacity for many organizations, ranging from small startups to very large enterprises, I have seen all of the major strategies. I've even seen organizations make up their own strategies in an attempt to fit their workflow or business needs. And here's what I have to share with you...
Trunk-Based Development is the way to go. I'm not saying your organization or team are ready to begin practicing it today, but I am saying that it is the most solid and fool-proof option for branching. In order to transition to this strategy, you will absolutely need to have a few things in place to prevent your team from tripping all over each other and having new features lost in the abyss. At a very minimum, you are going to need to implement and practice a few things:
- Feauture Flags (sometimes features aren't ready or tested and you don't want them to be used in production. This shouldn't prevent code from merging to master)
- Continuous Integration - All branches, pull requests, and merges are built and tested as soon as they occur.
- Continuous Delivery - A change on the primary git branch deploys to all environments in succession without manual intervention. Yes, even production.
- Tests. All the tests. Unit, Functional, Integration, and Acceptance at a minimum. These should prevent breaking changes from reaching production.
- Automated Rollbacks - If something happens to slip through the tests unnoticed, health checks should be invoked after a deployment (if possible). If the health check shows that the application is inoperable, then a rollback to the previous healthy version should immediately be invoked without manual intervention.
Yes, these things are going to take some time to implement. But what's the alternative? Sticking to the status quo? Choosing an option that doesn't accelerate your team's development as much so that your team can cope with process or tooling deficiencies? Harsh words? Yeah, probably ¯\_(ツ)_/¯
But what's at stake here? What are you really trying to gain? If you are just choosing a branching strategy, why would you pick one for where you are today? Do you have no aspirations for your team? Strive for something new and exciting! The switch to Trunk-Based Development brings with it new practices that will indubitably accelerate your delivery cadence and raise your software quality. You're not just choosing a branching strategy. You're choosing a better culture overall. Don't believe me? Try reading Accelerate. The research in that book proves it.
All in all, if you implement the practices I mentioned above, Trunk-Based Development will allow your team to thrive, and will also come with the least amount of drawbacks.
You have many alternatives. I'm not going to bother giving you the full explanations. I'll keep it brief.
Holy branches, Batman! This is a great branching strategy if you want to have branches that live for an eternity with stale code that is nearly impossible to merge back to master aside from manually picking out changes and reapplying them. If you are looking for a strategy that enables your team to waste time and accidentally lose or delete weeks worth of code, then this is it! Don't even give this strategy a second thought. For crying out loud, the guy who invented the strategy has even mentioned that you should adopt something simpler.
I'm not sure why they chose to give it such a similar name. It's just confusing. Nevertheless, GitHub Flow is the only other branching strategy that I can recommend without feeling guilty. It's incredibly similar to Trunk-Based Development with one very major difference – where code is built and deployed from. GitHub Flow deploys code changes from pull requests instead of the main branch. Why is that bad? Imagine that your pull request is complete and you deploy your changes. Now your colleague completes his PR and deploys his code to production. Suddenly, your code is not in production when you think it should be. With GitHub Flow, you are adding an extra layer of communication that must happen to orchestrate deployments and to ensure that your changes won't get stepped on before you are done testing them.
Also known as the release branching strategy, this approach can be a valuable approach when you need to bridge the gap until you have things ready for your transition to Trunk-Based Development. Don't stay here too long, though. This strategy encourages poor branching practices and enables changes to the software development workflow to fit an organization's operational processes, which is a big fat mistake. I wish I could tell you that it is, but unfortunately, your organization is not special.
Creating Your Own
Do I need to talk about this one? I once worked with a company that decided cherry-picking changes between branches was a better strategy than merging or using pull requests. They called me about a month later to help them untangle a complete disaster. You are not likely to come up with a better strategy than what already exists. Stick to what the community (and research) show to be the most effective.
I once had the pleasure of working with 12 summer internship developers, all on the same project. I have never seen a spaghetti monster as scary as their git graph was. I still have flashbacks. Along those same lines, I have worked with groups of professional developers who adopt differing approaches across a team. This unpredictability leads to chaos and confusion. You are bound to lose code or merge to the wrong place.
The Strategy of a Former Version Control System
This one still makes me laugh. I have seen developers move from Team Foundation Version Control (TFVC) to git and continue trying to use git in the way they used TFVC. They treat branches as if they are expensive and time-consuming. Or they clone two copies of the repository, check out different branches in each, and manually copy files between the two folders. If you're migrating to git, take the time to educate your developers. Don't let them fumble like this 😅
Trunk-Based Development is the #1 pick, but it takes some effort to get there.
GitHub Flow takes the #2 spot, but adds an annoying amount of orchestration between developers.
Release Flow is a slightly acceptable idea. It should only be used as a stepping stone on your way to Trunk-Based Development. Don't stick with it!
Gitflow was a good idea 12 years ago when a lot of desktop applications were still being developed, and development paradigms and processes were drastically different. Now, it's like an old shirt that just hangs out in your closet, because it's not acceptable to wear in public, but you just can't throw it away.
All Others - there aren't any other true contenders.
What you choose ultimately affects what your team and processes are capable of. If you want to be a high-performing software delivery team, on par with the best, then you need to use what the best are using. Research shows that Trunk-Based Development is the most effective and what the best of the best are using.