A Practical Git Branching Model for Teams
— ny_wk

If your team merges straight into one branch and prays, you already know the pain. A clear Git branching model turns merging and releasing from a scary event into a routine. Here's a practical, battle-tested model — and why Git makes it work.
Why branch at all?
Coming from CVS/Subversion, many developers treated branching and merging as rare and risky ("beware the merge conflicts"). Git flipped that: branching and merging are cheap, fast, and meant to be part of your daily workflow. That cheapness is exactly what lets a structured model exist.
The two long-lived branches
- main (or master): always reflects production-ready, released code. Every commit here is a shippable state.
- develop: the integration branch where finished features come together for the next release.
The supporting (short-lived) branches
- Feature branches — branch off
developfor each new feature (feature/login). Merge back intodevelopwhen done. This keeps work-in-progress isolated. - Release branches — when
developis feature-complete, cut arelease/1.2branch for final testing and bug fixes. Merge it into bothmain(and tag it) and back intodevelop. - Hotfix branches — for urgent production bugs, branch off
main(hotfix/1.2.1), fix, then merge into bothmainanddevelopso the fix isn't lost.
The everyday flow
- Start a feature: branch from
develop. - Finish it: merge back to
develop(via pull request/review). - Ready to ship: cut a release branch, stabilize, then merge to
main+ tag. - Production fire: hotfix off
main, merge tomainanddevelop.
Key takeaways
- Two permanent branches: main (production) and develop (integration).
- Feature branches off develop; release branches stabilize; hotfix branches patch production fast.
- Always merge hotfixes and releases back into develop so nothing is lost.
- Git makes branching/merging cheap — lean into it daily.
Frequently asked questions
Do small teams need all these branches?
Not always — a lighter model (main + short feature branches, "GitHub Flow") suits small teams or continuous deployment. This fuller model shines with scheduled releases.
Where do feature branches come from?
From develop, and they merge back into develop — never directly into main.
Why merge a hotfix into develop too?
So the fix exists in the next release. Merging only into main means the bug returns when develop ships.
Should I tag releases?
Yes — tag main at each release (e.g., v1.2.0) so you can always reproduce exactly what shipped.
Pick the model that fits your release cadence, keep main always-shippable, and merging stops being something you fear.