使用Python进行Mercurial脚本编写

30 投票
7 回答
20845 浏览
提问于 2025-04-15 13:01

我想在Python中以编程的方式获取Mercurial的修订号/ID(它是一个哈希值,不是普通的数字)。

这样做的原因是我想把这个修订号加到我们网站的CSS和JS文件里,像这样:

<link rel="stylesheet" href="example.css?{% mercurial_revision "example.css" %}" />

这样每当样式表有改动时,它就会生成一个新的网址,而不再使用旧的缓存版本。

或者如果你知道哪里有好的Mercurial Python模块的文档,那也会很有帮助。我好像找不到相关的资料。

我的解决方案

我最终使用了subprocess模块来运行一个命令,以获取hg节点。我选择这个方法是因为API不一定会保持不变,但bash接口可能会保持稳定:

import subprocess

def get_hg_rev(file_path):
    pipe = subprocess.Popen(
        ["hg", "log", "-l", "1", "--template", "{node}", file_path],
        stdout=subprocess.PIPE
        )
    return pipe.stdout.read()

示例用法:

> path_to_file = "/home/jim/workspace/lgr/pinax/projects/lgr/site_media/base.css"
> get_hg_rev(path_to_file)
'0ed525cf38a7b7f4f1321763d964a39327db97c4'

7 个回答

6

这是一个更新过的、更简洁的子进程版本(使用了 .check_output(),这个功能在 Python 2.7/3.1 中新增),我在我的 Django 设置文件中用它来做一个简单的端到端部署检查(我把它放在 HTML 注释里):

import subprocess

HG_REV = subprocess.check_output(['hg', 'id', '--id']).strip()

如果你不想让一些奇怪的小问题影响启动,可以把它放在 try 语句里:

try:
    HG_REV = subprocess.check_output(['hg', 'id', '--id']).strip()
except OSError:
    HG_REV = "? (Couldn't find hg)"
except subprocess.CalledProcessError as e:
    HG_REV = "? (Error {})".format(e.returncode)
except Exception:  # don't use bare 'except', mis-catches Ctrl-C and more
    # should never have to deal with a hangup 
    HG_REV = "???"
9

你是指这个文档吗?
需要注意的是,正如页面上所说的,实际上并没有一个官方的API,因为他们保留随时更改它的权利。不过,你可以查看最近几个版本的变更列表,内容并不是很多。

15

确实没有官方的API,但你可以通过阅读其他扩展来了解一些最佳实践,特别是那些和hg一起打包的扩展。针对这个具体的问题,我会这样做:

from mercurial import ui, hg
from mercurial.node import hex

repo = hg.repository('/path/to/repo/root', ui.ui())
fctx = repo.filectx('/path/to/file', 'tip')
hexnode = hex(fctx.node())

更新:有一段时间参数的顺序发生了变化,现在是这样的:

   repo = hg.repository(ui.ui(), '/path/to/repo/root' )

撰写回答