How does Git decide on conflicts? How does Git decide on conflicts? git git

How does Git decide on conflicts?


Git has an internal merge system that is independent of difftool. Anyway you can specify the merge strategy using the -s option, from the manual:

-s <strategy>--strategy=<strategy>

Use the given merge strategy; can be supplied more than once to specify them in the order they should be tried. If there is no -soption, a built-in list of strategies is used instead (gitmerge-recursive when merging a single head, git merge-octopusotherwise).

Strategies go from the simple FastForward to the Octopus when merging a lot of trees.Check this answer to see how the different merge strategies work.

Anyway your scenario is weird. Maybe your IDE is using a different merge strategy, so when it opens it does the merge the right way.


As Atropo states in his answer,

Git has an internal merge system that is independent of difftool.

So Git decides when a change causes a conflict on its own, not by using whatever external diff or merge tools you're using (which probably use their own conflict detection and resolution strategies).

According to VonC's answer to What constitutes a merge conflict in Git? (emphasis mine):

I don't think the merge algorithm has anything special with Git: it is a classic 3-way merge algorithm (not the Codeville one), which can be used with several strategies (default: recurse, or resolve or octopus).The result is a fairly simply merge process which is described here.
Any visualization need is then delegated to third-party merge/diff tools.

The Wikipedia article he links to explains a 3-way merge thusly (emphasis mine):

A three-way merge is performed after an automated difference analysis between a file 'A' and a file 'B' while also considering the origin, or common ancestor, of both files. It is a rough merging method, but really widely applicable since it only requires one common ancestor to reconstruct the changes that are to be merged.

The three-way merge uses the ancestor of the changed files to identify blocks of content that have changed in neither, one, or both of the derived versions. Blocks that have changed in neither are left as they are. Blocks that have changed in only one derivative use that changed version. If a block is changed in both derivatives, the changed version is used if it has the same content on both sides, but if the changes differ, it is marked as a conflict situation and left for the user to resolve.

Three-way merging is implemented by the ubiquitous diff3 program, and was the central innovation that allowed the switch from file-locking based revision control systems to merge-based revision control systems. It is extensively used by the Concurrent Versions System (CVS).

The article also talks about Recursive three-way merges, which I see used in Git a lot:

Widespread use of three-way merge based revision control tools has brought up cases where simple-minded three-way merging causes spurious conflicts and sometimes silently re-enacts reverted changes. Examples of such situations include criss-cross merges and three-way rename conflicts.

The problems of three-way merge arise in situations where two derivative states do not have a unique latest common ancestor (LCA). To deal with these problems, the recursive three-way merge constructs a virtual ancestor by merging the non-unique ancestors first. This technique is used by the Git revision control tool.

Recursive three-way merge can only be used in situations where the tool has knowledge about the total ancestry DAG (directed acyclic graph) of the derivatives to be merged. Consequently, it cannot be used in situations where derivatives or merges do not fully specify their parent(s).


Yes, a number of IDEs and merge tools will do automated conflict resolutions on top of git's own.

As seen in git help merge-file, git's stock conflict resolution algorithm for text files is fairly simple: diff chunks conflict iff they change neighbouring lines. If git is unable to auto-resolve a conflict in this manner, it will put a text conflict marker in a format that has been standard since the RCS days, and that the IDE can pick up and work on (even if it doesn't know about git):

<<<<<<<< Version identifier 1Foo=======Bar>>>>>>>> Version identifier 2

I don't use Visual Studio, but a quick Google tells me that it has an automatic conflict resolution feature. (I use kdiff3 myself, which has its own automatic conflict resolution algorithm)