Mercurial 7.2.4 常用 CLI 命令详解

Mercurial 7.2.4 命令实战全集:建库提交、具名分支与书签、clone/push/pull 远程协作、diff/revert/backout 回退、merge 冲突处理、verify 校验,附每日开工自检与发布打标签脚本,全部实测回显。

MercurialMercurial版本控制2026/10/28

Mercurial 7.2.4 常用 CLI 命令详解

目标:把 hg 日常会用到的命令按「建库提交 → 分支合并 → 远程协作 → 差异回退 → 冲突处理 → 查询校验」六类串成可直接照抄的操作序列,每条命令的输入与回显都来自 2026-10-28 在 Ubuntu 22.04.5 LTS + Mercurial 7.2.4 的真实执行。

一、环境信息

项目值
操作系统Ubuntu 22.04.5 LTS
Mercurial7.2.4(hg --version)
实测用户root <root@example.com>
实验仓库/root/hg-demo(主库)、/root/hg-demo-clone(协作库)
默认编辑器vim(用户级 ui.editor)

本文所有路径均为实测路径,照抄前把 /root/hg-demo 换成自己的仓库位置即可。

二、命令速查表

先给全貌,后文逐条展开实测:

类别命令一句话作用
建库hg init初始化仓库(只创建 .hg)
提交hg add / hg remove / hg status / hg commit纳入跟踪、看状态、落库
历史hg log / hg log -G / hg tip查看变更历史与图形
分支hg branch / hg branches / hg update具名分支的创建、列举、切换
书签hg bookmark可移动指针(近似 Git 分支)
远程hg clone / hg push / hg pull / hg outgoing / hg incoming克隆与双向同步
服务hg serve启动内置 HTTP 服务
差异hg diff / hg diff -c / hg diff -r A -r B工作区差异、单提交差异、跨版本差异
回退hg revert / hg backout撤工作区改动、撤销已提交
冲突hg merge / hg resolve -l / hg resolve --mark合并与冲突标记
查询hg id / hg root / hg summary / hg tags / hg archive定位、摘要、导出
校验hg verify仓库完整性检查

三、建库与提交

3.1 hg init 与首批文件

hg init /root/hg-demo
cd /root/hg-demo
printf '# demo\n' > README.md
printf '#include <stdio.h>\nint main(){return 0;}\n' > main.c
hg status

实测回显:

? README.md
? main.c

? 表示「未跟踪」。与 Git 不同,hg 不会自动把新文件纳入下次提交,必须显式 hg add。

hg add README.md main.c
hg status

实测回显:

A README.md
A main.c

A 表示「已加入、待提交」。hg add 的语义是「登记到版本控制」,此时内容尚未进 changelog。

hg commit -m "Initial commit: main.c + README"
hg log

实测回显:

changeset:   0:722dc0302bce
tag:         tip
user:        root <root@example.com>
date:        Tue Oct 27 16:24:49 2026 +0000
summary:     Initial commit: main.c + README

0:722dc0302bce 的格式是 本地版本号:changeset 短哈希。本地版本号只在当前仓库有效,跨仓库引用历史一律用哈希或标签。

3.2 hg status 的字母含义

字母含义常见诱因
?未跟踪新文件未 hg add
A已加入待提交hg add 后未提交
M已修改跟踪文件被编辑
R已移除待提交hg remove 后未提交
!跟踪文件在磁盘丢失误删文件
U未解决(冲突中)合并未 hg resolve --mark

hg status 默认不含被忽略文件;hg status -i 才显示 .hgignore 命中的条目,这一点在排查「文件莫名不出现」时很有用。

四、分支与书签

Mercurial 有两套并行机制,这是从 Git 迁过来最容易混的地方:

机制命令特性适用
具名分支(named branch)hg branch名称写入 changeset,永久且全局长期并行的产品线(如 release-x)
书签(bookmark)hg bookmark可移动指针,可删除短期特性开发(近似 Git 分支)

4.1 具名分支的创建与列举

hg branch feature-login
hg branches

实测回显:

marked working directory as branch feature-login
(branches are permanent and global, did you want a bookmark?)
feature-login                  1:5fff4790d71c
default                        0:722dc0302bce (inactive)

(branches are permanent and global, did you want a bookmark?) 是官方给的提示:如果你只是想临时开个分支,应该用 bookmark。具名分支一旦提交就无法删除名称,只能「关闭」。

4.2 切换与关闭分支

hg update default

实测回显:

0 files updated, 0 files merged, 1 files removed, 0 files unresolved

hg update 相当于 Git 的 checkout:改变工作区所在的父版本。切换后有文件被移除(分支上新增的文件回到 default 就不再存在),这是正常行为。

关闭分支(保留历史,不再出现在默认列表):

hg commit --close-branch -m "close feature-login"
hg branches
hg branches --closed

实测回显:

default                        4:30fff2a7b673
default                        4:30fff2a7b673
feature-login                  5:73340ff5c05b (closed)

--closed 才能看到已关闭分支。关闭不等于删除,历史仍可 hg update 回去。

4.3 书签

hg bookmark release-1.0
hg bookmark

