W3docs

merge strategies

Learn Git merge strategies — ort, recursive, resolve, octopus, ours and subtree — plus fast-forward, squash and explicit merges, with examples.

mergeconflicts

Git Merge Strategies

When your work on a branch is complete and ready to be combined with the main line of development, Git has to decide how to fold the two histories together. The algorithm it uses to do that is called a merge strategy.

A merge strategy takes two (or more) branch tips and produces a single result. Most of the time you never name a strategy explicitly — the git merge command picks a sensible default based on how many branches you are merging and whether their histories have diverged. When you do need control, pass -s <strategy> (and optionally -X <strategy-option> for fine-tuning):

git merge -s recursive feature

This page covers two related ideas that are easy to confuse:

  • Merge strategies (-s): the algorithm that computes the merged tree — ort, recursive, resolve, octopus, ours, subtree.
  • Merge types: the kind of result you get — an explicit merge commit, a fast-forward, or a squash.

You almost never need to choose a strategy by hand. The defaults are correct for the overwhelming majority of merges; reach for -s or -X only when you hit a specific problem they solve.

Merge strategy algorithms

ort (default)

git merge -s ort feature

ort ("Ostensibly Recursive's Twin") has been the default two-head merge strategy since Git 2.34 (2021). It is a faster, more correct rewrite of the older recursive strategy and produces the same kind of result: a 3-way merge that handles renames and recursively merges multiple common ancestors into a single virtual ancestor.

Because it is the default, you get ort automatically when you run a plain merge:

git checkout main
git merge feature

recursive

git merge -s recursive feature

The original 3-way strategy for merging two branches, and the default before Git 2.34. It can detect and follow renames but cannot use detected file copies. You rarely need to request it by name now — ort supersedes it — but it is still available for compatibility.

resolve

git merge -s resolve feature

resolve performs a single 3-way merge between exactly two heads (the current branch and the one you name). It does not try to be clever about multiple merge bases, which makes it fast and predictable, but it can mis-merge across a "criss-cross" history where two branches were merged into each other earlier. Use it only when the recursive/ort merge produces a result you want to double-check with a simpler algorithm.

octopus

git merge -s octopus topic-a topic-b topic-c

octopus is the default strategy when you merge more than two branches at once. It bundles several branch tips into one merge commit, which is handy for joining a set of independent topic branches. It deliberately refuses any merge that would need manual conflict resolution — octopus merges are meant to be clean, so if there is a conflict you should merge the branches individually instead.

ours

git merge -s ours obsolete-branch

The ours strategy records a merge commit that has the other branch as a parent but keeps your current branch's tree completely unchanged — every change from the other branch is discarded. The typical use is to mark a branch as "merged" for history's sake (so future merges know about it) while ignoring its actual content, for example when retiring a long-lived branch whose work is no longer wanted.

Warning

Do not confuse the ours strategy (-s ours, which throws away the other branch's content entirely) with the ours strategy option (-X ours, which keeps your side only for the lines that actually conflict). They behave very differently.

subtree

git merge -s subtree project-b

subtree is a variant of the recursive/ort algorithm for the case where one tree is a subdirectory (a "subtree") of the other. Before merging, Git shifts the paths of one tree so the two line up, then merges as usual. This is the machinery behind incorporating one project into a subfolder of another. For day-to-day subtree work, the higher-level git subtree command is usually easier.

Merge types: what the result looks like

The strategy decides how the trees are combined; the merge type describes the shape of the history that comes out the other end.

Fast-forward merge

When the branch you are merging into has not moved since the other branch was created, there is nothing to combine — Git can simply slide the branch pointer forward to the latest commit. No new commit is created and history stays perfectly linear. This is Git's default whenever it is possible:

git checkout main
git merge feature
# Output (when main is an ancestor of feature):
# Updating a1b2c3d..d4e5f6a
# Fast-forward
#  app.js | 3 +++
#  1 file changed, 3 insertions(+)

To keep an explicit record of the merge even when a fast-forward is possible, force a merge commit with --no-ff:

git merge --no-ff feature

Explicit (3-way) merge commit

When both branches have new commits — their histories have diverged — Git creates a brand-new merge commit with two parents. This is "explicit" because the commit is visible in the history and records exactly where and when the branches came together:

git checkout main
git merge feature
# Output (when histories diverged):
# Merge made by the 'ort' strategy.
#  app.js | 5 +++++
#  1 file changed, 5 insertions(+)

If the two branches changed the same lines, the merge stops with a conflict you have to resolve by hand — see merge conflicts.

Squash merge

A squash merge collapses all the commits from the source branch into a single new commit on the current branch. It does not create a merge commit and does not record the source branch as a parent, so the source branch's individual commits never appear in the target history:

git checkout main
git merge --squash feature
# Changes are staged but NOT committed yet:
git commit -m "Add feature X"

This keeps the main branch history tidy — one commit per feature — at the cost of losing the fine-grained commit log of the feature branch. It is a popular policy for pull requests. For rewriting commits within a branch instead, see interactive rebase.

Strategy options (-X)

The ort/recursive strategies accept extra options through the -X flag (note the capital X, separate from -s). For example, to auto-resolve conflicts in favor of your side:

git merge -X ours feature

The available options are:

OptionEffect
oursAuto-resolves conflicting hunks by favoring our side. Non-conflicting changes from the other tree are still merged in. (Unlike -s ours, which discards the other side entirely.)
theirsThe opposite of ours: auto-resolves conflicts in favor of the other tree. There is no separate theirs strategy, only this option.
patienceSpends extra time matching lines so it avoids mis-merges caused by unimportant matching lines.
diff-algorithm=<algo>Tells the merge to use a different diff algorithm (e.g. histogram, minimal, patience).
ignore-space-change / ignore-all-spaceIgnores whitespace-only differences when detecting conflicts. Whitespace changes mixed with real changes are not ignored.
renormalizeRuns a virtual check-out and check-in of all file stages, useful when line-ending or smudge/clean filters changed.
no-renormalizeDisables the renormalize option.
no-renamesTurns off rename detection during the merge.
find-renames=<n>Turns rename detection on with a similarity threshold of n% (default 50%).
subtree=<path>Like the subtree strategy, but lets you specify the path prefix that should be shifted to make the trees line up.

How to choose

For everyday work you do not pick a strategy at all — let Git use ort, and decide only the result you want:

  • Want the simplest, linear history when possible? Just git merge (fast-forwards automatically).
  • Want every merge recorded as a commit? Add --no-ff.
  • Want one clean commit per feature on main? Use --squash.
  • Joining several finished topic branches at once? Plain git merge a b c uses octopus.

If you would rather replay your commits on top of the target branch instead of merging, look at git rebase. To bring in a single commit from another branch, use git cherry-pick.

Practice

Practice
What are the different merge strategies in Git and their characteristics?
What are the different merge strategies in Git and their characteristics?
Was this page helpful?