When you are building multiple features at the same time, there is one problem that shows up quickly: several branches need the same in-progress code.
If you do not account for this up front, you end up copying commits around, resolving the same conflicts repeatedly, and wondering why pull requests are impossible to review.
I use two branching patterns depending on the type of work. Both are valid. The key is choosing the one that matches the dependency structure of your features.
The Problem
Here is a common scenario where a branching strategy helps.
You start one feature branch and start adding code. A day later, you start two more features that also need that same code. One of those new features may also depend on the other.
Now your branches are connected, but not all in the same way. If you treat them as completely independent, you will repeatedly solve the same merge conflicts and pull requests become hard to review.
Strategy 1: Daisy-Chained Branches
Use this approach when each feature builds directly on the previous one.
Example:
git switch -c feature/a main
# work, commit
git switch -c feature/b feature/a
# work, commit
git switch -c feature/c feature/b
# work, commit
In this model, each branch has a clear parent:
feature/ais the basefeature/bdepends onfeature/afeature/cdepends onfeature/b
This is ideal when features are tightly layered and cannot be completed independently.
How to Maintain a Daisy Chain
Maintenance is the part people underestimate.
If feature/a changes, those changes must be propagated up the chain:
git switch feature/b
git merge feature/a
git switch feature/c
git merge feature/b
Daisy Chain Best Practices
- Keep each branch focused and small enough to review.
- Merge parent updates into child branches frequently, not once at the end.
- Open pull requests early, even as drafts, so review can begin before the entire chain is done.
- Document branch order in each pull request description, for example: "depends on feature/a".
- Avoid stacking too deeply. A chain of 2 to 4 branches is manageable. Beyond that, consider splitting work differently.
Strategy 2: Shared Base with Sibling Branches
Use this approach when multiple efforts need the same foundation, but are otherwise independent.
Example:
git switch -c feature/base main
# shared refactor or shared primitives
git switch -c feature/ui feature/base
git switch -c feature/api feature/base
git switch -c feature/jobs feature/base
In this model:
feature/basecontains common code all siblings needfeature/ui,feature/api, andfeature/jobscan evolve separately
This is useful when one large initiative touches multiple areas of the codebase and you want to keep concerns separated while reusing the same base.
How to Maintain a Shared Base Model
The base branch is the critical dependency. Treat it like a product.
When feature/base changes, merge it into each sibling branch:
git switch feature/ui
git merge feature/base
git switch feature/api
git merge feature/base
git switch feature/jobs
git merge feature/base
Do this regularly. If you wait too long, each sibling diverges and conflict resolution gets expensive.
After feature/base is merged to main, each sibling should be merged onto updated main to drop duplicate history and keep pull requests clean.
Shared Base Best Practices
- Keep
feature/basenarrowly scoped to truly shared code. - Do not sneak sibling-specific logic into
feature/base. - Protect
feature/basewith CI and code review just likemain. - Re-sync siblings from
feature/baseon a routine cadence (daily is often right during active development). - Use consistent branch naming to make relationships obvious.
Merge Order and Promotion Rules
No matter which strategy you choose, define the merge order before coding.
For daisy chains:
- Merge lowest parent first.
- Merge each child only after its parent lands.
- Re-target pull requests as parent branches merge.
For shared base plus siblings:
- Merge
feature/basefirst. - Merge each sibling onto the updated target branch.
- Merge siblings independently once they are clean.
This avoids accidental regressions and keeps review diffs understandable.
Which Strategy Should You Choose?
Use daisy-chained branches when each feature directly depends on the one below it.
Use shared base with sibling branches when multiple workstreams need common foundational code but can progress independently.
If you choose correctly, your branch strategy reduces risk and makes reviews easier. If you choose poorly, Git becomes the work instead of the tool.
A little upfront branch design saves a lot of cleanup later.