实测回显:

 * release-1.0               4:30fff2a7b673

* 表示当前激活书签。切到别的分支时若未加 -f,会出现 (leaving bookmark release-1.0) 提示——书签会被「放下」但仍存在。

4.4 标签(tag)

hg tag v1.0
hg tags

实测回显:

tip                                4:30fff2a7b673
v1.0                               3:1ca4114af80b

hg tag 本身会产生一个 changeset(把标签名写入 .hgtags),所以打完标签仓库会多一笔提交——这是与 Git 轻量标签最大的差异,也是很多人误以为「标签把历史改了」的原因。

五、远程协作

5.1 克隆

hg clone /root/hg-demo /root/hg-demo-clone
cd /root/hg-demo-clone
hg paths

实测回显:

updating to branch default
5 files updated, 0 files merged, 0 files removed, 0 files unresolved
default = /root/hg-demo

克隆后 default 路径自动指向源仓库,这是 hg push/hg pull 的默认目标。

5.2 推送前先看会推什么

hg outgoing

实测回显:

comparing with /root/hg-demo
searching for changes
changeset:   6:0c47fcb5f970
tag:         tip
parent:      4:30fff2a7b673
user:        root <root@example.com>
date:        Tue Oct 27 16:25:27 2026 +0000
summary:     Add USAGE.txt

hg outgoing 列出「本地有、远端没有」的 changeset;hg incoming 反之。生产操作建议「先 outgoing/incoming,再 push/pull」,避免盲目推送。

5.3 推送与拉取

hg push

实测回显:

pushing to /root/hg-demo
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files

反向流程(在源仓库拉取协作库的提交):

hg incoming
hg pull
hg update

实测回显:

comparing with /root/hg-demo-clone
searching for changes
changeset:   7:cb259917018f
tag:         tip
...
1 files updated, 0 files merged, 0 files removed, 0 files unresolved

关键点:hg pull 只把 changeset 拉进本地仓库,不自动更新工作区;必须再 hg update 才能让磁盘文件变成最新。这一点与 Git 的 pull(fetch+merge)语义不同,是新手最常见的「拉完了代码怎么没变」问题。

5.4 内置 HTTP 服务

hg serve -R /root/hg-demo -p 8130 -a 0.0.0.0 &
hg clone http://127.0.0.1:8130/ /root/hg-http-client

实测回显:

requesting all changes
adding changesets
adding manifests
adding file changes
added 8 changesets with 7 changes to 6 files
new changesets 722dc0302bce:cb259917018f
updating to branch default
6 files updated, 0 files merged, 0 files removed, 0 files unresolved

hg serve 同时提供 Web 浏览界面与仓库访问协议,适合临时共享;长期对外服务应按安装篇的做法交给 systemd 托管,并配置 [web] 段的 allow_push 与 push_ssl。

六、差异与回退

6.1 工作区差异

hg diff

实测回显:

diff -r cb259917018f main.c
--- a/main.c	Tue Oct 27 16:25:45 2026 +0000
+++ b/main.c	Tue Oct 27 16:26:30 2026 +0000
@@ -3,3 +3,4 @@
     printf("hello hg\n");
     return 0;
 }
+// comment

diff -r <changeset> 表示「相对哪个版本」,不带参数即相对工作区父版本。

6.2 跨版本差异

hg diff -c 6
hg diff -r 0 -r 4 --stat

-c 看单个提交相对其父的改动;-r A -r B 看两个版本的差异。实测 hg diff -c 对新增文件会输出:

diff -r 722dc0302bce -r 607484cbb8b7 util.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util.c	Tue Oct 27 16:25:06 2026 +0000
@@ -0,0 +1,2 @@

/dev/null 表明该文件在旧版本不存在。

6.3 hg revert:放弃工作区改动

hg revert main.c
hg status

实测回显:

? main.c.orig

revert 把文件恢复到父版本,但会留下 .orig 备份(未跟踪状态)。要彻底丢弃改动,用 hg revert --no-backup main.c;要看 ? main.c.orig 之外是否还有残留,hg status 一眼可见。

6.4 hg backout:撤销已提交的变更

hg backout -r 2
hg log -l 1

实测回显:

