简体   繁体   中英

Overload the pull command in a Hg extension

I am trying to debug a Mercurial extension. This extension adds some code that should be executed when a pull is performed. The original author setup this hook by changing the class of the repository object.

Here is the relevant code (which is actually a valid Mercurial extension):

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

When I perform a hg pull with this extension enabled, here is the output:

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

Is this a reasonable way to inject the code of the extension in the pull command? Why is the "pull called" statement never reached?

I use Mercurial 3.4.1 on Windows 7 with python 2.7.5.

According to the code ( mercurial/extensions.py ), this is the only reasonable way to extend the repository object ( https://www.mercurial-scm.org/repo/hg/file/ff5172c83002/mercurial/extensions.py#l227 ).

However, I looked at the code and the localrepo object does not appear to have a pull method at this point, so I suspect this is why your "pull called" print statement never shows up -- nothing calls it because it's not expected to exist!

There are better ways to inject code into pulls, depending on what you're trying to accomplish. For example, if you simply want to run something whenever the a pull is issued, prefer instead to wrap the exchange.pull function:

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

For your specific use case, I'd suggest creating a method with the following code:

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

In the extsetup method, add a line like this:

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

Finally, in the reposetup method, you can remove the projrcrepo class stuff entirely. Hopefully that will get you the behavior you're looking for.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM