CAMPUX Cloud Bootcamp Phase Three · Class Nineteen
Phase Three — DevOps Core
Reading 38 min · Drills 6 · 2 Labs
Aligned to AZ-400
Class Nineteen

Branching strategies

Every team argues about how branches should flow, and the argument is rarely about Git — it is about how often you dare to ship, which is the number that quietly decides how the whole team works.

§1

The question every team fights about

You now know how to make a branch and how to guard main. The next question is one every team argues about, sometimes bitterly: how should branches be arranged over time? When do you cut one, how long does it live, and how does its work reach production? This is a branching strategy — a team's agreed convention for the shape of its history — and there is no shortage of dogma about it. The trap is treating it as a matter of taste or seniority. It is neither. It is a consequence of one number.1

Branching strategy
A team's shared rules for how branches are created, how long they live, and how their work is integrated and released. Not a Git feature — a social contract the tooling then enforces.

The number is deployment frequency: how often the team actually ships to production. A team that releases once a quarter has different needs from one that ships thirty times a day, and almost every honest disagreement about branching dissolves once you ask that question first. The two strategies this class compares — GitFlow and trunk-based development — are not good and evil; they are answers to different deployment frequencies, and choosing between them by fashion instead of frequency is how teams end up fighting their own process. Get this right and branching becomes invisible, the way it should be. Get it wrong and the strategy itself becomes a daily tax on everyone.

§2

GitFlow: what it solved in 2010

In 2010 a developer named Vincent Driessen published a branching model that became so popular it got a name: GitFlow. To understand why it looks the way it does, remember the world it was born into. Software shipped on a schedule — versioned releases, every few weeks or months, often installed by customers rather than deployed by you. In that world you needed somewhere to stabilise the next release while ongoing work continued, and somewhere to patch the version already in the wild. GitFlow gave each of those a long-lived branch.

main
Holds only released, tagged versions — the history of what actually shipped.
develop
The long-lived integration branch where finished features accumulate between releases.
feature/*
One per feature, branched off develop and merged back when done — often living for weeks.
release/* and hotfix/*
A branch to stabilise the next version, and a branch to patch the current one in production.

For its moment, this was genuinely good engineering: it gave a versioned, ship-it-in-boxes product a clear place for every kind of work. But look at what it costs. Feature branches live long, so they drift far from develop and merge back in painful, conflict-heavy heaves. There are five kinds of branch to keep straight and a ceremony for moving between them. All of that friction is the price of decoupling "written" from "released" — and that price only makes sense if you release rarely. The moment your team wants to ship every day, GitFlow's careful machinery becomes the thing slowing you down.2

§3

Trunk-based: the straight line most cloud teams run

The modern default for teams that deploy often is almost the opposite of GitFlow. In trunk-based development there is one long-lived branch — the trunk, usually main — and everyone integrates into it constantly. You still use branches, but they are short-lived: a branch cut this morning, opened as a PR, reviewed, and merged back the same day. Nothing is allowed to drift for weeks. The trunk is kept releasable at all times, and shipping is a matter of deploying the trunk, not of merging a pile of aged branches together.

Figure 11: two branching strategies side by side. On the left, GitFlow, with several long-lived lanes — main, develop, and feature branches — whose merges tangle together, with a red pen circle around a knot of conflicting merges. On the right, trunk-based development, a single straight trunk with small short-lived branches that pop off and merge back almost immediately. GitFlow — long-lived lanes main dev merge conflicts pile up Trunk-based — one line trunk always releasable
Figure 11 The same work, two shapes. GitFlow's long-lived lanes decouple "written" from "released," but the longer a branch lives the further it drifts, and the merges knot together where the red pen circles. Trunk-based keeps one line and lets branches live only hours, so integration is small and constant instead of large and dreaded. Neither is wrong — but only one stays sane when you ship every day.

Why does short-lived win for cloud teams? Because the pain of merging grows with the age of a branch, and trunk-based simply refuses to let branches get old. Small, frequent integrations mean small, frequent conflicts — the kind resolved in a minute, not a war. It leans hard on the machinery you already have: a protected trunk, required reviews, and automated checks on every PR, so that constant integration does not mean constant breakage. Feature flags do the rest, letting unfinished work sit merged-but-hidden on the trunk rather than marooned on a branch.3 The whole approach is built for the team that deploys many times a day and cannot afford a merge ceremony each time.

§4

Releases and environments

"Ship the trunk" raises an obvious question: ship it where, and how do you gain confidence before it reaches customers? The answer is not more branches — it is more environments. Instead of a develop branch to stabilise on, a modern team promotes the same build through a sequence of running environments, and the trunk stays the single source of truth.

Table 1 — Two ways to reach production
GitFlow-styleTrunk + environments
Where work stabilisesOn a long-lived branch (develop, release/*)In running environments (dev → test → prod)
What differs between stagesDifferent branches of codeThe same build, different config
How a fix reaches prodMerge across branches, in orderMerge to trunk, promote the build forward
Failure modeBranches drift; merges rotA bad build is caught in an early environment

The distinction to hold is promotion, not re-branching. A change merges once to the trunk, produces one artifact, and that same artifact is deployed to dev, then to a test or staging environment, then — behind an approval gate — to production. The code does not change as it moves; only the environment it runs in and the configuration it reads do. Some teams keep a thin release/* branch for a slower cadence or a supported version, and that is a legitimate hybrid — but the everyday flow is trunk to artifact to environments. This is exactly the shape Build III will construct: a pipeline that deploys the trunk to non-prod on merge and waits for a human to approve production. Environments, not branches, are where release confidence is earned.

§5

Choose by frequency, not ideology

Now the decision, made honestly. You do not pick a branching strategy because it is "enterprise" or "what Google does" — you pick it by asking how often your team ships, then working backward.

Choose by frequency, not by fashion.

Ship many times a day
Trunk-based with short-lived branches and environment promotion. Long-lived branches would knot; you cannot afford a merge ceremony per release.
Ship on a slow, versioned cadence
A GitFlow-style model, or trunk plus a release/* branch, earns its overhead — you genuinely need to stabilise a version and patch old ones.
Somewhere in between
Most teams: trunk-based as the spine, with a light release branch only where a supported version demands it. Start simple; add branches only when a real need appears.

The failure mode to recognise in yourself and others is cargo-culting — adopting GitFlow's five-branch dance for a team that deploys daily, or forcing bleeding-edge trunk-based onto a team shipping firmware once a quarter. Both are the same mistake: choosing by identity instead of by deployment frequency. For most cloud infrastructure work — which is where you are headed — the honest answer in an interview is "trunk-based development with short-lived branches, protected trunk, and promotion through environments," because that is what deploying infrastructure many times a day actually requires. Know GitFlow well enough to explain what it solved and why it fell out of favour; that pairing — knowing both, and knowing why you chose one — is what separates an engineer from someone reciting a blog post.

Case File · Campux Retail

Picking the flow the platform will live by

campux-platform goes trunk-based

Campux's new lead, fresh from a big enterprise, opens with "we should run GitFlow — it is what serious companies use." You ask the question this class is built on: how often will we ship? The answer, for infrastructure that changes almost daily, settles it. GitFlow's develop and long release branches would have the team merging aged, conflicting changes into campux-platform constantly — the exact tangle Figure 11 circles in red. Campux commits to trunk-based: one protected main, branches that live hours not weeks, and every change reviewed on the way in.

Release confidence moves off branches and onto environments. The trunk builds one artifact; that artifact deploys to a non-prod environment on merge, and reaches production only behind a human approval. This is the shape Build III will implement for real — and it is a decision made on numbers, not on whose last employer did what. When the lead asks how they will support an older version if a big client ever pins one, you keep the door open: a thin release/* branch, added only if and when that need actually arrives.

Watch · Microsoft Learn

The official module, and a CAMPUX overview

Read or work the module first; watch the overview to see it move
Microsoft Learn · Module

Design and implement branch strategies and workflows
learn.microsoft.com/training/modules/manage-git-branches-workflows/

GitHub Docs · Understanding the GitHub flow
docs.github.com/get-started/using-github/github-flow

CAMPUX overview video

A short walkthrough of GitFlow's tangle versus a trunk-based straight line, and how environments replace release branches, will live here. Video to be added.

Lab 1 · Trunk-based flow

Short-lived branch, in and out the same session

~8 minutes · the campux-platform repo · one protected trunk

Feel the trunk-based loop at its natural speed: branch, change, PR, merge, delete — all in one sitting. The point is that the branch never gets old enough to drift.

  1. Start from an up-to-date trunk, then cut a short-lived branch:

    git switch main
    git pull
    git switch -c add-contributing
    What just happened: you branched from the latest main. Because you pulled first, the branch starts life with zero drift — the ideal it will try to keep by not living long.
  2. Make one small change and push the branch:

    printf "\n## Contributing\nBranch, PR, review, merge, delete.\n" >> README.md
    git commit -am "Document the contribution flow"
    git push -u origin add-contributing
    On screen: GitHub prints a link to open a PR. One focused change on a fresh branch is exactly what a reviewer can read in minutes.
  3. Open the PR, let the checks and review pass, and merge it — then delete the branch when GitHub offers.

    What to notice: the branch existed for minutes and is now gone. Its work lives on the trunk; the PR keeps the history. Nothing is left to rot.
  4. Bring your trunk up to date and confirm you are clean:

    git switch main
    git pull
    git branch            # the feature branch is gone locally too, once deleted
    The lesson: that is the whole rhythm — start fresh, change small, integrate fast, delete. Repeat it many times a day and merges never become events.
Lab 2 · The cost of drift

Make a long-lived branch bite you

~10 minutes · same repo · deliberately provoke a conflict

Now feel why trunk-based forbids old branches. You will let two branches edit the same lines while the trunk moves on, then watch the second merge collide — the pain that grows with a branch's age.

  1. From an updated trunk, create two branches that will touch the same line:

    git switch main && git pull
    git switch -c edit-title-a
    sed -i '1s/.*/# Campux Platform — A/' README.md
    git commit -am "Title edit A"
    What just happened: branch A rewrote line one. Keep it unmerged for a moment — it is about to become the "old" branch that drifted.
  2. Make a competing change reach the trunk first, via its own branch and merge:

    git switch main
    git switch -c edit-title-b
    sed -i '1s/.*/# Campux Platform — B/' README.md
    git commit -am "Title edit B"
    git switch main && git merge edit-title-b
    On screen: the trunk now says "— B" on line one. Branch A still says "— A" and was cut before this landed. The two have diverged on the same line.
  3. Try to bring branch A up to date — and hit the conflict:

    git switch edit-title-a
    git merge main
    On screen: CONFLICT in README.md. Git cannot know whether line one should read A or B, so it stops and hands you both, wrapped in <<<<<<< markers.
  4. Resolve it by editing the file to the line you actually want, then finish the merge:

    sed -i '1s/.*/# Campux Platform/' README.md   # pick the real answer
    git add README.md
    git commit --no-edit
    The lesson: this conflict took seconds because only one line diverged. Now imagine a branch that drifted for three weeks across forty files — the same mechanism, multiplied into an afternoon. That multiplication is exactly what short-lived branches exist to prevent. Delete these throwaway branches when done.
Note · sed -i edits in place on Linux and Git Bash for Windows; on macOS use sed -i ''. Any text editor works just as well — the conflict is the point, not the tool.
On the job

How the team avoids a Friday

You · Cloud Engineer · two features are colliding

Two people are building on top of each other and stepping on toes. You untangle it with a branching strategy that fits the team — short-lived branches off main, merged small and often — so integration happens continuously instead of in one dreaded big-bang merge the night before release. The strategy is not dogma; it is how the team avoids a Friday.

Class Nineteen

Examination

Four drills, then two situations. The situations have no marking scheme — write your answer before you reveal the reasoning, or the exercise is worthless. Nothing is stored; this is between you and the page.

Drill 01Recall · strategy matching
A team deploys infrastructure changes many times a day. Which branching strategy fits, and why?
Marked

A. High deployment frequency is the fact that decides it: long-lived branches drift further the longer they live, so a team shipping daily under GitFlow spends its life reconciling aged branches. B chooses by prestige, not frequency — the exact cargo-cult this class warns against. C is GitFlow's failure mode taken to its extreme. D throws away review and protection entirely. Trunk-based keeps branches too young to drift, which is what shipping many times a day actually requires.

Drill 02Recall · environments
In a trunk-based team, how does a change gain confidence before it reaches customers?
Marked

B. Trunk-based moves release confidence off branches and onto environments: the trunk produces one artifact, and that same artifact is promoted forward, changing only its configuration, until a human approves production. A and C are the branch-based habits it replaces; D is the dangerous version — building a different artifact per environment means you never actually tested what you shipped. Promotion, not re-branching, is the idea to hold — and it is the exact shape Build III implements.

Drill 03Select three
Which three are true of trunk-based development?
Marked

Short-lived branches, feature flags for hidden work, and small frequent conflicts. The two false options are the common misreadings: trunk-based is not "commit to main with no review" — it leans harder on protection and checks than any other model, because constant integration would be constant breakage without them. And it does not remove the protected trunk; the protected trunk is precisely what makes it safe to integrate all day. Short branches plus strong guardrails, not a free-for-all.

Drill 04Spot the error
A developer describes their plan for a big feature. One line is the decision that will hurt most. Which?
FEATURE PLAN — as proposed

1.  Cut a feature branch off main today
2.  Build the whole feature over the next 6 weeks on it
3.  Keep it off main until it is 100% finished and perfect
4.  Rebase on main at the very end, then open one big PR
5.  Merge the ~40-file branch in a single review
Marked

Line three. The six-week isolation is the decision every other problem flows from. While the branch sits off main, the trunk moves under it every day; by the end it has drifted so far that the "rebase at the very end" in line four is a minefield and the "single review" in line five is a rubber stamp on forty files nobody can hold in their head.

