Git-flow is a branching and merging methodology popularized by this blog post, entitled “A Successful Git branching model”.
In the last ten years, countless teams have been snookered by the headline and dare I say lied to.
If you read the blog post, the author claims they successfully introduced it in their projects, but purposefully doesn’t talk about the project details that made it successful.
And for the rest of us, this is mistake #1 of trusting the blog post. I’ll claim it as a truism that not all strategies work in all situations, with all people, in all contexts, and I apply that same logic to this branching model.
The end, right? Well, not quite. I can tell a few of you are unconvinced by this line of reasoning, so let’s dig deeper into why the gitflow branching model should die in a fire.
GitFlow Is Complicated On its Face
Even before you think about Microservices, or continuous delivery, gitflow is complicated. Take a look at this image and tell me it’s immediately intuitive:
So here you have feature branches, release branches, master, develop, a hotfix branch, and git tags. These are all things that have to be tracked, understood, and accounted for in your build and release process.
More so than that, you also need to keep track of what branch is what, all the time. The mental model you need to retain for this to be useful carries a high cognitive load. I’ve been using git for 10 years now, and I’m not even sure I’m at the point where I could mentally keep up with what’s going on here.
Gitflow violates the “Short-lived” branches rule
In git, the number of merge conflicts with people committing to a branch will increase with the number of people working on that branch. With git-flow, that number increases even more, because there are three other branches (of varying lifetimes) that merge into develop: Feature branches, release branches, and hot-fixes. So now the potential for merge-conflicts is not linear, it’s going to potentially triple the opportunities for merge conflicts.
No thank you.
While I hesitate to say “Worrying about merge conflicts” is a valid reason not to pursue a branching strategy like gitflow; the amount of potential complexity that is introduced when all these branches come together is too much to overlook. This would be fine if you have an organization with a low commit-velocity rate; but for any appreciable fast moving organization or startup, this won’t be the case.
Gitflow abandons rebasing
I recognize rebasing is a complex topic; but it’s important to this conversation. If you pursue gitflow, you’re gonna have to give up rebasing. Remember, rebasing does away with the merge commit — the point where you can see two branches coming together. And with the visual complexity of gitflow, you’re going to need to visually track branches, and that means no rebasing if you want to unwind a problem.
Gitflow makes Continuous Delivery Improbable
Continuous delivery is a practice where the team release directly into production with each “check-in” (in reality, a merge to master), in an automated fashion. Look at the mess that is gitflow and explain to me how you’re going to be able to continuously deliver *that*?
The entire branching model is predicated off a predictable, long term release cycle; not off releasing new code every few minutes or hours. There’s too much overhead for that; not to mention one of the central practices of CD is to roll-forward with fixes; and Gitflow treats hotfixes as a separate entity to be carefully preserved and controlled and separated from other work.
Gitflow is impossible to work with in multiple repositories
With the advent of Microservices; there’s been more of a push towards the idea of micro-repos as well (cue commenter shouting “they’re orthogonal to each other”), where individual teams have control over their repositories and workflows, and where they can control who checks in to their repositories and how their workflows work.
Have you ever *tried* a complex branching model like gitflow with multiple teams, and hoped for everyone to be on the same page? Can’t happen. Soon, the system becomes a manifest of the different revisions of the different repositories, and the only people who know where everything is at are the people pounding out the YAML to update the manifests. “What’s in production” becomes an existential question, if you’re not careful.
Gitflow is impossible to work with in a monorepo as well
So if micro-repos are out due to the difficulty in coordinating releases, why not just one big branching workflow that all the microservices teams have to abide by for releases?
This works for about 3.2 seconds, or the time it takes for a team to say “This has to go out now”, when the other teams aren’t ready for their stuff to be released. If teams are independent and microservices should be independently deployable, you can’t very well tie your workflow to the centralized branching model you created in your mono-repo.
Who should (and shouldn’t) use Gitflow?
If your organization is on a monthly or quarterly release cycle and it’s a team that works on multiple releases in parallel, Gitflow may be a good choice for you. If your team is a startup, or an internet-facing website or web application, where you may have multiple releases in a day; gitflow isn’t good for you. If your team is small (under 10 people), gitflow puts too much ceremony and overhead into your work.
If your teams, on the other hand, are 20+ people working on parallel releases, gitflow introduces just enough ceremony to ensure you don’t mess things up.
Ok, so my team shouldn’t use gitflow. What should we use?
I can’t answer that. Not all branching models work for all teams, in all contexts, and all cultures. If you practice CD, you want something that streamlines your process as much as possible. Some people swear by Trunk-based development and feature flags. However, those scare the hell out of me from a testing perspective.
The crucial point I’m making is to is ask questions of your team: What problems will this branching model help us solve? What problems will it create? What sorts of development will this model encourage? Do we want to encourage that behavior? Any branching model you choose is ultimately meant to make humans work together more easily to produce software, and so the branching model needs to take into account the needs of the particular humans using it, not something someone wrote on the internet and claimed was ‘successful’.
Author’s end note: I thought about using the ‘considered harmful’ moniker that is so common in posts like this; but then did a google search and realized someone else already wrote Gitflow considered harmful. That article is also worth your time.