使用 Mercurial,如何在进行更新时 运行 每个变更集的作业?

With Mercurial, how to run a job for each changeset when doing an update?

问题: 当我将我的工作目录从一个修订版更新到另一个修订版时,我想 运行 每个通过的修订版都有一个脚本。我该怎么做?

重要约束

举例说明:

r1(*) -- r2 -- r3 -- r4(head)

基本上我愿意

r1(*) --> r2 (then run script) --> r3 (then run script) --> r4 (then...

比方说,我的工作目录目前在 r1,现在我想将它更新到 r4。我不想直接更新(比如 hg update),而是想先更新到 r2,然后再更新到 运行 一个脚本(例如 update-my-database)。之后我想更新到 r3,然后是 运行 相同的脚本等等。

这是可行的,但我们必须小心 select 修订图中的 线性 部分。

考虑一个有两个头的最小存储库(如果有两个分支或两个书签,情况也是一样):

$ hg log -G --template "{rev}\n"
o  4
|
| o  3
| |
| o  2
|/
o  1
|
o  0

假设我们从 1 开始。我们想要沿着头 4(因此线性部分为:1、4)或沿着头 3(因此线性部分为:1、2、3)。

因此我们将使用带有两个参数的脚本:线性片段的开始和结束。

这是最基本的但有效:

for rev in `hg log -r "descendants(1) and ancestors(3)" --template "{rev}\n"`
do
    echo Updating to $rev:
    hg update $rev
    echo Executing our script:
    hg id --id --num
done

这是输出:

Updating to 1:
0 files updated, 0 files merged, 2 files removed, 0 files unresolved
Executing our script:
4d5aba4313ce 1
Updating to 2:
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
Executing our script:
f0de0712ec00 2
Updating to 3:
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
Executing our script:
d052bd7c310b 3

无论工作目录的当前版本是什么,脚本都有效。

在启动它之前,您必须hg fetch从远程获取更改而不将它们应用到工作目录,hg log --graph了解拓扑结构,因此select直线段的起点和终点。

您还必须将硬编码的 13 替换为 </code> 和 <code> shell 位置参数并替换 hg id 符合您的实际脚本:-)

为了理解它是如何工作的,我们使用了一个叫做 revsets 的 mercurial 特性(做 hg help revsets 来了解更多),它允许在历史图上执行查询(有点像 SQL :- )