找出不同的变更

作者:Steve Losh
日期:2009-12-09

你能不能说出哪些变更集属于版本 X不是 属于版本 Y 呢?

本文受到 mercurial-devel 邮件列表一封邮件 的启发。

那个问题简单的来说就是:你怎样能确定哪些变更集属于版本 X不是 属于版本 Y ?这在你更新使用的软件并想知道新老版本之间有何不同的时候将会很有用。

听起来是个很简单的任务,不过这里还是有一些你值得注意的技巧在里面。

Note

本贴士中我会使用 shortlog 别名 来代替 hg log 命令使输出内容更易读。所有工作都和 hg log 一样正确的执行 (因为 hg slog 就是 hg log 添加了模板的别名命令而已),所以请放心使用。

简单(但不正确)的方法

让我们先用最简单的方法来列出版本: --rev 选项。比方说我们有一个简单的代码库的结构图看起来就像下面这样:

$ hg glog
o  4 Fix another bug. (6 seconds ago by Steve Losh) tip
|
o  3 Fix a bug. (16 seconds ago by Steve Losh)
|
@  2 Add another simple feature. (34 seconds ago by Steve Losh)
|
o  1 Add a simple feature. (40 seconds ago by Steve Losh)
|
o  0 Initial revision. (7 minutes ago by Steve Losh)

假如你当前正在版本 2 并想知道你更新到 tip 之后会发生哪些变更,你可能会用像下面这样的操作:

$ hg slog --rev 2:tip
2 Add another simple feature. (5 minutes ago by Steve Losh)
3 Fix a bug. (5 minutes ago by Steve Losh)
4 Fix another bug. (5 minutes ago by Steve Losh) tip

你可以看到输出内容中居然还包括了版本 2 ,这并不需要列举出来的因为你就正处于这个版本。好吧,这并不是什么大问题,你完全可以忽略掉它。

可是,当你同时在代码库的多个分支上进行工作时这个方法就没用了。比如:

$ hg glog
@  6 Fix a critical bug. (1 second ago by Steve Losh) tip
|
| o  5 Start the rewrite of the UI. (24 seconds ago by Steve Losh)  ui-rewrite
| |
o |  4 Fix another bug. (8 minutes ago by Steve Losh)
| |
o |  3 Fix a bug. (8 minutes ago by Steve Losh)
| |
o |  2 Add another simple feature. (9 minutes ago by Steve Losh)
|/
o  1 Add a simple feature. (9 minutes ago by Steve Losh)
|
o  0 Initial revision. (16 minutes ago by Steve Losh)

$ hg slog --rev 2:tip
2 Add another simple feature. (9 minutes ago by Steve Losh)
3 Fix a bug. (9 minutes ago by Steve Losh)
4 Fix another bug. (9 minutes ago by Steve Losh)
5 Start the rewrite of the UI. (54 seconds ago by Steve Losh)
6 Fix a critical bug. (31 seconds ago by Steve Losh) tip

注意 hg slog 命令的输出中包含了变更集 5 。它可是另一个分支上的,从 2 更新到 tip (6) 根本不会包括 5 里的变更。

这发生原因是因为当你指定一个版本范围时 Mercurial 是按照版本号顺序步进的去执行 它们。这也就是说 1:4 真正表示的是 “ 123 还有 4 不管它们之间有没有分支出现”。

通过一些其他的 hg log 选项我们能比这做的更好。

正确的方法

如果我们回退几步并仔细思考下我们正试图解决的问题,我们可以将其简化为一个更简单的定义。我们想要查看所有的变更集是:

  • 属于目标版本(即其祖先)
  • 属于源版本

解决第一个问题,我们可以使用两个选项的组合, --rev--follow ,就像这样:

$ hg slog --rev tip:0 --follow
6 Fix a critical bug. (11 minutes ago by Steve Losh) tip
4 Fix another bug. (20 minutes ago by Steve Losh)
3 Fix a bug. (20 minutes ago by Steve Losh)
2 Add another simple feature. (20 minutes ago by Steve Losh)
1 Add a simple feature. (21 minutes ago by Steve Losh)
0 Initial revision. (28 minutes ago by Steve Losh)

注意这里并没有显示其他分支上多余的变更集。

使用 --rev DESTINATION:0 假设 --follow 就是说“显示所有是 DESTINATION 祖先的变更集”。 试试 hg help log 了解所有选项的作用。

接下来我们还有一件事要做 – 从列表中移除属于我们当前版本的变更集:

$ hg slog --rev tip:0 --follow --prune 2
6 Fix a critical bug. (16 minutes ago by Steve Losh) tip
4 Fix another bug. (25 minutes ago by Steve Losh)
3 Fix a bug. (25 minutes ago by Steve Losh)

就是这样!变更集 643 就是从我们示例代码库中将 2 更新到 6 后生效的变更集。

这个命令通常的格式就是这样:

hg slog --rev DESTINATION:0 --follow --prune SOURCE

当然你也可以全部都使用缩写来指定。比如你想知道从你当前工作的版本更新到 tip 会包含哪些变更:

hg slog -r tip:0 -fP .

Note

这个命令在你“向后”更新的时候 不会 有用。它只会向你展示那些添加的变更集 – 它不会提到属于 SOURCE 属于 DESTINATION 的变更集。