Mercurial 提交消失了

发布于 2024-12-29 16:35:59 字数 293 浏览 1 评论 0原文

我们最近已切换到 Mercurial。一切都进展顺利,直到我们发生了两起已提交的变更丢失的事件。检查日志并没有让我们变得更明智。

下面是一个例子。在 (1) 处提交的文件将恢复到 (2) 处的先前状态,即使这些文件未在合并中提及。

我可以检查什么来了解文件恢复的原因?

修订图

We have switched to Mercurial recently. All had been going well until we had two incidents of committed changes going missing. Examining the logs has not made us any wiser.

Below is an example. The files committed at (1) revert to a previous state at (2) even though those files are not mentioned in the merge.

What can I check to understand why the files reverted?

revision graph

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

平定天下 2025-01-05 16:35:59

此图中有三个有趣的变更集可以影响 (2) 合并:

  • 青色变更集:未显示,但看起来就在该图的下方。这是 (2)
  • 蓝色变更集: 从底部数第五个的第一个父级,标记为“修复测试”。这是 (2) 的第二个父级。
  • 父母的共同祖先:也未显示,将在下面进一步介绍。奇怪的是,看起来青色变更集可能是共同的祖先,但 Mercurial 现在允许您在正常情况下进行此类退化合并。

当 Mercurial 进行合并时,这是唯一三个重要的变更集:您合并的两个头及其共同祖先。在三向合并中,现在的逻辑是:

ancestor  parent1  parent2  =>  merge
X         X        Y            Y (clean)
X         Y        X            Y (clean)
X         Y        Y            Y (clean)
X         Y        Z            W (conflict)

像这样读取表格:“如果祖先是X,并且第一个父代也是X,第二个父代是Y,那么合并将包含 Y”。换句话说:三向合并有利于改变,并且会让修改获胜。

您可以找到祖先,

$ hg log -r "ancestor(p1(changeset-2), p2(changeset-2))"

其中 changeset-2 是上面标有 (2) 的那个。当你说

即使合并中未提及这些文件,在 (1) 提交的文件也会恢复到 (2) 时的先前状态。

那么重要的是要理解“合并”只是一个快照,显示如何混合其他两个变更集。合并“中”所做的更改是此快照与其两个父级更改集之间的差异:

$ hg status --rev "p1(changeset-2):changeset-2"
$ hg status --rev "p2(changeset-2):changeset-2"

这显示了合并更改集分别与其第一个和第二个父级更改集有何不同。我确信这些文件在其中一个列表中被提及 - 除非合并根本不是罪魁祸首。

当您检查三个变更集以及它们之间的差异时,您可能会发现有人必须解决冲突(上面合并表中的第四行)并在此过程中的某个步骤中选择了错误的文件。

There are three interesting changesets in this graph that can influence the (2) merge:

  • Teal changeset: not shown, but looks like it's just below the graph. This is the first parent of (2)
  • Blue changeset: number five from the bottom, labelled "Fix test". This is the second parent of (2).
  • Common ancestor of the parents: also not shown, will be further below. Strangely, it looks like the teal changeset could be the common ancestor, but Mercurial will now allow you to make such a degenerate merge under normal circumstances.

When Mercurial does a merge, these are the only three changesets that matter: the two heads you merge and their common ancestor. In a three-way merge the logic is now:

ancestor  parent1  parent2  =>  merge
X         X        Y            Y (clean)
X         Y        X            Y (clean)
X         Y        Y            Y (clean)
X         Y        Z            W (conflict)

Read the table like this: "if the ancestor was X, and the first parent was also X and the second parent was Y, then the merge will contain Y". In other words: a three-way merge favors change and will let a modification win.

You can find the ancestor with

$ hg log -r "ancestor(p1(changeset-2), p2(changeset-2))"

where changeset-2 is the one marked with (2) above. When you say

The files committed at (1) revert to a previous state at (2) even though those files are not mentioned in the merge.

then it's important to understand that "a merge" is just a snapshot that shows how to mix two other changesets. The change made "in" a merge is the difference between this snapshot and its two parent changesets:

$ hg status --rev "p1(changeset-2):changeset-2"
$ hg status --rev "p2(changeset-2):changeset-2"

This shows how the merge changeset is different from its first and second parent, respectively. I'm sure the files are mentioned in one of those lists — unless the merge isn't the culprit after all.

When you examine the three changesets and the differences between them, then you will probably see that someone has to resolve a conflict (the fourth line in the merge table above) and picked the wrong file at some step along the way.

素食主义者 2025-01-05 16:35:59

2处的合并是在一个非常旧的分支(深蓝色,在提交1之后从主线/绿色分支分叉)和一个更旧的分支(浅蓝色,自从提交1之前就没有与主线同步)之间的

合并可能是 2 处的合并选择了错误的文件版本 - 从这里无法判断是工具选择了错误的文件版本,还是用户手动选择了错误的版本。

编辑添加:

为了帮助准确跟踪 2 中的更改,您可以使用 hg diff -r REV1 -r REV2 ,它将显示任何两个修订版之间的逐行差异。

当您知道不良情况是在第 1 点和第 2 点之间的某个时间引入时,hg bisect 可以帮助您追踪不良情况的确切来源:

hg 二等分 [-gbsr] [-U] [-c CMD] [REV]

变更集的细分搜索

此命令有助于查找引入问题的变更集。要使用,

将您知道的最早出现问题的变更集标记为“坏”,然后标记
最新的变更集也没有问题。

Bisect 会将您的工作目录更新为测试版本
(除非指定了 -U/--noupdate 选项)。一旦你有
执行测试,将工作目录标记为好或坏,然后一分为二
将更新到另一个候选变更集或宣布它
已发现错误的修订版。

The merge at 2 is between a very old branch (dark blue, forked from the mainline/green branch just after commit 1) and an even older branch (light blue, hasn't been in sync with mainline since before commit 1)

It seems likely that the merge at 2 picked the wrong version of the file - can't tell from here if that was the tool picking the wrong version of the file, or the user manually selecting the wrong version.

Edited to add:

To help track down exactly what changed at 2, you can use hg diff -r REV1 -r REV2, which will show you the line-by-line differences between any two revisions.

When you know that the badness was introduced sometime between point 1 and point 2, hg bisect may help you track down the exact source of the badness:

hg bisect [-gbsr] [-U] [-c CMD] [REV]

subdivision search of changesets

This command helps to find changesets which introduce problems. To use,

mark the earliest changeset you know exhibits the problem as bad, then mark
the latest changeset which is free from the problem as good.

Bisect will update your working directory to a revision for testing
(unless the -U/--noupdate option is specified). Once you have
performed tests, mark the working directory as good or bad, and bisect
will either update to another candidate changeset or announce that it
has found the bad revision.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文