在 Mercurial 中,过时的变更集是否可以强制变为未过时?

In Mercurial, can obsolete changesets be forced to become not obsolete?

在 Mercurial 中,带有后继者的变更集被标记为 obsolete

这个标记能以某种方式(强行)移除吗?

使用hg strip删除后继者后,原始变更集仍被标记为过时和灭绝)。 hg evolve拒绝重新创建继任者。

您不能将更改取消标记为过时,但您可以使用“hg touch <rev> --hidden”使它恢复生机,其中 touch 是 evolve extension 的一部分的新命令。

FWIW。也可以对过时的更改进行变基,但如果使用触摸,您可能会遇到更少的并发症。

我想出了以下 bash 函数 - 一个 hack 并且可能依赖于 mercurial 版本,但多年来一直运行良好。以 revset 作为参数。

function hg_unhide() {
  for i in $(hg --hidden  log --template '{node}\n' -r ""); do
    hg --hidden debugobsolete --index | grep $i | awk '{ print ;}' | \
      xargs -r hg --hidden debugobsolete --delete
  done
}

是的!您现在可以删除过时标记。也许在 2015 年问这个问题时是不可能的。

解决方案在 user377178 2018 年 4 月 18 日的回答中:hg --hidden debugobsolete --delete <revindex>

请注意,您不使用变更集 ID。您必须使用索引号(至少对于 Mercurial 4.1.3)。 运行 hg --hidden debugobsolete --index 获取带有过时标记的变更集列表。找到您想要成为非过时的变更集的索引,然后 运行 hg --hidden debugobsolete --delete <revindex> 将索引替换为 revindex。那么你过时的变更集就不再过时了。 (它可能在列表中多次--我没有彻底调查。)

evolve user guide, even in the section on recovering obsolete changesets. However, it is listed in the Evolve How To 指南中目前未列出 debugobsolete 命令。

非常感谢 user377178。

当前的 Mercurial 文档 Evolve: User Guide 对此进行了讨论。

Recover an obsolete changeset

Sometimes you might obsolete a changeset, and then change your mind. You’ll probably start looking for an “unobsolete” command to restore a changeset to normal state. For complicated implementation reasons, that command doesn’t exist. ...

Instead, evolve provides a touch command to resurrect an obsolete changeset.

An unexpected quirk: you almost certainly need to use --hidden, since obsolete changesets tend to be hidden, and you can’t reference a hidden changeset otherwise.

Typical usage thus looks like

$ hg --hidden touch REV

This creates a new, normal changeset which is the same as REV—except with a different changeset ID. The new changeset will have the same parent as REV, and will be a successor of REV.

The current implementation of hg touch is not ideal, and is likely to change in the future. ...

(强调我的)

来源:https://www.mercurial-scm.org/doc/evolution/user-guide.html#example-11-recover-an-obsolete-changeset


也就是说,我个人发现 graft 将过时的变更集重新投入使用更简单。您可以在 TortoiseHG 中轻松地做到这一点,例如,只需选择您想要的废弃物并将它们全部移植到一个批次中。嫁接在技术上可能在过时系统之外(或绕过)工作,但考虑到使用 touch 的复杂性,如上文所述,我发现它的简单性是值得的。

最新的甚至可能是“最前沿”的方法似乎是使用:

hg rewind

或其别名

hg undo

我说“最前沿”是因为尽管此命令已发布并且似乎有效,但我找不到太多关于它的文档,尽管 hg 命令行帮助确实包含它(如下)。它可能仍被视为 实验性 (截至 2022 年)。

hg rewind 似乎有可能取代 hg touch.


这是一个使用示例:

% hg rebase --dest=25707 --source=26017 
rebasing 26017:5c78e2af32cb "message 1"
rebasing 26018:f156002253b3 "message 2"
...
[command completed successfully Fri Apr 29 09:07:15 2022]

% hg rewind
rewound to 33 changesets
(33 changesets obsoleted)
working directory is now at 0ad018a90b93

这些命令的最终效果是让事情完全等同于我开始的地方。 rewind 花费的时间和 rebase 一样长。


内置帮助说明如下:

% hg undo --help
hg rewind [--as-divergence] [--exact] [--keep] [--to REV]... [--from REV]...

aliases: undo

rewind a stack of changesets to a previous state

    This command can be used to restore stacks of changesets to an obsolete
    state, creating identical copies.

    There are two main ways to select the rewind target. Rewinding "from"
    changesets will restore the direct predecessors of these changesets (and
    obsolete the changeset you rewind from). Rewinding "to" will restore the
    changeset you have selected (and obsolete their latest successors).

    By default, we rewind from the working directory parents, restoring its
    predecessor.

    ...


% hg --version
Mercurial Distributed SCM (version 5.9.2)
...

重要的是,该帮助还包括以下注意事项:

Current rough edges:

  • fold: rewinding to only some of the initially folded changesets will be problematic. The fold result is marked obsolete and the part not rewinded to are "lost". Please use --as-divergence when you need to perform such operation.

  • 'hg rewind' might affect changesets outside the current stack. Without --exact, we also restore ancestors of the rewind target, obsoleting their latest successors (unless --as-divergent is provided). In some case, these latest successors will be on branches unrelated to the changeset you rewind from. (We plan to automatically detect this case in the future)


关于 rewind 的一些 Mercurial developer-oriented 注释是: