Merge strategies

  1. Git Merge Strategies
  2. Types of git merge strategies
  3. Recursive git merge strategy options

Git Merge Strategies

When the work is complete and ready to be merged into the main line of the development, we should choose our merge strategy.

Git combines two commit pointers into one common base commit between them. Git finds that common base in different ways called “merge strategies". After selecting a merge strategy, Git creates a new merge commit combining the changes of the specified merge commits. If not specified, the git merge command will automatically select a merge strategy based on the provided branches. The -s option can be attached with the name of the specified strategy. Here’s the list of merge strategies:

Recursive

git merge -s recursive branch1 branch2

Git will select recursive as a default strategy when pulling or merging branches. The recursive strategy can detect and manage merges that involve renames, but it cannot use detected copies.

Resolve

git merge -s resolve branch1 branch2

The resolve strategy uses a 3-way merge for resolving branches and can resolve only two HEADs using a 3-way merge algorithm. It is safe and fast and detects criss-cross merge ambiguities in detail.

Octopus

git merge -s octopus branch1 branch2 branch3 branchN

When two or more branches are passed, the octopus strategy is engaged, by default. Octopus refuses if the merge has conflicts that need manual resolution. The basic use of Octopus is to bundle feature branch HEADs that have similarities.

Ours

git merge -s ours branch1 branch2 branchN

Our strategy resolves multiple branches, but the result is always that of the current branch HEAD. It ignores all changes from all other branches very effectively. It is intended to be used to replace an old history of side branches.

Subtree

git merge -s subtree branchA branchB

The subtree strategy is the modified version of the recursive strategy. For example, we merge A and B trees. When corresponding to a subtree of A, B is first modified to reflect the tree structure of A. The modification can be done to the shared ancestor tree of A and B.

Types of git merge strategies

Explicit merge

Explicit merges are considered as the default merge type. It is called explicit because it creates a new merge commit changing the history and displaying where the merge was invoked. The merge commit content is also considered as explicit as it displays the parent commits of the merge commit.

Implicit merge via rebase or fast-forward merge

The implicit merges do not create a merge commit. They just take a number of commits from the specified branch HEAD and put them to the top of the target branch. They are triggered by rebase events or fast forward merges.

Squash on merge without explicit merge

Squash is another type of implicit merge. A squash merge takes the commits from the target branch and squashes them into one commit which then is applied to the HEAD of the merge base branch. Squash can be executed during an interactive rebase. The commit history of the target branches becomes a squashed branch commit when squashed and merged.

Recursive git merge strategy options

ours Forces conflicted parts to be auto-resolved by favoring 'our' version. The changes from the other tree not conflicting with our side are reflected to the merge output.
theirs Favors the other merging tree in conflict resolution. There is no "theirs" merge strategy unlike "ours".
patience Spends much time to avoid mis-merges that occur because of unimportant matching lines.
diff-algorithim Instructs "merge-recursive" to use a different diff algorithm that helps to avoid mis-merges on unimportant matching lines.
ignore-*
  • ignore-space-change
  • ignore-all-space
  • ignore-space-at-eol
  • ignore-cr-at-eol
Targets whitespace characters. Whitespace changes mixed with other changes are not ignored.
renormalize Runs a check-out and check-in on all of the file stages when resolving a 3-way merge.
no-normalize Disables the renormalize option.
no-renames Ignores renamed files during merge.
find-renames=n Turns on the rename detection passing a similarity threshold. The n value is 100%.
subtree Works on the path metadata of the tree to make the trees match.



Do you find this helpful?

Related articles