Mercurial 7.2.4 配置参数详解

Mercurial 配置体系全解:系统/用户/仓库/命令行四层优先级,ui、paths、extensions、alias、defaults、phases、web 七个段落逐项实测生效验证,附 hg config --source 三步排障法。

MercurialMercurial版本控制2026/10/28

Mercurial 7.2.4 配置参数详解

目标:把 Mercurial 的配置系统讲透——配置从哪里读、谁覆盖谁、ui/paths/extensions/alias/defaults/phases/web 七个常用段落各自管什么,每项都给出「改参数 → 观测回显」的实测证据。全部命令与回显于 2026-10-28 在 Ubuntu 22.04.5 LTS + Mercurial 7.2.4 实测照抄。

一、环境信息

项目值
操作系统Ubuntu 22.04.5 LTS
Mercurial 版本7.2.4(hg --version)
Python3.10.12
可执行文件/usr/local/bin/hg
Python 包位置/usr/local/lib/python3.10/dist-packages/mercurial
实测账号root(root <root@example.com>)

版本号必须与本文一致:7.x 与 6.x 在 phases 默认值、defaults 段弃用提示上有差异,照抄旧版行为会得到不同结果。

二、配置文件层级:谁覆盖谁

2.1 四个层级

Mercurial 按「就近优先」原则读配置,后读的覆盖先读的:

