我正在尝试调试 Mercurial 扩展。此扩展添加了一些应在执行 pull
时执行的代码。原作者通过改变存储库对象的类来设置这个钩子(Hook)。
这是相关的代码(实际上是一个有效的 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
命令中注入(inject)扩展代码的合理方法吗?为什么从未达到“拉取”语句?我在 Windows 7 上使用 Mercurial 3.4.1 和 python 2.7.5。
最佳答案
根据代码 ( mercurial/extensions.py
),这是扩展存储库对象 ( https://www.mercurial-scm.org/repo/hg/file/ff5172c83002/mercurial/extensions.py#l227 ) 的唯一合理方法。
但是,我查看了代码,此时 localrepo
对象似乎没有 pull
方法,所以我怀疑这就是为什么您的“pull called”打印语句永远不会出现的原因——没有任何东西调用它,因为它不应该存在!
有更好的方法将代码注入(inject)到 pull 中,这取决于您要完成的任务。例如,如果您只想在发出 a 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 类的内容。希望这会让你得到你正在寻找的行为。
关于python - 在 Hg 扩展中重载 pull 命令,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30982884/