Table of contents
- Why branching strategies matter
- Core branching strategies
- Choosing the right strategy
- Managing multiple branches
- Best practices for advanced Git workflows
- Graphite CLI for stacked pull requests
- CI/CD alignment
- Conclusion
Why branching strategies matter
For complex projects and large teams, a solid Git branching strategy helps maintain stability while enabling fast-paced development. With many contributors and release requirements, branching models bring clarity and structure to how code is written, integrated, and deployed. This guide introduces advanced Git workflows, compares popular strategies, and offers practical advice on managing multiple branches in Git.
Core branching strategies
Git Flow
Git Flow introduces long-lived branches like main
, develop
, and release/*
. New features are developed on feature/*
branches and integrated into develop
. Releases are prepared on release/*
and eventually merged into main
. For production fixes, hotfix/*
branches are used. It's structured but heavyweight—best for teams needing strict release control and support for multiple versions.
GitHub Flow
GitHub Flow is lightweight: every feature or fix starts on a short-lived branch from main
, undergoes code review, and merges back into main
. This suits teams releasing continuously, such as web applications. There's no release branch—main
is always deployable. Simpler, but it requires strong CI/testing discipline.
Trunk-based development
Trunk-based development emphasizes small, frequent commits directly to main
. Feature flags are used to hide incomplete work. Developers may use short-lived branches, but the goal is to integrate changes quickly. This strategy supports rapid CI/CD and minimizes long-lived divergence but requires a mature, test-driven culture.
GitLab Flow and hybrids
GitLab Flow blends GitHub Flow with environment or release branches, allowing staged deployment (e.g., main
to staging
to production
). It's flexible for teams that need both continuous integration and structured releases. Many teams create hybrids: trunk-based for development speed, with a stable branch for deployments.
Choosing the right strategy
- Use Git Flow for complex products needing long-term support or when managing multiple release tracks.
- Use GitHub Flow for fast-moving teams deploying one main version.
- Use trunk-based if you're optimizing for CI/CD and developer velocity.
- Use GitLab Flow/hybrids for a balance between speed and structure.
Managing multiple branches
Managing multiple branches can get chaotic. These practices help:
- Short-lived branches: Merge work frequently to avoid complex rebases.
- Naming conventions: Use prefixes like
feature/
,bugfix/
,release/
,hotfix/
. - Rebasing and syncing: Regularly rebase or merge
main
into your branch to reduce conflicts. - Branch protection: Protect
main
ordevelop
with required reviews and CI checks. - Clean up stale branches: Use automation or enable auto-delete after PRs merge.
Best practices for advanced Git workflows
- Keep
main
stable: Use CI, code reviews, and protection rules. - Automate testing: Run tests on every commit and pull request.
- Feature flags: Merge incomplete work safely by toggling features on or off.
- Document your workflow: Define when and how to create, merge, and deploy from branches.
- Review regularly: Adapt your strategy as your team and codebase evolve.
Graphite CLI for stacked pull requests
Graphite CLI is a GitHub-integrated tool designed to simplify and enhance stacked pull request workflows. It enables you to break a large feature into a series of incremental, reviewable PRs and manage them efficiently.
Core workflow:
Create a branch with your work
Terminalgt checkout main# make your changesgt create --all --message "feat(api): add new API method"This creates a new branch from
main
, stages all changes, commits them, and checks out the new branch.Submit the first PR
Terminalgt submitPushes the branch and opens a pull request. Amend or add commits with
gt modify
or create new ones.Stack a second PR on top
Terminalgt checkout --top # check out the top of the stack# make more changesgt create --all --message "feat(frontend): load user list"gt submit --stackCreates a new branch on top of the first and opens a stacked PR.
Inspect your stack
Terminalgt log short# orgt stack listShows the current stack of PRs and their relationship.
Address feedback with modify
Terminalgt checkout <branch-name># edit codegt modify --all # amend default# orgt modify --all --commit --message "apply review feedback"This amends or adds a commit and automatically restacks dependent branches.
Keep the stack in sync with main
Terminalgt syncPulls the latest
main
, rebases all open PRs, and prompts to clean up merged branches.Merge the stack
Terminalgt topgt pr # open the top PR in web UI# click Merge (merges whole stack in order)Or merge incrementally via the pull request UI.
Final cleanup
After merging, run
gt sync
again to fetch the latestmain
, clean up merged branches, and restack any remaining work.
This approach is ideal for trunk-based or GitHub Flow workflows. Graphite handles rebasing stacks, syncing with main
, and cleaning up merged branches. It's especially useful in large teams where reviewing smaller, focused changes improves code quality and velocity.
CI/CD alignment
Your branching strategy should guide your CI/CD setup:
- Git Flow: Test and build
develop
,release/*
, andmain
. Deploy frommain
. - GitHub/trunk-based: Test on all PRs and auto-deploy from
main
after merge. - Feature flags: Test both enabled and disabled code paths.
- Hotfixes: Create and merge from
hotfix/*
, then test and deploy.
Keep builds fast, reliable, and informative. Consider merge queues or build caching for scale.
Conclusion
The best Git branching strategy for your team depends on your product's complexity, deployment needs, and team size. By applying the Git branching strategy best practices outlined above—clear workflows, short-lived branches, CI/CD alignment, and tools like Graphite CLI—you can scale collaboration and deliver with confidence. Whether you're managing multiple branches in Git or streamlining into a continuous flow, strategy and discipline make the difference.