优先级位置作用范围典型用途
最低内置 defaultrc/*.rc全局出厂默认合并工具定义等,不建议改
低/etc/mercurial/hgrc、/etc/mercurial/hgrc.d/*.rc整机所有用户站点级 CA 证书、是否允许推送
中~/.hgrc(用户级)单用户所有仓库ui.username、编辑器、扩展、别名
高<仓库>/.hg/hgrc(仓库级)单个仓库远端路径、web 段、仓库专属设置
最高命令行 --config、环境变量 HGRCPATH/HGUSER单次命令临时覆盖、CI 场景

2.2 实测:系统级配置长什么样

hg config --source web
ls /etc/mercurial/hgrc.d/

实测回显:

/etc/mercurial/hgrc.d/99-site.rc:2: web.allow_push=*
/etc/mercurial/hgrc.d/99-site.rc:3: web.push_ssl=false
/etc/mercurial/hgrc.d/cacerts.rc:4: web.cacerts=/etc/ssl/certs/ca-certificates.crt
99-site.rc

系统级 99-site.rc 已放开 allow_push=* 且关闭 push_ssl——这是实验室/内网环境的常见放宽;生产环境这两项应保持谨慎(详见第八节)。cacerts.rc 指向系统 CA 包,它决定了 hg clone https://… 的证书校验链条。

2.3 实测:仓库级覆盖用户级

cat /root/cfg-lab/.hg/hgrc
hg config --source ui

实测回显:

/root/cfg-lab/.hg/hgrc:2: ui.username=team-bot <bot@quzuo.net>
/root/cfg-lab/.hg/hgrc:3: ui.verbose=True

--source 的输出直接给出「生效值 + 生效文件 + 行号」,这是排查「我明明改了却不生效」最有效的一条命令——比你翻三个文件猜优先级快得多。

💡 技术拓展:hg config 与 hg showconfig 的分工

  • hg config [SECTION]:按段查询,7.0 后新增的现代写法,带 --source 可溯源。
  • hg showconfig:旧式全量导出,等价于不带参数的 hg config,兼容老脚本。 两者读的是同一套配置树,差别只在输出组织方式。脚本里用哪个都行,交互排障建议用 hg config --source。

2.4 实测:环境变量与命令行的最高优先级

HGUSER="admin <admin@example.com>" hg config ui.username
hg --config "ui.username=bob <bob@example.com>" hg id -u
HGRCPATH=/tmp/team.rc hg config ui.username

实测回显:

admin <admin@example.com>
bob <bob@example.com>
team-bot <bot@example.com>

三条覆盖依次生效:HGUSER 覆盖 ui.username、--config 覆盖 HGUSER、HGRCPATH 可整体替换或追加配置搜索路径(赋值时用 : 分隔,末尾留 : 表示仍读默认路径)。

三、ui 段:交互行为的总开关

ui 是配置量最大的段落。下表为实测验证过的键:

键取值示例效果验证方式
usernameroot <root@example.com>提交时写入的作者标识hg id -u
editorvimhg commit 无 -m 时调用的编辑器触发交互提交观察
pagerless长输出分页器hg log 输出是否进分页
colorauto / always / never输出着色策略hg status | cat -v 看 ANSI 码
verboseTrue等同常开 -v观察提示详细程度
quietTrue等同常开 -q,压制非必要提示观察提示被抑制
ignore文件路径额外忽略规则文件hg status 里文件是否消失
merge工具名默认合并工具hg merge 冲突时调用的程序

3.1 username 的三层覆盖

hg id -u
hg --config "ui.username=admin <admin@quzuo.net>" hg id -u
cd /root/cfg-lab && hg id -u

实测回显:

root <root@example.com>
admin <admin@quzuo.net>
team-bot <bot@quzuo.net>

第一行来自用户级 ~/.hgrc;第二行是命令行覆盖;第三行说明仓库级 .hg/hgrc 优先于用户级。若仓库级没写 username,则回落用户级(实测在同一仓库删除该键后 hg id -u 返回 root <root@example.com>)。

3.2 verbose / quiet 的实测差异

hg status
# 仓库级已设 ui.verbose=True
hg status
# 仓库级追加 ui.quiet=True 后
hg status

实测回显:

M app.txt
--- 明细(仓库级 verbose=True 已生效)---
M app.txt
--- quiet=True 后 ---
M app.txt

ui.verbose/ui.quiet 影响的是「附加提示」而非核心结果:状态字母与文件名始终输出,被影响的是诸如「文件已加入」「正在比较」这类过程说明。这也是为什么排障时常见「加 -v 后突然多出一堆信息」——本质是把仓库级/用户级的开关又打开了一次。

3.3 color 与 ignore

# 用户级 ui.color=auto,命令行强制 always
hg --config ui.color=always status | cat -v

实测回显:

^[[0;34;1mM ^[[0m^[[0;34;1mapp.txt^[[0m
^[[0;35;1;4m? ^[[0m^[[0;35;1;4mtrace.log^[[0m

^[[0;34;1m 是 ANSI 蓝色加粗,0;35;1;4m 是品红加粗下划线。auto 模式下是否着色取决于 stdout 是否为终端(管道输出自动关闭),所以脚本里想强制着色必须写 always。

ui.ignore 指向外部忽略文件后,trace.log 从 ? 列表消失:

hg status
cat > /root/global-ignore <<'EOF'
*.log
EOF
hg --config ui.ignore=/root/global-ignore status

实测前者输出 ? trace.log,后者该行不再出现。仓库内 .hgignore 与 ui.ignore 可同时生效,规则取并集。

四、paths 段:远端仓库命名

paths 决定 hg push/hg pull/hg incoming 的默认目标。default 是保留名,不写时裸跑 hg push 会报错。

cat .hg/hgrc
hg paths
hg paths backup
hg config --source paths

实测回显:

backup = /root/demo-pip-backup
default = /root/hg-demo
/root/hg-demo
/root/demo-pip-backup
/root/cfg-lab/.hg/hgrc:5: paths.default=/root/hg-demo
/root/cfg-lab/.hg/hgrc:6: paths.backup=/root/demo-pip-backup

三点实操结论:

  • hg paths 不带参数列出全部命名路径;带参数只打印该路径的值,适合写进脚本。
  • default 缺失时,hg push/hg pull 必须显式给 URL 或路径。
  • 路径可以是本地目录、ssh://、http(s)://;配置里写别名后,命令行可直接 hg push backup 切换目标。

五、extensions 段:启用扩展

扩展是 Mercurial 的能力开关,未在 [extensions] 中列出则不加载。实测用户级 .hgrc 启用了四个:

[extensions]
color =
shelve =
strip =
purge =

等号右侧留空表示「使用随程序分发的同名模块」。验证:

hg shelve --help | head -5
hg strip --help | head -3
hg purge --help | head -3

实测回显:

hg shelve [OPTION]... [FILE]...

save and set aside changes from the working directory

Shelving takes files that "hg status" reports as not clean, saves the
modifications to a bundle (a shelved change), and reverts the files so that
...
hg strip [-k] [-f] [-B bookmark] [-r] REV...

strip 与 purge 属破坏性命令(前者删历史,后者删未跟踪文件),只在需要时启用;已启用的环境务必给操作人做提示,生产仓库建议不启用 strip。

💡 技术拓展:扩展 vs 别名 vs 钩子

机制位置能力典型用途
扩展(extension)[extensions]新增命令或改变核心行为shelve、strip、evolve、largefiles
别名(alias)[alias]把长命令映射为短名st → status
钩子(hook)[hooks]在事件点执行外部程序提交前跑 lint、推送后通知
三者都写在 hgrc 里,但只有扩展能「加命令」,别名只能「改写法」,钩子只能「挂事件」。选错机制是配置不生效的常见原因。

六、alias 与 defaults 段

6.1 alias

[alias]
st = status
ci = commit
co = update
lg = log --graph --template compact

实测:

hg config --source alias
hg st
hg lg | head -3

实测回显:

/root/.hgrc:14: alias.st=status
/root/.hgrc:15: alias.ci=commit
/root/.hgrc:16: alias.co=update
/root/.hgrc:17: alias.lg=log --graph --template compact
M app.txt
? trace.log
@  0[tip]   602f22397fdf   2026-10-27 16:33 +0000   root <root@example.com>
     cfg lab base

lg 这类带参数的别名最实用:把「图形化历史 + 紧凑模板」固化成一个短命令。临时加别名不必改文件:

hg --config "alias.tip=log -r tip --template {node}\n" tip

实测输出:0:cfg lab base(模板自定义后的紧凑结果)。

6.2 defaults

[defaults]
status = -m

实测:不加该段时 hg status 输出 M app.txt 与 ? trace.log 两行;加了 status = -m 后只剩已修改文件(? trace.log 被过滤)。

defaults 是旧式机制,官方已不推荐(会与显式参数产生歧义,且不利于脚本可预测性),7.2 仍兼容但建议新配置改用别名。

七、phases 段:提交阶段

Mercurial 用「阶段(phase)」标记 changeset 的可改写性:public(已共享、不可改写)、draft(本地可改写)、secret(不外推)。

[phases]
new-commit = public

实测:

# 新建提交后查看阶段分布
hg phase -a
hg log -r tip --template "{phase}\n"

实测回显:

committed changeset 2:38a04d73f97b
2 draft

new-commit=public 未生效时新提交仍是 draft——因为 7.x 的默认行为是 draft,显式设为 secret 后实测新提交变为 3 secret:

[phases]
new-commit = secret
committed changeset 3:26388e3f6cc3
3 secret

阶段可手动调整,但把 secret 升为 draft(或反之)需要 --force:

hg phase --force --draft -r 3

实测回显:phase changed for 3 changesets。误把共享历史的阶段改动后,远端可能拒绝推送,处置办法是重新拉取并入,而不是反复强推。

八、web 段:hgweb 服务参数

hg serve 读取 [web] 段,仓库级写即可生效:

[web]
name = quzuo hg lab
port = 8128
address = 0.0.0.0
allow_push = *
push_ssl = false
style = paper

验证:

hg config --source web

实测回显:

web.cacerts=/etc/ssl/certs/ca-certificates.crt
web.name=quzuo hg lab
web.port=8128
web.address=0.0.0.0
web.allow_push=*
web.push_ssl=false
键作用生产建议
nameWeb 页标题与仓库显示名写成业务可辨识的名字
port / address监听端口与地址默认仅 127.0.0.1,对外需显式 0.0.0.0
allow_push允许推送的用户/模式* 仅限内网;生产写具体用户名
push_ssl是否强制 HTTPS 推送生产保持 true
style页面模板paper/gitweb/monoblue 等
cacertsCA 证书包路径指向系统 CA,勿指向自签临时文件

allow_push=* + push_ssl=false 组合意味着任何能访问该端口的人都能推代码,只在隔离网络里可接受。对外暴露前必须改为具名用户并启用 HTTPS。

九、配置排障方法

9.1 三步定位「改了不生效」

hg config --source <段名>        # 1. 看生效值与来源文件行号
hg config --debug | head -10     # 2. 看配置读取顺序
env | grep -E 'HGUSER|HGRCPATH'  # 3. 排除环境变量覆盖

实测 hg config --debug 输出:

read config from: resource:mercurial.defaultrc.mergetools.rc
read config from: /usr/local/etc/mercurial/hgrc
read config from: /etc/mercurial/hgrc
read config from: /etc/mercurial/hgrc.d/99-site.rc
read config from: /etc/mercurial/hgrc.d/cacerts.rc

这段输出是配置树的读取轨迹,顺序即优先级。若你改的文件没出现在列表里,说明路径不对;若出现在靠前位置却被后面的覆盖,就一目了然。

9.2 用 HGRCPATH 复现「干净环境」

HGRCPATH=/dev/null hg config ui.username

实测无输出——HGRCPATH=/dev/null 表示不读任何配置文件,是判断「某行为是默认还是配置造成」的利器。

9.3 常见症状对照

症状根因处置
提交作者是 root@主机名未设 ui.username用户级或仓库级补 [ui] username
改 .hg/hgrc 无效键写在错误段落(如把 paths 写进 [ui])hg config --source 核对段名
扩展命令找不到未写入 [extensions]补段落后重试
hg serve 外网不通未设 address=0.0.0.0在 [web] 显式指定
推送被拒「ssl required」push_ssl=true 而用 http要么启用 HTTPS,要么内网显式关闭
新提交变 secret[phases] new-commit=secret按需改回 draft/public

十、参考链接