Skip to content
Back to blog

Git Branching Strategy: main, develop, and When to Branch

July 6, 20266 min read

Every team using Git eventually faces the same question: what goes on `main`, where do features live, and how do you ship a release without breaking production? A clear branching strategy turns those decisions into habit instead of debate — everyone knows where to branch, where to merge, and what each branch is allowed to contain.

This guide walks through the Git Flow–style model used by thousands of teams: long-lived main and develop branches, short-lived feature, release, and hotfix branches, naming conventions, and the practices that keep merges painless. Whether you use GitHub, GitLab, or Azure DevOps, the branch rules are the same.

mainProductionStable, deployableProtected — no direct commitsdevelopIntegrationFeatures merge herePre-release testingfeature/*New workBranch from developDelete after mergerelease / hotfixShip & fixrelease/* → main + develophotfix/* from main
Git branching: long-lived main branches + short-lived task branches

Main Branches: main and develop

Two branches outlive every sprint. main (sometimes still called `master`) holds production-ready code. Every commit on main should be deployable — if it is not, it does not belong there. Most teams protect main: no direct pushes, merges only through reviewed pull requests, and CI must pass before merge.

develop is the integration branch where completed features land before a release. Developers merge feature branches into develop, run integration tests, and only cut a release branch when the codebase is stable enough to ship. Develop is not production — it is the staging ground where the next version takes shape.

main (or master)Production-readyEvery commit is deployableDirect pushes usually blockedTagged releases cut from heredevelopIntegration branchCompleted features merge hereCI runs before release branchesNever deploy directly to prodrelease
Main branches: production code vs ongoing integration

Quick reference

  • main: production code — stable, tagged releases, protected from direct commits.
  • develop: integration branch — features merge here first.
  • Never deploy develop directly to production in Git Flow.
  • Use branch protection rules on main (and often develop) in GitHub/GitLab.
  • Tag releases on main (v2.1.0) for traceability and rollbacks.
  • Some teams use only main (trunk-based) — this article covers the two-branch model.

Remember this

main is production truth; develop is where features integrate before a release cut.

Supporting Branches: feature, release, hotfix

Supporting branches are short-lived — created for one job, merged, then deleted. feature/ branches (e.g. `feature/login`) hold new work. Branch from develop, merge back to develop when the pull request is approved. Never merge an unfinished feature directly to main.

release/ branches (e.g. `release/v2.0`) prepare a version for production. Only bug fixes and release chores go here — no new features. When ready, merge release into both main and develop, tag main, and delete the release branch. hotfix/ branches fix critical production bugs: branch from main, patch, merge to both main and develop so the fix is not lost on the next release.

feature/*New functionalityFrom: developMerge: developDelete after mergerelease/*Release prepFrom: developMerge: main + developBug fixes onlyhotfix/*Production emergencyFrom: mainMerge: main + developFast-track to prod
Supporting branches: short-lived branches for features, releases, and urgent fixes

Quick reference

  • feature/* — from develop → merge develop → delete after merge.
  • release/* — from develop → merge main + develop → tag and delete.
  • hotfix/* — from main → merge main + develop → deploy immediately.
  • Keep supporting branches days or weeks, not months.
  • One feature per branch — easier review and safer rollback.
  • Cherry-pick hotfixes to develop if branches have diverged.

Remember this

Feature branches build, release branches stabilize, hotfix branches patch production — all short-lived.

How Branches Flow Together

The lifecycle follows a predictable path. Developers create feature branches from develop and open pull requests. When features pass review and CI, they merge into develop. Integration tests run on develop continuously.

When it is time to ship, create a release branch from develop. Stabilize it with minor fixes, then merge to main (deploy to production) and back to develop (so fixes are not lost). If production breaks, branch a hotfix from main, patch, merge to main and develop, deploy, and delete the hotfix branch. This loop keeps main always deployable while develop moves forward.

feature/loginfeature/apideveloprelease/v2maindevelophotfix/payFeatures → develop → release → main · hotfix branches from main back to both main and develop
Branch flow: features integrate on develop, releases ship through main

Quick reference

  • Multiple feature branches can merge to develop in parallel.
  • Only one active release branch per version is typical.
  • Merge release → main first, deploy, then merge release → develop.
  • Hotfixes skip the normal feature → develop → release path for speed.
  • Rebase or merge develop into long-running feature branches weekly.
  • Delete merged branches — stale branches confuse everyone.

Remember this

Features flow up through develop; releases and hotfixes are the only paths to main.

Branching Best Practices

A strategy on paper fails without discipline. Create a branch for every feature — no committing directly to develop. Keep commits small and focused so reviewers can understand each change. Always open a pull request before merging; even solo developers benefit from CI running on the PR.

Delete branches after merge — Git hosting platforms offer a button for this. Protect main (and usually develop) with required reviews and status checks. Rebase or merge from develop regularly on long feature branches to avoid painful merge conflicts at the end. Use consistent naming so anyone can tell what a branch does from its name alone.

Quick reference

  • One branch per feature or bug — not one branch per developer.
  • Small commits with clear messages (imperative mood: "Add auth middleware").
  • Pull requests trigger CI — merge only when green.
  • Delete merged branches immediately.
  • Protect main: require PR, require passing checks, no force-push.
  • Rebase or merge develop into feature branches at least weekly.
  • Use conventional branch prefixes (feature/, bugfix/, hotfix/).

Remember this

Small branches, reviewed PRs, protected main, and deleted merged branches keep the workflow fast.

Branch Naming Conventions

Consistent names make branches scannable in lists and automation-friendly in CI. Prefix the branch type, then a short kebab-case description. feature/user-auth for new functionality, bugfix/login-error for non-urgent fixes on develop, hotfix/api-timeout for production emergencies, release/v2.1.0 for release preparation.

Use chore/ for tooling and dependency updates that are not user-facing features. Use docs/ for documentation-only changes. Avoid personal names (`john-fix`) or vague names (`fix-stuff`) — future you will not remember what they mean.

1feature/feature/user-auth2bugfix/bugfix/login-error3hotfix/hotfix/api-timeout1release/release/v2.1.02chore/chore/deps-update3docs/docs/readme-update
Branch naming conventions

Quick reference

  • feature/ — new functionality (feature/oauth-login).
  • bugfix/ — fix on develop, not production-critical.
  • hotfix/ — urgent production patch (hotfix/payment-null).
  • release/ — version prep (release/v2.1.0).
  • chore/ — deps, config, tooling (chore/upgrade-eslint).
  • docs/ — documentation only (docs/api-readme).

Remember this

Prefix + kebab-case description — feature/user-auth, not johns-branch or fix2.

Key takeaway

Share:

A solid Git branching strategy removes daily friction: everyone knows where to branch, what can merge where, and how production stays stable. Start with protected main, a develop integration branch, and feature branches for all new work. Add release and hotfix branches when you ship versioned releases to production. Good branches do not slow teams down — they let multiple developers ship in parallel without stepping on each other.

Related Articles

Manual deployments are one of the highest-risk activities in software engineering. A developer SSHes into a production s

Read

Microservices are not a single tool — they are an ecosystem. You need containers to package services, databases to store

Read

Containers are ephemeral by design — when you remove one, its filesystem disappears with it. That is fine for stateless

Read

Explore this topic

Keep learning

Follow a structured path or browse all courses to go deeper.