我正在研究Mercurial,但我不明白它是如何检测文件冲突的。
当集中式SCM(作为SubVersion)在我的项目中检测到文件的两个版本之间的混乱时,这意味着我的本地文件的版本号比远程存储库中相同文件的版本号小,因为另一个开发人员( pe John Smith)在我面前承诺(通过相同的初始版本号)。
在分散的SCM(Mercurial,Git等)中,我没有中央存储库,那么:
Git如何理解我们的文件是数字版本A的直接后代? Mercurial / Git / Bazaar / etc没有内部数字标识:他们如何理解修改后的文件是否发生冲突?
答案 0 :(得分:2)
只有在您和John Smith相互沟通(使用hg push
和hg pull
)之后才会检测到任何冲突,然后其中一人想要合并两个工作线(使用{{1} })。
将John Smith的更改提取到本地存储库后,更改集图形可能如下所示:
hg merge
您在变更集... [a] --- [b]
\
`---------- [c]
和John Smith根据变更集b
制作c
的位置。在a
和a
之间,您更改了文件b
以及helloworld.c
和a
之间的John Smith更改了同一个文件。 Mercurial现在可以告诉我这里可能存在潜在的冲突(重叠编辑),它会告诉您何时运行c
。
系统不基于与文件关联的版本号 - 它基于上述变更集图。具体而言,当您将hg merge
与b
合并时,Mercurial会找到最大的共同祖先,即c
。然后,它会在a
,a
和b
中查看清单(给定变更集中的文件列表(及其版本))并注意到文件c
存在于三个不同版本中。这告诉Mercurial它需要进行三向合并,helloworld.c
是基本版本,a
和b
是本地版本和其他版本。默认情况下,它会尝试在内部执行合并,但如果失败,它将调用外部合并工具(如KDiff3)。
答案 1 :(得分:0)
如果你真的想知道它是如何运作的,我推荐Chapter 4 of the book "Mercurial: The Definite Guide"
简而言之,Mercurial为每个版本创建一个唯一标识符。它在所有存储库中都是唯一 - 基于散列。您和John Smith都将在您的存储库中具有相同的A版标识符。您的本地更改将具有不同的标识符。当你们中的一个决定提取和合并更改时,Mercurial可以确定你们两个都对同一个版本A进行了更改。这两个更改都与基础版本A进行了比较。然后检查生成的补丁是否存在冲突很容易