Merge Strategies (ours, theirs, recursive)
Git has several merge strategies — algorithms that decide how to combine commits. Most of the time you do not pick one; Git uses sensible defaults. But knowing about them helps you handle edge cases and unusual merge scenarios.
The built-in strategies
Strategy | Used when | What it does |
|---|---|---|
ort | Default (Git 2.34+) | Optimised three-way merge — successor to recursive |
recursive | Older Git default | Classic three-way merge |
resolve | Two heads only | Simpler 3-way; faster but fewer features |
octopus | 3+ branches at once | Multi-way merge with no conflicts allowed |
ours | Explicit | Take only the current branch’s version; ignore the others |
subtree | Subtree merge | For merging a project as a sub-folder of another |
The default — ort / recursive
Modern Git uses ort (“Ostensibly Recursive’s Twin”), introduced in Git 2.33–2.34. It is a faster, cleaner rewrite of the older recursive strategy. Both produce the same result for normal merges — but ort handles a few edge cases (criss-cross merges, large files) better.
Selecting a strategy
git merge -s ort feature-x # explicit (modern) git merge -s recursive feature-x # legacy git merge -s resolve feature-x # simpler git merge -s octopus a b c # multiple branches git merge -s ours feature-x # discard theirs entirely git merge -s subtree feature-x # for subtree merges
Strategy options (-X)
Strategies accept options that fine-tune their behaviour. The most useful ones for the default (recursive/ort):
-X ours— for conflicts, automatically prefer the current branch’s version.-X theirs— for conflicts, automatically prefer the incoming branch’s version.-X ignore-all-space— treat whitespace differences as non-conflicting.-X ignore-space-change— ignore changes in amount of whitespace.-X patience— use the patience diff algorithm (better for code that has been moved around).
Strategy options in action
# Resolve all conflicts by preferring the current branch's version git merge -X ours feature-x # Resolve all conflicts by preferring the incoming branch git merge -X theirs feature-x # Ignore whitespace-only differences git merge -X ignore-all-space feature-x
-s ours vs -X ours (very different!)
-s ours— strategy. The merge takes EVERYTHING from the current branch and NOTHING from the other branch. The merge commit records the merge but the content is unchanged. Useful for marking “we are not taking these changes.”-X ours— option. The merge uses the normal three-way algorithm, but when a conflict arises, it auto-picks the current branch’s version. Other (non-conflicting) changes from the other branch ARE included.
The ‘ours’ strategy in detail
Mark a branch as merged without taking content
git checkout main git merge -s ours abandoned-experiment # History now shows that 'abandoned-experiment' was merged # But main's content is unchanged — none of the experiment's code came in # Useful to prevent the abandoned branch from being suggested for re-merging
The octopus strategy
Merge several branches at once
git merge -s octopus feature-a feature-b feature-c # Creates a single merge commit with FOUR parents (main + 3 features) # Will refuse to run if any conflicts exist between the branches
Per-file merge using attributes
.gitattributes
# For these files, always take ours during merges CHANGELOG.md merge=ours # For binary files, refuse to auto-merge — always conflict *.psd merge=binary
See the “.gitattributes File” page for the full picture.
Per-driver custom merge
You can register a custom merge driver — an external program that knows how to merge a specific file type:
Register a driver
# Tell Git which command to run git config merge.translations.driver "po-merge %O %A %B" # In .gitattributes: # locales/*.po merge=translations
When you actually need to pick a strategy
Almost never. The default is right >99% of the time.
-X theirs/-X oursduring a contentious lockfile merge — pick one to avoid manual work.-s oursto formally close out an experimental branch.-s octopusfor very specific “merge train” workflows.-s subtreewhen integrating one repo as a sub-folder of another.
-X ours and -X theirs — those two cover most real-world use cases (conflict shortcuts). Everything else is rare and lookup-able.