I was recently asked to do an evaluation of git-flow. Now there’s a mixed bag. Yes, they’ve tamed the chaos which always ensues with release branches in git projects. But they discourage what I thought were the fundamental rules of agile git:
- Thou shalt not break master.
- Thou shalt merge to master often.
If your only goal is rule #1, git-flow probably helps. But without rule #2, you don’t have the all-important rapid agile feedback loop and it sure looks like an anti-pattern.
Contrast this with github-flow which everyone I know seems to be using, even if we didn’t know that it had a name. You work on your feature, open a pull request, and when it’s good it’s merged to master. The github-flow document only actually mentions rule #1, but I’m pretty sure that’s because rule #2 is obvious, a corollary of rule #0 (also implicit):
- Thou shalt create wondrous things with computers.
It’s the tension between rule #1 and rule #2 which makes agile work. In doing #2, people might break #1. Well, these aren’t logical rules. The only sound way to obey rule #1 involves breaking rule #0. These are deontic rules (not quite as common in computing!), and they are simple saying that a community has to strive for both stability and innovation.
If you don’t accept rule #2, one of two things happens:
- Either people don’t merge often to a shared branch, you get big deviation and big new commits that are hard to review and represent major risk. (So either you end up breaking rule #1, or killing your velocity, or both.)
- Or people use a different “shared branch” to coordinate intermediate features; but inevitably this shared branch will have a lower threshhold for quality.
Either way, you become conservative and slow. Git-flows‘s “develop” branch is an example of the latter approach, but there’s a tautology there. If people don’t have the attitude that the develop branch must be usable, then a project is doomed to continual debugging, expecting that someone later will fix all the bugs allowed through the pull request gate. On the other hand, if people have the attitude that the develop branch must be usable, then why have it at all? Merge straight to “master”, after a pull request review.
What git-flow does well, however, is manage releases. In some universes you don’t need releases, and life there is glorious as Scott Chacon’s excellent article makes clear: “master” gets deployed immediately, unless it doesn’t compile or pass automated tests, in which case someone is shot or buys donuts depending on the severity.
But in most universes this isn’t possible. Maybe people have downloaded and installed your software, or compiled it in as a library, and understandably they want to do their own tests before slurping your upgrade. Of course agile has given them a new rule:
- Thou shalt upgrade often.
But we can’t enforce this on other people, and we can’t get away from having versions.
And despite all the hype, continuous delivery should not be the goal everywhere. In mission critical deployments, it’s absolutely right to have an extended QA process and with that rightly comes versioning.
This doesn’t mean we should abandon github-flow in favor of git-flow and it doesn’t mean we have to throw out rule #2 and agility. Big projects on GitHub have almost all developed techniques for solving this, including us in Apache Brooklyn. They’re all messy non-standard affairs, radically different incarnations of the Flying Spaghetti Monster with obscure noodly branches, and that is a problem. But the answer isn’t to abandon the one process attribute they have in common and which everyone expects: there is one place where the code action is, and that is the one true “master”.
Sure, it may be a bit of a hunt to find the code associated with the last release, but honestly that shouldn’t be a use case high on people’s list. People wanting the last GA release shouldn’t be looking at your git branches.
Sadly this means that the disciplined strategies git-flow introduced for working with releases have gotten lost. And it is a needless loss, as with a few simple renames — of git-flow‘s “master” branch to “production”, and “develop” to “master” — it fits neatly into github-flow and fixes release branching standardization.
Even better, someone has now formalized this: enter gitlab-flow. It’s relatively new (Sept 2014), by@sytses of @gitlab, but it seems to have all the benefits of git-flow without breaking the github-flow that we all know and love. Here’s hoping it’s as good as it seems.
If you have experience or opinions on gitlab-flow, please tweet me: @ahgittin