Mercurial预提交钩子:如何连接当前目录中的Python程序?

9 投票
1 回答
3415 浏览
提问于 2025-04-16 22:17

我正在尝试创建一个Mercurial的钩子,这个钩子会在提交代码推送到主仓库时运行。我写了一个下面的python脚本:

# commit.py

from mercurial import ui, hg
from mercurial.i18n import gettext as _

def getV1ID(ui, repo, **kwargs):
    ui.write("The hook works!!!")
    v1id = ui.prompt('Enter the VersionOne ID')
    ui.write('VersionOne ID: '+v1id)

对于每个分支,这个 commit.py 脚本都是复制的,因为它包含了一些在代码推送到主仓库之前需要运行的机制。只有当这些推送前的机制通过后,推送才会成功。用户可以根据自己正在做的项目修改本地的 commit.py,这样他们就可以只运行那些特定的推送前操作。而且每个人可能同时在做多个项目。因此, commit.py 不能是一个放在 .hg 文件夹里的全局python脚本。

为了让Mercurial运行本地的 commit.py,我在我的 mercurial.ini 文件(在 C:\Users\UserName\mercurial.ini)中添加了以下语句:

[hooks]
prechangegroup = python:./commit.py:getV1ID

如果我把这个python脚本放在 .hg 文件夹里,它就能运行,但如果这样做就不行。有没有人能帮我解答这个问题?非常感谢。

1 个回答

6

我在IRC上找到了这个关于Mercurial的解决方案。正如我在评论中提到的,钩子(hook)所用的脚本应该是一个绝对路径,或者是PYTHONPATH中的一个Python模块。因此,pmezard在IRC上建议我应该有一个固定的脚本来调用本地的commit.py。这可以通过下面的方式实现:

mercurial.ini文件中,设置一个指向用户主目录下.hg目录中的“全局”Python脚本,如下所示:

[hooks]
preoutgoing = python:%USERPROFILE%\.hg\commit.py:run

这个“全局”Python脚本commit.py大致长这样:

from mercurial import ui, hg
import os

class Chdir:
    def __init__(self, newPath):
        self.savedPath = os.getcwd()
        os.chdir(newPath)

    def __enter__(self):
        return self

    def __exit__(self, type, value, traceback):
        os.chdir(self.savedPath)

def run(ui, repo, **kwargs):
    if kwargs['source'] == 'push':
        with Chdir(repo.root) as dirchanged:
            import localcommit
            sys.exit(localcommit.main(ui, repo, **kwargs))

然后,位于仓库目录中的localcommit.py会被这个“全局”提交脚本运行,这样每个仓库就可以维护自己的定制提交脚本。

撰写回答