Differences between revisions 29 and 30
Revision 29 as of 2007-01-17 21:07:46
Size: 5320
Comment: Add links to extension pages and minor editing
Revision 30 as of 2007-01-18 01:14:50
Size: 4434
Comment: Add contents to write extensions
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
Mercurial features an extension mechanism for adding new commands. It allows you to create new features and use them directly from the main hg command line. = Writing Mercurial extensions =
Line 3: Line 3:
== Bundled extensions == Mercurial features an extension mechanism for adding new commands.
Line 5: Line 5:
The following extensions are distributed with Mercurial.

|| ''Name'' || ''Description'' ||
|| '''acl''' || Hooks to control commit access to parts of a tree. (see AclExtension)||
|| '''bisect''' || Extension for binary searching in O(log2(n)) for the changeset introducing a (mis)feature (see UsingBisect for more details). ||
|| '''bugzilla''' || Update Bugzilla bugs when changesets mention them. (see BugzillaExtension) ||
|| '''churn''' || Graph amount of code changed per author over time. (see ChurnExtension)||
|| '''extdiff''' || Extension for using an external program to diff repository (or selected files). (see UsingExtdiff) ||
|| '''fetch''' || Convenience wrapper for pulling and merging. (see FetchExtension)||
|| '''gpg''' || Extension for signing and checking signatures. (see GpgExtension)||
|| '''hgk''' || Start {{{hgk}}}, a gitk-like graphical repository browser bundled with Mercurial. (see UsingHgk) ||
|| '''mq''' || Mercurial Queue management extension. (see MqExtension) ||
|| '''notify''' || Template-driven email notifications. (see NotifyExtension) ||
|| '''patchbomb''' || Extension providing the {{{hg email}}} command for sending a collection of Mercurial changesets as a series of patch emails. (see PatchbombExtension) ||
|| '''win32text''' || Extension for line ending conversion filters for the Windows platform. (see Win32Extension) ||

== Other Extensions ==

