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.