Why you shouldn't use Mercurial's internal API

Mercurial's internals are continually evolving to be simpler, more consistent, and more powerful, a process we hope will continue for the foreseeable future. Unfortunately, this process means we will regularly be changing interfaces in ways that break third-party code in various (mostly minor) ways.

For the vast majority of third party code, the best approach is to use Mercurial's published, documented, and stable API: the command line interface.

{X} There are NO guarantees that third-party code calling into Mercurial's internals won't break from release to release.

{X} Use of Mercurial's internal API very likely makes your code subject to Mercurial's license. Before going any further, read the License page.

/!\ If you do use Mercurial's API for published third-party code, we expect you to test your code before each major Mercurial release (see TimeBasedReleasePlan). This will prevent various bug reports from your users when they upgrade their copy of Mercurial.

Changes after 1.5

Changes after 1.4

Changes after 1.3

Changes from 1.2 to 1.3

    # before
    ui = ui.ui(parentui=parentui, interactive=False)

    # after
    ui = baseui.copy() # there's no longer a parent/child concept
    ui.setconfig('ui', 'interactive', 'off')

Changes from 1.1 to 1.2

Changes from 1.0 to 1.1

    # before
    for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
                                             node=ctx.node()):

    # after

    m = cmdutil.match(repo, pats, opts)
    for abs in ctx.walk(m):
        rel = m.rel()

    # before
    def status(self, node1=None, node2=None, files=[], match=util.always,
               list_ignored=False, list_clean=False, list_unknown=True):

    # after
    def status(self, node1='.', node2=None, match=None,
               ignored=False, clean=False, unknown=False):

    # before
    a = manifest.linkrev(node)
    b = manifest.linkrev(manifest.node(rev))

    # after
    a = manifest.linkrev(manifest.rev(node))
    b = manifest.linkrev(rev)

    # before
    displayer = cmdutil.show_changeset(ui, repo, opts)
    displayer.show(rev, node)

    # after
    displayer = cmdutil.show_changeset(ui, repo, opts)
    displayer.show(repo[rev]) 

    # before
    keep = { }
    patch.applydiff(..., keep, ...)
    
    print keep
    { 'fname': ( action, other ) }

    # after
    keep = { }
    patch.applydiff(..., keep, ...)
    
    print keep
    { 'fname': action }

as before, action will only be set to anything not-None if the patch is in git-format.

1. Template changes in 1.0

If you use your own template set (particularly for hgweb), here are some relevant changes.