我正在尝试调试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。
答案 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类的东西。希望这会让你得到你正在寻找的行为。