How does Git decide on conflicts?
当我从GitHub中拉出时,团队中的其他人修改了某个文件,Git命令显示出Git无法解决的冲突。我打开Perforce或Visual Studio 2012来修复冲突,图形工具显示没有冲突,并快速执行合并。
Git是否有独立于您的set merge tool/difftool的内部冲突检测/合并工具?
或者它是否使用您配置的工具来自动合并和检测无法解决的冲突?
我的场景很奇怪,Git显示它不能自动合并,但是图形工具显示没有问题。
Git有一个独立于
1 2 | -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 -s
option, a built-in list of strategies is used instead (git
merge-recursive when merging a single head, git merge-octopus
otherwise).
号
当合并许多树时,策略从简单的
不管怎样,你的情况很奇怪。也许您的IDE使用了不同的合并策略,所以当它打开时,合并的方式是正确的。
正如阿托普在回答中所说,
Git has an internal merge system that is independent of
difftool .
号
因此,Git决定什么时候一个变更会自己引起冲突,而不是使用你正在使用的任何外部diff或合并工具(它们可能使用自己的冲突检测和解决策略)。
根据VONC对什么构成了Git中的合并冲突的回答?(重点是我的):
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.
号
他链接到的维基百科文章解释了一个三方合并(强调我的):
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).
号
本文还讨论了递归的三方合并,我在Git中经常看到这种合并:
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).
号
是的,许多IDE和合并工具将在Git自己的基础上进行自动冲突解决。
正如在
1 2 3 4 5 | <<<<<<<< Version identifier 1 Foo ======= Bar >>>>>>>> Version identifier 2 |
号
我不使用Visual Studio,但一个快速的谷歌告诉我它有一个自动冲突解决功能。(我自己使用kdiff3,它有自己的自动冲突解决算法)
这里的文章是我在Git合并策略上看到的最好的答案。是的,你可以选择你想要哪一个和
但您的问题是,为什么其他工具(如Visual Studio)在Git无法合并时会合并它。Visual Studio可以有一个相当激进的合并策略-"自动合并功能通常不会使用旧版本中的任何内容,因为自动合并功能的默认设置倾向于最新的文件",有关详细信息,请参见此处。
要进一步了解与2012年相比的合并工具,请看这篇文章,Brian Harry深入探讨了他们如何将"合并时的最小冲突"视为一个关键功能。
至于性能,我怀疑他们有类似的合并策略——Git到P4连接器必须使用性能合并策略来解决问题,我相信他们也更具攻击性。
在Git中,"我们的"可能是一个类似的激进合并策略。
但长短不一的是,每种产品都在使用自己的合并策略,有些产品或多或少具有攻击性。这取决于您的用例和可接受的需求。