2015-06-22 37 views
4

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

下面是相关的代码(这实际上是一个有效的水银扩展名):

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。

回答

5

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

不过,我看着代码和localrepo对象不会出现有在这一点上pull方法,所以我怀疑这就是为什么你的“拉名为” print语句一直没有出现 - 没有什么要求,因为它是预计不存在!

有很好的方法可以将代码注入拉取决于你想要完成什么。例如,如果您只是想只要一拉发出运行的东西,而是喜欢包裹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类的东西。希望这会让你找到你想要的行为。

+0

感谢您的回答。我试图用你的建议来调整代码,但目前为止没有成功(我不是Python开发人员,有时候我有点失落)。实际上,我试图完成的是让projrc扩展工作。我提交了[问题](https://bitbucket.org/aragost/projrc/issue/2/no-projrc-update-on-pull#comment-18753387)描述了我的问题,但由于我没有得到反馈我试图自己修复它(在SO的帮助下,显然!)。 – barjak

+2

我检出了mercurial的代码,并且在localrepo类中没有看到任何拉出方法,这可能是为什么代码没有运行的更好解释。现在我会更新我的答案,提供一些更具体的想法,我知道你想要完成什么。 – ryanmce

+2

感谢您的跟进。我可以按照你使用'exchange :: pull'的建议来工作。我为Projrc项目创建了一个[pull request](https://bitbucket.org/aragost/projrc/pull-request/5/make-projrc-compatible-with-mercurial-32/diff)。你介意看看我的差异,并告诉我,如果你认为没关系? – barjak