The fix is not a better merge — it is to never let the branch get old. Slice the feature into small pieces that each merge within a day, hidden behind a feature flag until the whole thing is ready. The work still takes six weeks; it just integrates continuously instead of colliding all at once. Branch age is the enemy, and line three is where the team chose to make it their enemy.

Situation 01Write before you reveal
A new team lead announces the team will adopt GitFlow "because that's what serious enterprises do." Your team deploys infrastructure changes several times a day. You think it is the wrong fit. Make your case — then say what you do once the decision is made.
A strong answer argues on the number, not on taste — and knows when the arguing ends.
Reasoning

Argue on frequency, not identity. Do not say "GitFlow is old" or "trunk-based is better" — those are taste, and taste loses to a lead. Say the number: we deploy several times a day, and GitFlow's long-lived develop and release branches assume a slow, versioned cadence we do not have. Name the concrete cost — daily merges of drifting branches, the exact tangle we are trying to avoid — and offer the alternative in the same breath: trunk-based with a protected trunk and environment promotion, which gives the same safety GitFlow was reaching for, at our speed.

Bring evidence, not just opinion. Point at how the team actually ships today, and if you can, at what GitFlow would have cost on a recent change. The case is strongest when it is about this team's deployment frequency, not a blog post either of you read.

Then commit to the decision, whichever way it lands. If the lead still chooses GitFlow, you implement GitFlow well — disagreeing and committing is a senior trait, not a betrayal of your view. You made the argument on the merits; now the team needs one strategy executed cleanly, not two half-followed. Revisit it later with data if the pain you predicted shows up. Being right is worth less than being someone the team can decide with.

Situation 02Write before you reveal
A stakeholder hears you are moving to trunk-based development and objects: "So half-finished code will be sitting on main — won't that ship broken features to our customers?" How do you answer?
The fear is real; the premise that "on main" equals "in front of customers" is the thing to separate.
Reasoning

Concede the fear before you dissolve it. The worry is legitimate — unfinished work reaching customers would be bad. The move is to separate two things the objection has fused: being merged to main and being visible to a customer. Trunk-based keeps them apart deliberately, so "on main" never means "live to users."

Name the two mechanisms. First, feature flags: unfinished work merges to the trunk switched off, present in the code but dark to users until we choose to turn it on. Second, environments: the trunk deploys to dev and test long before production, and production sits behind an approval gate, so nothing reaches customers unreviewed. Merged, tested, and released are three different events.

Turn it back into the benefit. This is actually safer than the alternative: a giant feature branch merged after six weeks lands as one big, poorly understood change, while small flagged increments are each reviewed and integrated continuously. Customers see a feature the day we flip the flag — not a moment sooner — and by then it has been on the trunk, tested, the whole time. The stakeholder wanted safety; trunk-based with flags is how you give it to them.

Examination record · first attempt
0/4
Class Nineteen · Complete
Retain this much

Five things worth carrying out of this class

  1. A branching strategy is a consequence of one number — how often you ship — not a matter of taste or seniority.
  2. GitFlow's long-lived lanes (main, develop, feature, release, hotfix) suit a slow, versioned cadence; the price is drift and painful merges.
  3. Trunk-based keeps one protected trunk and short-lived branches, so integration is small and constant instead of large and dreaded — the modern default for cloud teams.
  4. Release confidence lives in environments, not branches: promote one build through dev → test → prod. Feature flags keep unfinished work merged but hidden.
  5. Choose by deployment frequency, not fashion. Know both strategies and why you picked one — that pairing is the interview answer.
Notes
  1. "Deployment frequency" is not a slogan — it is one of the four DORA metrics, the research-backed measures of software delivery performance (alongside lead time for changes, change failure rate, and time to restore service). The finding that elite teams both deploy far more often and fail less is what retired the old assumption that speed and safety trade off. Trunk-based development is strongly associated with the high-performing end of that data. Treat the exact rankings with a little suspicion — they are survey-based — but the direction is well replicated.
  2. GitFlow's own author, Vincent Driessen, later added a note to his 2010 post urging readers not to treat it as a default — for teams practising continuous delivery on web apps, he now points them toward simpler, trunk-based flows. This is a healthy thing to cite in an interview: the model is not "wrong", it is a good answer to a question fewer teams are asking. Knowing that history signals you understand the why, not just the diagram.
  3. "Trunk-based development" is sometimes used loosely to mean "commit straight to main", which is a caricature that gives it a bad name. The disciplined version — short-lived branches, a protected trunk, PR review, and automated checks on every change — is the one the research and this class mean. If someone dismisses trunk-based as reckless, they are usually arguing against the caricature; the real practice is more guarded than long-branch models, not less.