You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助Mercurial远程Head ID缓存方案:实现类似Git的即时hg outgoing功能

解决方案

一、现成扩展:remoteheads

  • 该扩展原生支持远程仓库头节点ID的自动缓存,会在pull/push操作完成后自动更新缓存数据。
  • 启用方式:在仓库的.hgrc配置文件中添加以下内容:
[extensions]
remoteheads =
  • 使用方法:执行hg remoteheads outgoing即可快速查看本地待推送的变更集,全程无需网络请求,直接读取本地缓存的远程heads数据。

二、手动编写钩子脚本实现

如果不想依赖第三方扩展,可以通过自定义钩子+命令的方式实现需求:

1. 配置钩子(修改.hgrc)

[hooks]
post-pull.cache-remote-heads = python:hooks.cache_remote_heads
post-push.cache-remote-heads = python:hooks.cache_remote_heads

2. 编写钩子逻辑(新建hooks.py放在仓库根目录)

import os
from mercurial import ui, hg, util

def cache_remote_heads(ui, repo, hooktype, node=None, source=None, **kwargs):
    # 遍历所有配置的远程仓库
    for name, url in repo.ui.configitems('paths'):
        try:
            # 获取远程仓库的heads
            remote_repo = hg.repository(ui.ui(), url)
            remote_heads = remote_repo.heads()
            # 创建缓存目录并写入数据
            cache_dir = os.path.join(repo.root, '.hg', 'cached_remote_heads')
            util.makedirs(cache_dir, exist_ok=True)
            cache_file = os.path.join(cache_dir, name)
            with open(cache_file, 'w') as f:
                f.write('\n'.join(str(h) for h in remote_heads))
            ui.status(f"已缓存远程仓库[{name}]的heads信息\n")
        except Exception as e:
            ui.warn(f"缓存远程仓库[{name}]heads失败: {str(e)}\n")
    return 0

3. 自定义outgoingcached命令(新建outgoingcache.py放在仓库根目录)

先在.hgrc中启用该自定义扩展:

[extensions]
outgoingcache = ./outgoingcache.py

然后编写命令逻辑:

from mercurial import cmdutil, ui, util
from mercurial.node import short

def cmd_outgoingcached(ui, repo, dest='default', **opts):
    cache_file = os.path.join(repo.root, '.hg', 'cached_remote_heads', dest)
    if not os.path.exists(cache_file):
        ui.warn(f"未找到远程仓库[{dest}]的缓存heads,请先执行hg pull\n")
        return 1
    
    # 读取缓存的远程heads
    with open(cache_file, 'r') as f:
        remote_heads = [util.bin(h.strip()) for h in f if h.strip()]
    
    # 计算本地待推送的变更集
    revs = repo.revs(f"not ancestor({remote_heads})")
    if not revs:
        ui.status("无待推送的变更集\n")
        return 0
    
    ui.status(f"远程仓库[{dest}]共有{len(revs)}个待推送变更集:\n")
    for rev in revs:
        ctx = repo[rev]
        ui.write(f"{short(ctx.node())} [{ctx.branch()}] {ctx.description().splitlines()[0]}\n")
    return 0

cmdtable = {
    'outgoingcached': (
        cmd_outgoingcached,
        [],
        'hg outgoingcached [DEST]'
    )
}

之后执行hg outgoingcached就能快速获取待推送的变更集列表,无需网络请求。

三、注意事项

  • 缓存的远程heads仅在pull/push后更新,若远程仓库被其他人修改,缓存数据会过时,可定期执行hg pull -n(仅拉取heads不更新本地代码)手动刷新缓存。
  • 钩子脚本支持多远程仓库,可根据实际需求调整缓存逻辑。

内容的提问来源于stack exchange,提问作者Dinu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 21:36:26