Git gives you multiple ways to combine branches. Choosing the right merge strategy keeps history readable, reduces conflicts, and makes releases predictable.
Fast-forward merge
What it is: If the target branch has no new commits since you branched off, Git just moves the pointer forward—no merge commit.
Use it when: Small feature branches, no parallel changes on main, you want linear history.
Tip: Protect main to allow fast-forward only if you prefer a straight line of commits.
Recursive (three-way) merge
What it is: Default strategy; creates a merge commit that combines both histories.
Use it when: Teams working in parallel; you want to preserve branch context and avoid rewriting commits.
Tip: Great for auditability; keeps the “where did this come from?” trail.
Squash merge
What it is: Combines all commits from a branch into one commit on the target, without preserving the source branch history.
Use it when: You want a clean main branch history with one commit per feature/PR.
Trade-off: You lose individual commit granularity from the feature branch.
Rebase (onto target) then fast-forward
What it is: Replay your branch commits on top of the latest main, then fast-forward merge.
Use it when: You want a linear history but need to catch up with main before merging.
Rule: Never rebase shared/public branches; it rewrites history. Safe on local/feature branches.
Ours/Theirs strategies
- ours: Keep the target branch changes, ignore incoming changes.
- theirs (during rebase): Prefer the incoming branch’s changes in conflicts.
Use with caution: These are override choices for specific conflicts or bulk reversions; document why.
Octopus merge
What it is: Merges multiple branches at once (no conflicts allowed).
Use it when: Combining several topic branches that don’t conflict—rare in typical feature workflows.
Choosing a strategy
- Linear history focus: Rebase + fast-forward or squash.
- Context/audit focus: Recursive merge with merge commits.
- Release branches: Prefer merge commits to keep a clear release lineage.
- Hotfixes: Cherry-pick to stable branches, then merge back normally.
Policy tips for teams
- Protect main; require reviews and CI before merge.
- Decide per-repo: allow merge commits, require squash, or enforce rebase+FF.
- Document when “ours” overrides are acceptable and how to log them.
- Keep feature branches short-lived to reduce conflicts.
Quick commands
# fast-forward (if possible)
git checkout main
git pull
git merge --ff-only feature-branch
# recursive merge commit (default)
git checkout main
git merge feature-branch
# squash merge (one commit)
git checkout main
git merge --squash feature-branch
git commit
# rebase feature on main then FF
git checkout feature-branch
git rebase main
git checkout main
git merge --ff-only feature-branch
Pick the strategy that matches your team’s priorities: linear history, auditability, or simplicity. Consistency in your policy matters more than using every option Git provides.