removing util.c
created new head
changeset 8:e2fcd7b8a826 backs out changeset 2:607484cbb8b7
merging with changeset 8:e2fcd7b8a826
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
(branch merge, don't forget to commit)
@  changeset:   8:e2fcd7b8a826
|  tag:         tip
~  parent:      2:607484cbb8b7
   user:        root <root@example.com>
   summary:     Backout util.c

backout 的思路是「生成一个新提交来反向抵消旧提交」,历史不重写——这比 strip 安全得多。注意输出里的 created new head:若被撤销的提交后面还有提交,会产生多头,需要再合并一次(回显末行的 (branch merge, don't forget to commit) 就是在提醒这件事)。

💡 技术拓展:「撤销」的三种代价

手段是否改写历史风险适用
hg revert否(只动工作区)低丢弃未提交改动
hg backout否(新增反向提交)中(可能多头,需合并)撤销已推送的错误提交
hg strip是(删除 changeset)高(不可逆,他人仓库已有时无法收回)仅限本地未推送的误提交
团队仓库里默认只用前两种;strip 需扩展支持且必须确认该提交未外推。

七、合并与冲突处理

7.1 制造并识别冲突

hg merge feature-a

实测回显:

merging service.conf
warning: conflicts while merging service.conf! (edit, then use 'hg resolve --mark')
0 files updated, 0 files merged, 0 files removed, 1 files unresolved
use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon

三条处置线索都在输出里:编辑文件消解冲突 → hg resolve --mark 标记已解决 → 或 hg merge --abort 整体放弃。

hg status
hg resolve -l

实测回显:

M service.conf
? service.conf.orig
U service.conf

U 是「未解决」,hg resolve -l 是冲突清单的权威来源。? service.conf.orig 是合并前的备份,提交前应确认删除。

7.2 消解与收尾

# 编辑 service.conf,保留想要的最终内容,删除 <<<<<<< ======= >>>>>>> 标记
hg resolve --mark service.conf
hg commit -m "merge feature-a"
hg resolve -l

实测 hg resolve --mark 后 hg resolve -l 不再输出内容(无未解决项);hg status 中 U 转为 M。

7.3 放弃合并

hg merge --abort

--abort 会回到合并前状态,比手工逐个 revert 干净。合并中途如果已 hg resolve --mark 过部分文件,--abort 依然有效。

八、查询、导出与校验

8.1 定位与摘要

hg id
hg root
hg summary

实测回显:

22fa61e2d8df tip
/root/d-lab
parent: 1:22fa61e2d8df tip
 rev1
branch: default
commit: (clean)
update: (current)
phases: 2 draft

hg summary 一次给全「父版本、分支、书签、工作区是否干净、是否最新、阶段分布」,是进仓库第一眼该看的命令。commit: (clean) 表示无未提交改动;update: (current) 表示工作区就是分支 tip。

8.2 导出快照

hg archive /root/release-v1.tar.gz -r v1.0
tar tzf /root/release-v1.tar.gz | head -3

实测回显:

a.txt
v1

hg archive 导出指定版本的文件树,不含 .hg 元数据,适合做发布包。注意它不会带上未提交改动。

8.3 完整性校验

hg verify

实测回显:

checking changesets
checking manifests
crosschecking files in changesets and manifests
checking files
...

hg verify 是仓库级的 fsck:校验 changeset、manifest、文件内容三层以及交叉引用一致性。备份/迁移后必须跑一次,输出末尾无 error/warning 即通过。

8.4 图形化历史

hg log -G -l 5

实测回显(节选):

@    changeset:   3:1ca4114af80b
|\   tag:         tip
| |  parent:      2:607484cbb8b7
| |  parent:      1:5fff4790d71c
| |  user:        root <root@example.com>

-G 用 ASCII 图形展示分叉与合并,@ 标记当前工作区父版本,| 是分支线,/ \ 表示分叉/汇合。排障「历史为什么分叉了」时,一条 hg log -G 比翻十页 log 文本有效。

九、常用组合与运维脚本

9.1 每日开工检查

cd /root/hg-demo
hg summary
hg incoming | head -5

先看工作区是否干净、再看远端有没有新提交,避免在脏工作区上合并。

9.2 提交前自检

hg status
hg diff --stat
hg diff

三步:确认待提交文件集合、确认改动规模、确认改动内容。hg status 里出现 !(文件丢失)或 U(未解决冲突)时禁止提交。

9.3 发布打标签

hg update default
hg pull && hg update
hg tag -m "release v1.1" v1.1
hg push

顺序不能反:先落到目标分支并同步到最新,再打标签,最后推送(标签本身也是 changeset,必须推送才会共享)。

9.4 批量清理未跟踪文件

需先启用 purge 扩展:

hg purge --print
hg purge

--print 先预览将被删除的文件,确认后再执行。该命令不可恢复,务必先预览。

十、排障实录

10.1 hg pull 之后文件没变

根因:pull 只更新仓库数据,不动工作区。补一条 hg update 即可。回显特征为 1 files updated, 0 files merged, ...。

10.2 hg push 报 abort: push creates new remote head

根因:本地产生了新的头(常见于 backout 或未合并的并行提交)。处置顺序:先 hg pull → hg merge → hg commit → 再 hg push;强行用 --force 会制造远端多头,团队仓库禁用。

10.3 合并后 hg status 一直有 U

根因:只编辑了文件但忘了 hg resolve --mark。补标记后再提交;hg resolve -l 是确认是否还有未解决项的唯一权威。

10.4 hg commit 卡在编辑器里

根因:未传 -m,hg 调用了 ui.editor(实测为 vim)。要么写提交信息后 :wq,要么改用 hg commit -m "...",要么把 ui.editor 换成更轻的编辑器。

10.5 hg clone 到一半失败

根因多为网络中断或认证失败。clone 中断会留下半成品目录,直接删除重来比修复更快;HTTPS 源若报证书错误,检查 web.cacerts 指向的 CA 包是否完整,而不是关闭校验。

十一、参考链接