在Hg扩展中重载pull命令

时间:2015-06-22 14:43:09

标签: python mercurial mercurial-extension

我正在尝试调试Mercurial扩展。此扩展添加了一些应在执行pull时执行的代码。原作者通过更改存储库对象的类来设置此挂钩。

以下是相关代码(实际上是有效的Mercurial扩展名):

def reposetup(ui, repo):
    class myrepo(repo.__class__):
        def pull(self, remote, heads=None, force=False):
            print "pull called"
            return super(myrepo, self).pull(remote, heads, force)

    print "reposetup called"
    if repo.local():
        print "repo is local"
        repo.__class__ = myrepo

当我启用此扩展程序时执行hg pull时,输出结果为:

# hg pull
reposetup called
repo is local
pulling from ssh://hgbox/myrepo
reposetup called
searching for changes
no changes found

这是在pull命令中注入扩展代码的合理方法吗?为什么"拉叫"声明从未到达?

我在Windows 7上使用Mercurial 3.4.1和python 2.7.5。

1 个答案:

答案 0 :(得分:5)

根据代码(mercurial/extensions.py),这是唯一扩展存储库对象(https://www.mercurial-scm.org/repo/hg/file/ff5172c83002/mercurial/extensions.py#l227)的合理方式。

但是,我查看了代码,此时localrepo对象似乎没有pull方法,所以我怀疑这就是为什么你的"拉叫" print语句永远不会出现 - 没有任何东西可以调用它,因为它不会存在!

有更好的方法可以将代码注入到pull中,具体取决于您尝试完成的任务。例如,如果你只想在发出pull时运行某些东西,那么更喜欢包装exchange.pull函数:

extensions.wrapfunction(exchange, 'pull', my_pull_function)

对于您的具体用例,我建议使用以下代码创建方法:

def expull(orig, repo, remote, *args, **kwargs):
    transferprojrc(repo.ui, repo, remote)
    return orig(repo, remote, *args, **kwargs)

在extsetup方法中,添加如下所示的行:

extensions.wrapfunction(exchange, 'pull', expull)

最后,在reposetup方法中,您可以完全删除projrcrepo类的东西。希望这会让你得到你正在寻找的行为。