Search code examples
pythonmercurialmercurial-api

mercurial API: how do I get the 40 digit revision hash from incoming command?


I am using the python mercurial API in my project.

from mercurial import ui, hg, commands
from mercurial.node import hex

user_id = ui.ui()
hg_repo = hg.repository(user_id, '/path/to/repo')

hg_repo.ui.pushbuffer()
some_is_coming = commands.incoming(hg_repo.ui, hg_repo, source='default',
                                       bundle=None, force=False)
if some_is_coming:
    output = hg_repo.ui.popbuffer()

In [95]: output
Out[95]: 'comparing with ssh:host-name\nsearching for changes\nchangeset:   1:e74dcb2eb5e1\ntag:         tip\nuser:        that-is-me\ndate:        Fri Nov 06 12:26:53 2015 +0100\nsummary:     added input.txt\n\n'

Extracting the short node info e74dcb2eb5e1 will be easy. What I really need, however, is the 40 digit hex revision id. Is there any way to retrieve this information without pulling the repo first?


Solution

  • You need to specify a template that provides the full node hash as part of its output. Also, commands.incoming returns a numeric error code, where zero indicates success. I.e. you need something like:

    from mercurial import ui, hg, commands
    from mercurial.node import hex
    
    user_id = ui.ui()
    hg_repo = hg.repository(user_id, '/path/to/repo')
    
    hg_repo.ui.pushbuffer()
    command_result = commands.incoming(hg_repo.ui, hg_repo, source='default',
        bundle=None, force=False, template="json")
    if command_result == 0:
        output = hg_repo.ui.popbuffer()
        print output
    

    Two more things: First, you'll also get diagnostic output ("comparing with ..."), which can be suppressed via -q (or ui.setconfig("ui", "quiet", "yes")). However, note that this option will also affect the default templates and you may have to provide your own one. Second, setting the environment variable HGPLAIN is recommended so that aliases and defaults from your .hgrc are ignored (see hg help scripting).

    Alternatively, you can use the Mercurial command server as implemented in hglib (available via pip install python-hglib).

    import hglib
    
    client = hglib.open(".")
    # Standard implementation of incoming, which returns a list of tuples.
    # force=False and bundle=None are the defaults, so we don't need to
    # provide them here.
    print client.incoming(path="default")
    # Or the raw command output with a custom template.
    changeset = "[ {rev|json}, {node|json}, {author|json}, {desc|json}, {branch|json}, {bookmarks|json}, {tags|json}, {date|json} ]\n"
    print client.rawcommand(["incoming", "-q", "-T" + changeset])