# How to do history-sensitive merges in Git

DevFeed: [How to do history-sensitive merges in Git](<https://devfeed.tech/articles/how-to-do-history-sensitive-merges-in-git-21566.md>)

Original publisher: [Read original article](<http://lackingrhoticity.blogspot.com/2014/03/how-to-do-history-sensitive-merges-in-git.html>)

Author: Mark Seaborn (noreply@blogger.com)

Published: 2014-03-26T17:17:00Z

Content type: tutorial

Language: en

Sources: [Mark Seaborn](<https://devfeed.tech/sources/mark-seaborn.md>)

Topics: [Git](<https://devfeed.tech/topics/git.md>), [LLVM](<https://devfeed.tech/topics/llvm.md>)

Tags: [git](<https://devfeed.tech/tags/git.md>), [history](<https://devfeed.tech/tags/history.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [llvm](<https://devfeed.tech/tags/llvm.md>), [merge](<https://devfeed.tech/tags/merge.md>), [patches](<https://devfeed.tech/tags/patches.md>), [refactoring](<https://devfeed.tech/tags/refactoring.md>), [upgrade](<https://devfeed.tech/tags/upgrade.md>), [version-control](<https://devfeed.tech/tags/version-control.md>)

## AI overview

This tutorial explains how to perform history-sensitive merges in Git by applying upstream changes one at a time. It uses the merge of LLVM 3.4 into a patched PNaCl LLVM branch to show how considering commit history can reduce conflicts and provide more context when resolving them.

## Source excerpt

Merging in Git is usually not history-sensitive. By this I mean: if you're merging branches A and B together, Git looks at the content at the tips of branches A and B, and the content of the common ancestor commit(s) of A and B, but it doesn't look at any commits inbetween. Git just does a 3-way merge. This can make merging more painful than it needs to be. History-sensitive merging is a merge algorithm that does look at the commit history. It can automatically resolve conflicts in cases where non-history-sensitive merging won't. It can also present conflicts more readably: It can reduce the size of a conflict and show which upstream change conflicted with your local change. This is a short "how to" for doing a history-sensitive merge in Git. My case study is: Merging LLVM 3.4 into PNaCl's branch of LLVM, which I did recently. The problem PNaCl has a branch of LLVM with various patches applied. (As an aside, we should really upstream those patches, to reduce the difficulty of merging from upstream.) Before the merge, this branch was based on LLVM 3.3 (commit $FROM). We wanted to upgrade it to being based on LLVM 3.4 (commit $TO). Simply doing git merge $TO produced about 160 conflicts, as counted by "git grep '<<<<<<<' | wc -l". A large number of those conflicts occurred because pnacl-llvm contained various changes cherry-picked from upstream LLVM. Often those changes touched code that was later refactored upstream. That will produce a conflict if we do a 3-way merge. For example, pnacl-llvm cherry-picked various changes that add test files with "CHECK:" lines. Upstream later refactored these to "CHECK-LABEL:". If we do "git merge $TO", Git will see that the two branches added a file with the same name but different contents. Bam: that's a conflict. Git's 3-way merge doesn't look at the history, so it doesn't notice that both branches contain identical commits that add the file with a "CHECK:" line, and just one of the two branches later modifies that file. A soluti