Search code examples
pythonmercurialrevision

Mercurial scripting with python


I am trying to get the mercurial revision number/id (it's a hash not a number) programmatically in python.

The reason is that I want to add it to the css/js files on our website like so:

<link rel="stylesheet" href="example.css?{% mercurial_revision "example.css" %}" />

So that whenever a change is made to the stylesheet, it will get a new url and no longer use the old cached version.

OR if you know where to find good documentation for the mercurial python module, that would also be helpful. I can't seem to find it anywhere.

My Solution

I ended up using subprocess to just run a command that gets the hg node. I chose this solution because the api is not guaranteed to stay the same, but the bash interface probably will:

import subprocess

def get_hg_rev(file_path):
    pipe = subprocess.Popen(
        ["hg", "log", "-l", "1", "--template", "{node}", file_path],
        stdout=subprocess.PIPE
        )
    return pipe.stdout.read()

example use:

> path_to_file = "/home/jim/workspace/lgr/pinax/projects/lgr/site_media/base.css"
> get_hg_rev(path_to_file)
'0ed525cf38a7b7f4f1321763d964a39327db97c4'

Solution

  • It's true there's no official API, but you can get an idea about best practices by reading other extensions, particularly those bundled with hg. For this particular problem, I would do something like this:

    from mercurial import ui, hg
    from mercurial.node import hex
    
    repo = hg.repository('/path/to/repo/root', ui.ui())
    fctx = repo.filectx('/path/to/file', 'tip')
    hexnode = hex(fctx.node())
    

    Update At some point the parameter order changed, now it's like this:

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