4

我正在编写代码来分析我们对 的提交Hg,并将我的结果与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 中的 repo 并选择 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

显示两行变化。

4

2 回答 2

2

I think I've figured out what tortoisehg's logic is here (though I haven't checked the source to be sure).

As you've guessed, tortoise shows files changed on both sides of a merge with a double arrow. However, it does not look simply at the diff of the merge to each of its parents (e.g. p1(58eb7c70)::58eb7c70 and p2(58eb7c70)::58eb7c70). Instead, tortoise finds all changes introduced in the merge, compared the last common ancestor of the two parents.

Let's take the tortoise repo as an example. The graph view of the ancestry of 58eb7c70 is:

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
| |

As you can see, merge 58eb7c70d501 merged two branches of development, with one changeset (p1, 6c716caa11fd) on one side, but two on the other (p2, 39c95a813105, and its parent, da7ff15b4b96). The point where these branches diverged is the last common ancestor of p1 and p2 -- 48c055ad634f.

(The last common ancestor can be found directly with hg log -r "last(ancestor(p1(58eb7c70), p2(58eb7c70)))")

Let's look at the changes that were made on those two branches. We'll compare each parent of the merge with the common ancestor:

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

These are the changes that were actually merged by 58eb7c70d501 -- everything changed on the two branches since they diverged. As you can see, the only file in common between the lists -- the only file that was changed on both branches -- is tortoisehg/hgqt/repowidget.py, just as you expected. You'll see that this file was changed in da7ff15b4b96, the one changeset that's not a parent of the merge but is still included in the changes merged from the two branches.

于 2013-03-17T16:39:27.927 回答
0

tortoisehg/hgqt/repowidget.py6c716caa11fd中进行了修改,这可以解释为什么你的第二次调用hg diff给你结果;第一次调用比较两个未注册更改的修订tortoisehg/hgqt/repowidget.py;这对我来说似乎是合理的,除非我错过了关于hg diff行为方式的其他内容。

于 2013-03-16T17:23:58.887 回答