|| ''Name'' || ''Source'' || ''Description'' ||
|| '''forest''' || [http://www.terminus.org/hg/hgforest repository] || Extension that provides commands to help working with trees composed of many Mercurial repositories. [http://www.selenic.com/pipermail/mercurial/2006-July/009336.html thread] (see ForestExtension) ||
|| '''transplant''' || [http://hg.kublai.com/mercurial/transplant repository] || Cherry-picking, rebasing and changeset rewriting. (see TransplantExtension) ||

== Enabling an extension ==

To load an extension, you add it to the "extensions" section of your [http://www.selenic.com/mercurial/hgrc.5.html .hgrc] file.

Mercurial will scan the default python library path for a file named {{{hgk.py}}} if you set {{{hgk}}} empty:

{{{
[extensions]
hgk=
}}}

Extensions are usually located in the hgext directory, in which case you can load them like:

{{{
[extensions]
hgext.hgk=
}}}

You can also specify an absolute path:

{{{
[extensions]
hgk=/usr/local/lib/hgk.py
}}}

Extensions can often be configured further in an extension specific section in the same configuration file.
Extensions allow the creation of new features and using them directly from the main hg command line as if they were builtin commands.
Line 57: Line 9:
To write your own extension, your python module can provide an optional dict named `cmdtable` with entries describing each command, and an optional callback named `reposetup`.
The `reposetup` callback is called after the main Mercurial repository initialization, and can be used to setup any local state the extension might need. Below is an example extension to help demonstrate how things work:
=== Command table ===
To write your own extension, your python module can provide an optional dict named `cmdtable` with entries describing each command.

==== The `cmdtable` dictionary ====
The `cmdtable` dictionary uses as key the new command names, and, as value, a tuple containing:

 1. the function name to be called when the command is used.
 1. a list of options the command can take.
 1. a help string for the command.

==== List of options ====
Al the command flag options are documented in the mercurial/fancyopts.py sources.

The options list is a list of tuples containing:
 1. a flag specifying if the option is of the short or long sort, like {{{-o}}} or {{{--option}}}.
 1. an option name.
 1. a default value for the option.
 1. a help string for the option.

==== Example `cmdtable` ====
{{{
cmdtable = {
    # "command-name": (function-call, options-list, help-string)
    "print-parents": (print_parents,
                     [('s', 'short', None, 'print short form'),
                      ('l', 'long', None, 'print long form')],
                     "hg print-parents [options] node")
}
}}}

=== Command function signatures ===
Functions that implement new commands always receive a {{{ui}}} and a {{{repo}}} parameter. The rest of parameters are taken from the command line items that don't start with a dash and are passed in the same order they were written.

If no default value is given in the parameter list they are required.

=== Repository setup ===
Extensions can implement an optional callback named `reposetup`. It is called after the main Mercurial repository initialization, and can be used to setup any local state the extension might need.

As other command functions it receives an ui object and a repo object (no additional parameters for this, though):

{{{
def reposetup(ui, repo):
    #do initialization here.
}}}


== Example extension ==
Line 108: Line 105:
Line 109: Line 107:
CategoryExtension See CategoryExtension for related pages and ["Extensions"] for a list of readily avaliable extensions bundled with Mercurial or provided by third parties.

Writing Mercurial extensions

Mercurial features an extension mechanism for adding new commands.

Extensions allow the creation of new features and using them directly from the main hg command line as if they were builtin commands.

Writing your own extension

Command table

To write your own extension, your python module can provide an optional dict named cmdtable with entries describing each command.

The `cmdtable` dictionary

The cmdtable dictionary uses as key the new command names, and, as value, a tuple containing:

  1. the function name to be called when the command is used.
  2. a list of options the command can take.
  3. a help string for the command.

List of options

Al the command flag options are documented in the mercurial/fancyopts.py sources.

The options list is a list of tuples containing:

  1. a flag specifying if the option is of the short or long sort, like -o or --option.

  2. an option name.
  3. a default value for the option.
  4. a help string for the option.

Example `cmdtable`

cmdtable = {
    # "command-name": (function-call, options-list, help-string)
    "print-parents": (print_parents,
                     [('s', 'short', None, 'print short form'),
                      ('l', 'long', None, 'print long form')],
                     "hg print-parents [options] node")
}

Command function signatures

Functions that implement new commands always receive a ui and a repo parameter. The rest of parameters are taken from the command line items that don't start with a dash and are passed in the same order they were written.

If no default value is given in the parameter list they are required.

Repository setup

Extensions can implement an optional callback named reposetup. It is called after the main Mercurial repository initialization, and can be used to setup any local state the extension might need.

As other command functions it receives an ui object and a repo object (no additional parameters for this, though):

def reposetup(ui, repo):
    #do initialization here.

Example extension

   1 #!/usr/bin/env python
   2 
   3 from mercurial import hg
   4 
   5 # every command must take a ui and and repo as arguments.
   6 # opts is a dict where you can find other command line flags
   7 #
   8 # Other parameters are taken in order from items on the command line that
   9 # don't start with a dash.  If no default value is given in the parameter list,
  10 # they are required.
  11 def print_parents(ui, repo, node, **opts):
  12     # The doc string below will show up in hg help
  13     """Print parent information"""
  14 
  15     # repo.lookup can lookup based on tags, an sha1, or a revision number
  16     node = repo.lookup(node)
  17     parents = repo.changelog.parents(node)
  18 
  19     if opts['short']:
  20         # hg.short will return a smaller portion of the sha1
  21         print "short %s %s" % (hg.short(parents[0]), hg.short(parents[1]))
  22     elif opts['long']:
  23         # hg.hex will return the full sha1
  24         print "long %s %s" % (hg.hex(parents[0]), hg.hex(parents[1]))
  25     else:
  26         print "default %s %s" % (hg.short(parents[0]), hg.short(parents[1]))
  27 
  28 cmdtable = {
  29     # cmd name        function call
  30     "print-parents": (print_parents,
  31                      # see mercurial/fancyopts.py for all of the command
  32                      # flag options.
  33                      [('s', 'short', None, 'print short form'),
  34                       ('l', 'long', None, 'print long form')],
  35                      "hg print-parents [options] node")
  36 }

If cmdtable or reposetup is not present, your extension will still work. This means that an extension can work "silently", without making new functionality directly visible through the command line interface.

Where to put extensions in the source tree

As of a change shortly after the 0.7 release, the recommended location for installing extensions in the source tree is the hgext directory. If you put a file in there called foo.py, you will need to refer to it in the hgrc file as a qualified package name, hgext.foo.

The contents of the hgext directory will be installed by the top-level setup.py script along with the rest of Mercurial.


See CategoryExtension for related pages and ["Extensions"] for a list of readily avaliable extensions bundled with Mercurial or provided by third parties.

WritingExtensions (last edited 2020-07-29 10:00:07 by aayjaychan)