在Hg扩展中重载pull命令

bar*_*jak 4 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
Run Code Online (Sandbox Code Playgroud)

hg pull启用此扩展时执行a 时,输出如下:

# hg pull
reposetup called
repo is local
pulling from ssh://hgbox/myrepo
reposetup called
searching for changes
no changes found
Run Code Online (Sandbox Code Playgroud)

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

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

rya*_*mce 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)
Run Code Online (Sandbox Code Playgroud)

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

def expull(orig, repo, remote, *args, **kwargs):
    transferprojrc(repo.ui, repo, remote)
    return orig(repo, remote, *args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

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

extensions.wrapfunction(exchange, 'pull', expull)
Run Code Online (Sandbox Code Playgroud)

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

  • 我查看了mercurial的代码,我在localrepo类中没有看到任何pull方法,这可能更好地解释了为什么代码没有运行而不是我的第一个猜测.现在,我知道你要完成什么,我会用更具体的想法更新我的答案. (2认同)
  • 感谢您的跟进.我能够通过遵循你使用`exchange :: pull`的建议来使它工作.我在Projrc项目中创建了一个[pull request](https://bitbucket.org/aragost/projrc/pull-request/5/make-projrc-compatible-with-mercurial-32/diff).你介意看看我的差异并告诉我你是否觉得它没问题? (2认同)