Episode Transcript
Welcome to the deep dive.
Today we're getting into something really core to software development, how teams actually manage their code day-to-day, specifically branching.
Yeah, we're digging into some great material here from Marco Tulio Valenti's book Software Engineering a Modern Approach, focusing on Chapter 13.
Our goal?
To really breakdown the three big branching strategies you hear about all the time.
Get Flow, GitHub Flow and Trunk Based Development or TBD give you a quick way to grasp them.
And it really matters, you know, choosing the right strategy.
It's not just a technical footnote.
It shapes how fast you integrate changes, how often you run into those awful merge conflicts and, well, ultimately the quality you ship.
We're aiming for that aha moment for you, figuring out which fits where.
Exactly.
It's all about the trade-offs.
OK, let's unpack, starting with I guess the most established one, right?
Get flow.
This one goes back to Vincent Dreisen 2010.
I think For ages this was the way.
It's definitely the most structured.
Lots of moving parts, 2 permanent branches, 3 temporary ones.
It's got a whole system.
It really does.
Think of it like having 2 main arteries.
Those are the permanent branches.
First, there's main, sometimes called master or trunk historically, but Maine is common now.
This holds only code that's absolutely ready for production stuff you could deploy right now.
OK.
So Maine is the pristine ready to go version.
What's the second permanent one that that's where the active work happens?
That's it exactly.
That's the developed branch.
So if Maine is the finished product on the shelf, Develop is kind of like the workshop floor.
It collects all the features developers have finished, but before they've gone through, say, final QA testing.
Ah.
OK, so it assumes that testing phase often with a separate QA team maybe?
Often, yeah.
It reflects that more traditional pipeline where development hands off to QA.
Now the temporary branches are where the real action is how code moves between develop and main.
Let's break those down.
First up, feature branches, right?
Correct.
A developer wants to build something new.
They branch off, develop, they do their work, commit, commit, commit.
Well, locally maybe they're pushed.
It could be local sometimes Valenti mentions that, but usually push so others can see it.
Once the feature is done, they merge it back into develop and then poof, the feature branch is deleted, kept tidy.
OK, feature to develop.
What's next?
How does stuff get ready for like a release?
That brings us to release branches.
So the team looks at develop and says, OK, we've got enough good stuff here for version 2, point O, they cut a release branch from develop.
This branch is then specifically for stabilization.
Think bug fixing, final tweets, documentation updates, getting it ready for prime time.
This is often where that dedicated QA team really hammers on.
It right hardening it and when that release branch is finally approved, maybe by the customer or product owner, it doesn't just go to Maine, does it?
It goes two ways.
Exactly.
That's a key part of get flows structure.
Once it gets the thumbs up, it's merged into Maine.
That's your actual deployment trigger, and crucially, it's also merged back into develop.
Right back to develop.
Well, imagine you found a few small bugs during that final QA on the release branch and fixed them there.
You need those fixes back and develop so they're not lost and are part of the baseline for the next round of features.
Keeps everything in the sync.
Makes sense.
Okay, one more temporary branch.
What about emergencies like a critical bug hits production right now?
Yep, got to have an escape hatch.
That's the hot fix branch.
This is the dedicated path for those all hands on deck production fires.
If there's a critical issue on Main, you branch a hot fix directly from Maine.
Not from develop.
No, straight from Maine.
You put the fix commits onto that hot fix branch.
Then just like the release branch, it merges back two ways into Maine, often getting tagged immediately like version 1.0 point 1 and also back into develop so the fix isn't lost for future work.
Wow.
OK, so the full picture is future branches feed develop, develop gets bundled into release branches, release branches get approved and feed both main and develop, and hotfixes jump straight from Maine to fix emergencies, then update both main and develop.
You got it.
It's very methodical.
It sounds incredibly safe, very structured, ideal for situations where you have maybe strict regulations or mandatory customer sign offs before anything goes live.
Places where that multi stage process is necessary.
Definitely safety and predictability are the big wins.
But, and this is a big but, that very structure can cause its own problems and slow things.
Down here's where it gets really interesting.
The downsides you mentioned bottlenecks.
Developers often talk about merge hell with git flow.
What's that actually feel like for a team if my feature branch takes weeks to finish?
It's painful.
Technically it means if I branch off, develop and then develop, it's getting new features merged into it while I'm working away for 2-3 weeks, by the time I try to merge my branch back in disaster.
Conflicts everywhere.
Exactly Dozens, maybe hundreds of conflicts.
My code doesn't fit neatly anymore, so instead of shipping my feature, I'm spending hours, maybe days, just trying to untangle the mess, figuring out who's change should win.
It's incredibly frustrating and kills velocity.
So the elaborate branching designed for safety ironically creates huge integration friction, and that feedback loop must be slow too, right?
I finished my code, but I don't really know if it works in the bigger picture until much later when it finally hits a release branch and gets tested properly.
That's the other major drawback.
Delayed feedback.
You push your code, it goes into develop, but it might sit there for weeks before it's part of a release candidate that gets real scrutiny.
It slows down learning, slows down iteration if the cost of structure is constant, merge pain and slow feedback, well, people started looking for something simpler.
Which leads us nicely to GitHub Flow.
If git flow is the complex 5 branch beast, GitHub flow is like the minimalist response, way simpler.
Basically just main and feature branches, right?
They ditch develop, release, hotfix, all of that.
Pretty much, yeah.
It streamlines things dramatically, but the real innovation isn't just fewer branches, it's about when the quality checks happen.
GitHub Flow builds the review process right into the workflow before anything hits the main line, usually using pull requests or PRS.
The pull request.
That's the key mechanism here.
Absolutely.
It's designed around the kind of features you get in platforms like GitHub or GitLab or Bitbucket.
The PR is the focal point for discussion and approval.
So walk us through the steps for a developer using GitHub Flow.
It sounds much more linear.
It is super straightforward.
One, create a local branch for your feature or fix, give it a clear name.
2 Do the work, write the code, commit often.
3 Push that branch up to the remote server, like GitHub.
OK, code is push now what?
4 you open a pull request.
This is basically you saying hey team I've got this code it does X can someone please review it before we merge it?
Right, it's a formal request for scrutiny.
Exactly.
Then Step 5.
Someone else, a teammate, a lead, maybe even automated checks kick in, reviews the code in the PR.
They might ask for changes, discuss things.
Once everyone's happy and it's approved, then the code gets merged directly into the main branch.
Directly into Maine, so Maine is always potentially deployable.
That's the idea.
As soon as a PR is merged, Maine should be in a state where you could.
Deploy it.
Much faster cycle time potentially.
Who's this best suited for?
It's really common for web application systems where you generally only have one main version in production at a time.
You want to get changes reviewed and integrated into that deployable main branch quickly, without the ceremony of gitflow's release branches.
OK, but every system has trade-offs.
Gitflow's bottleneck was merge conflicts from long lived branches.
Where is the potential slowdown in GitHub flow?
It sounds like the review itself.
That's generally the main challenge, yeah.
The PR review process can become the new bottleneck.
If your reviewers are swamped, or if the team culture doesn't prioritize quick reviews, your code might sit waiting for approval for days.
So you've just shifted the delay from complex merges to human review cycles.
In essence, yes.
It solves one problem, but can introduce another if not managed well.
It requires A-Team culture that values fast, high quality reviews.
OK, so if git flow is structure and GitHub flow is review centric, there's one more model that takes simplicity and speed to the absolute extreme.
Trunk based development TBD.
This sounds like the simplest on paper.
Just one branch main.
That's it.
That's basically it.
TBD is all about keeping everyone working directly on or very close to the main line, the trunk.
It's less a specific set of branch rules and more a philosophy of continuous integration.
Think high frequency commits directly to Maine.
Multiple times a day even.
Ideally, yes.
It's the kind of approach used by places known for moving incredibly fast.
Like, you know, Google or Amazon are often cited examples.
Small changes integrated.
OK, but wait, if everyone's merging straight into Maine all the time, doesn't that sound incredibly risky?
How do you avoid breaking the build constantly?
Can developers still use feature branches at all?
They can, but here's the catch.
And Valente is really clear on this.
If you do use a branch in PBD, it has to be extremely short lived.
The rule of thumb often quoted is no more than two days.
Max two days?
What?
2 days?
What's magical about that number?
It's not magic, but it represents A threshold.
If your branch lives longer than a couple of days, it starts to drift significantly from the main trunk, which is evolving rapidly because everyone else is merging into it constantly.
Ah, so a three day branch is already becoming a a long lived feature branch.
Exactly, and that's the antithesis of TBD.
As soon as you have long lived branches, you reintroduce the risk of those massive, painful merge conflicts that TBD is specifically designed to avoid.
The whole point is small, frequent, easy integrations.
OK, so this demands extreme discipline.
If every merge is potentially one step away from production, you absolutely cannot afford to break things.
This sounds like automation doesn't just nice to have anymore, it's mandatory.
100% mandatory.
You cannot do TBD effectively without a rock solid comprehensive suite of automated tests, unit tests, integration tests, maybe even end to end tests.
These tests have to run automatically on every single proposed change before it gets merged into main.
They are your safety net.
Because there's no QA team waiting downstream like in Get Flow.
Right.
The automation is the primary QA gate.
This naturally leads teams doing TBD to embrace continuous integration or CI very heavily.
That's the practice of automatically building and testing every change, and often continuous deployment CD automatically deploying changes that pass all the tests.
So TBD and CICD are basically two sides of the same coin.
Very much so.
TBD is the development practice that makes true high frequency CICD feasible.
But what about bigger features?
Things that realistically take, say, A-Team several weeks to build?
You can't do that in two day branches.
How does TBD handle large initiatives?
Great question.
The standard technique here is using feature flags or feature toggles.
You break the massive feature down into tiny, manageable chunks.
Each tiny chunk can be built and merged into Maine within that short time frame, maybe even daily.
But the feature isn't finished yet.
You're merging incomplete code.
Yes, but you wrap that incomplete code in a feature flag.
Think of it like a runtime switch.
The code gets deployed to production with Maine, but the flag is initially off so users don't see the half finished feature.
Developers keep merging small pieces behind the flag.
Only when the entire feature is complete, tested and ready do you flip the flag on in production, making it visible.
Clever so you maintain the high integration frequency even for big projects just hiding the work in progress.
OK this paints a clear picture.
Get flow values that staged formal release process.
GitHub Flow values the pre merge review via PRS and TBD values sheer velocity and continuous integration, heavily relying on automation and techniques like feature flags.
That's a great summary and the choice between them really boiled down to your team's context.
What's your tolerance for risk?
How mature is your automated testing?
Do you need formal sign offs?
Get flow, Trust the process and QA.
Get help.
Flow trust the reviewer.
TBD trust the developer and the automation it.
Really dictates how your team operates.
So we've covered the structured world of Get Flow, the review focused GitHub Flow, and the fast-paced automation heavy trunk based development.
Yeah, and remember, these aren't just abstract diagrams.
They directly impact how quickly ideas turn into code that's actually running and delivering value.
It's about the flow of knowledge into production.
Thank you for joining us for this deep dive into software branching strategies.
