GitMerge Strategies (ours, theirs, recursive)

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

Bash
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

Bash
# 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 oursstrategy. 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 oursoption. 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.

An easy way to remember
Capital `-S` and `-X` were not chosen for symmetry — `-s` picks the strategy class; `-X` configures one of its options. Capital `X` is for *extras*.
The ‘ours’ strategy in detail

Mark a branch as merged without taking content

Bash
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

Bash
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

Text
# 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

Bash
# 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 ours during a contentious lockfile merge — pick one to avoid manual work.

  • -s ours to formally close out an experimental branch.

  • -s octopus for very specific “merge train” workflows.

  • -s subtree when integrating one repo as a sub-folder of another.

Tip
Do not memorise the strategies. Just remember -X ours and -X theirs — those two cover most real-world use cases (conflict shortcuts). Everything else is rare and lookup-able.