Mercurial 7.2.4 常用 CLI 命令详解
Mercurial 7.2.4 命令实战全集:建库提交、具名分支与书签、clone/push/pull 远程协作、diff/revert/backout 回退、merge 冲突处理、verify 校验,附每日开工自检与发布打标签脚本,全部实测回显。
Mercurial 7.2.4 常用 CLI 命令详解
目标:把
hg日常会用到的命令按「建库提交 → 分支合并 → 远程协作 → 差异回退 → 冲突处理 → 查询校验」六类串成可直接照抄的操作序列,每条命令的输入与回显都来自 2026-10-28 在 Ubuntu 22.04.5 LTS + Mercurial 7.2.4 的真实执行。
一、环境信息
| 项目 | 值 |
|---|---|
| 操作系统 | Ubuntu 22.04.5 LTS |
| Mercurial | 7.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 包是否完整,而不是关闭校验。
十一、参考链接
- Mercurial 命令手册:
https://www.mercurial-scm.org/doc/hg.1.html - Mercurial 官方教程:
https://www.mercurial-scm.org/guide - 同专栏:《Mercurial 介绍与选型指南》
- 同专栏:《Ubuntu 22.04 安装 Mercurial 7.2.4 指南》
- 同专栏:《Mercurial 7.2.4 配置参数详解》