2013-03-15 54 views
4

我正在编写代码来分析我们对Hg的提交,并将我的结果与TortoiseHg进行比较。我无法理解TortoiseHg在合并情况下的行为。合并中显示的TortoiseHg文件

当我在TortoiseHg中选择合并变更集时,受影响的文件列表仅显示那些冲突的文件,除非我按下"Show All"按钮。至少这似乎是我的意图,基于我可以从网上搜集的内容,以及观察到如果按下“全部显示”按钮,列表中显示的文件具有双向箭头。

我试图通过对照父母双方对变更集中的每个文件进行比较来仿效,并且只在我的分析中包括该文件,如果它与父母双方不同。但是,我遇到TortoiseHg在合并描述中显示的文件,但这些文件仅与一位父母不同。我在TortoiseHg中也看到 - 与父级1或2的差异会显示更改,但另一个父级不会。

我也尝试使用--git选项进行区分,以确保它不是我缺少的元数据更改,但这根本不会改变结果。

要获得我使用的是变更的信息:

hg log -v -r <rev> --removed --style xml 

我拿起合并变更的父母,并在合并的每个文件,做

hg diff -r <parent1> -r <rev> filename 
hg diff -r <parent2> -r <rev< filename 

我发现文件TortoiseHg在其合并报告摘要中显示为合并为没有冲突。

任何人都可以阐明这种差异吗?

更新: 我能够使用TortoiseHg本身的源代码重现此问题。

https://hg01.codeplex.com/tortoisehg克隆 打开tortoiseHg的回购并选择rev 12602(58eb7c70)。这是与12599(6c716caa)和12601(39c95a81)的父母合并。

TortoiseHg显示文件tortoisehg/hgqt/repowidget.py作为合并的唯一冲突的文件,但

hg diff -r 12599 -r 12602 tortoisehg/hgqt/repowidget.py 

回报什么,而

hg diff -r 12601 -r 12602 tortoisehg/hgqt/repowidget.py 

显示两行改变。

+0

您的存储库是公开的吗?有一些真实的数据来看待会更容易。 – kevingessner 2013-03-15 22:27:26

+0

可悲的是,但我会看看我是否可以在公开回购问题上重新创建问题 – 2013-03-15 23:35:23

回答

2

我想我已经想出了什么tortoisehg的逻辑在这里(虽然我没有检查源确定)。

正如你所猜测的,乌龟显示文件在双向箭头合并两侧发生了变化。然而,它并不是简单地看待每个父母的合并差异(例如,p1(58eb7c70)::58eb7c70p2(58eb7c70)::58eb7c70)。相反,乌龟发现合并中引入的所有变化,比较两个父母的最后共同祖先。

让我们以乌龟回购为例。的58eb7c70祖先的图形视图是:

Jonathan:tortoisehg $ hg log --graph -r ::58eb7c70 -l 5 --template "{node|short}\n{desc|firstline}\n\n" 
o 58eb7c70d501 
|\ Merge with stable (noop) 
| | 
| o 39c95a813105 
| | repowidget: show all errors on infobar 
| | 
| o da7ff15b4b96 
| | repowidget: limit infobar error messages to 2 lines of up to 140 chars by default 
| | 
o | 6c716caa11fd 
|\| Merge with stable 
| | 
| o 48c055ad634f 
| | sync: show non-ascii command-line arguments correctly 
| | 

正如你所看到的,合并58eb7c70d501合并发展的两个分支,与一侧的一个变更(P1,6c716caa11fd),但另一方面( p2,39c95a813105及其父母,da7ff15b4b96)。这些分支发散的点是p1和p2 - 48c055ad634f的最后一个共同祖先。

(最后的共同祖先可以直接与hg log -r "last(ancestor(p1(58eb7c70), p2(58eb7c70)))"找到)

让我们来看看那些两个分支中所做的更改。我们将比较合并的每个父母与共同祖先:

Jonathan:tortoisehg $ hg status --rev "48c055ad634f::6c716caa11fd" 
M .hgtags 
M tortoisehg/hgqt/commit.py 
M tortoisehg/hgqt/compress.py 
M tortoisehg/hgqt/hgemail.py 
M tortoisehg/hgqt/postreview.py 
M tortoisehg/hgqt/purge.py 
M tortoisehg/hgqt/rename.py 
M tortoisehg/hgqt/repowidget.py 
M tortoisehg/hgqt/revset.py 
M tortoisehg/hgqt/run.py 
M tortoisehg/hgqt/settings.py 
M tortoisehg/hgqt/status.py 
M tortoisehg/hgqt/sync.py 
M tortoisehg/hgqt/visdiff.py 
M tortoisehg/util/cachethg.py 
M tortoisehg/util/hglib.py 

Jonathan:tortoisehg $ hg status --rev "48c055ad634f::39c95a813105" 
M tortoisehg/hgqt/repowidget.py 

这些是实际上是由58eb7c70d501融合的改变 - 在两个分支改变,因为他们分道扬镳的一切。如您所见,列表中唯一共享的文件(在两个分支上更改的唯一文件)为tortoisehg/hgqt/repowidget.py,正如您所期望的那样。您会看到该文件在da7ff15b4b96中已更改,该变更集不是合并的父项,但仍包含在从两个分支合并的更改中。

+0

这很有道理。非常感谢您的深入分析。现在我知道如何在我自己的代码中重新创建这个逻辑。不胜感激。 – 2013-03-17 16:57:27

0

tortoisehg/hgqt/repowidget.py已在6c716caa11fd中修改,这可以解释为什么您第二次致电hg diff会给出结果;第一次调用比较两个修改,其中没有更改注册到tortoisehg/hgqt/repowidget.py;这听起来对我来说很合理,除非我对hg diff的行为方式缺少其他信息。

+0

差异行为对我来说很有意义。我试图弄清楚为什么乌龟将这个文件标记为在合并的每一边都有变化(即冲突)。我最感兴趣的是试图复制乌龟的行为,以便我们对我们的提交和合并所作的分析将给出和乌龟一样的答案。只是基于差异,我会说文件合并没有冲突。 – 2013-03-16 17:46:49