Setting up Mercurial to e-mail on changes

When your project no longer has one person working on it, things can get somewhat messy. It happens in all software projects, but there are differences between bad software projects, and really good software projects. One key to a successful collaborative environment relies on information that is passed among developers, and among other involved people. While too much information is bad, no information is worse.

Within a software development group, email on commit messages can provide substantial benefits. In an open source project (with an open development model), outsiders can view changes without having to check out a copy of the repository, or run to an interface like Trac, or Bugzilla (although these systems are good in their own right).

For Mercurial, the Notify extension makes a system setup relatively painless. This extension however, is somewhat buried unless you know where to look. It is here. It should be installed by default, since it is distributed with Mercurial.

Assuming you already have a repository, the setup is relatively straightforward. Make sure `diffstat` is installed, or disable it with diffstat=False in the following .hgrc file.

In your actual code repository:
me@waffleiron:~/mercurial-code$ vi .hg/hgrc

Add the following (per the Mercurial NotifyExtension wiki article):


[extensions]
hgext.notify =

[hooks]
# Enable either changegroup or incoming.
# changegroup will send one email for each push,
# whereas incoming sends one email per changeset.
changegroup.notify = python:hgext.notify.hook
#incoming.notify = python:hgext.notify.hook

[email]
from = your@email.address

[smtp]
host = localhost

# presently it is necessary to specify the baseurl for the notify
# extension to work. It can be a dummy value if your repo isn't
# available via http
[web]
baseurl = http://hgserver/...

[notify]
# multiple sources can be specified as a whitespace separated list
sources = serve push pull bundle
# set this to False when you're ready for mail to start sending
test = True
config = /path/to/subscription/file
# you can override the changeset template here, if you want.
# If it doesn't start with \n it may confuse the email parser.
# here's an example that makes the changeset template look more like hg log:
template = \ndetails: {baseurl}{webroot}/rev/{node|short}\nchangeset: {rev}:{node|short}\nuser: {author}\ndate: {date|date}\ndescription:\n{desc}\n
maxdiff = 300 # max lines of diffs to include (0=none, -1=all)

Values that you should change are:

  • from = your@email.address
    To the e-mail address that e-mails will appear to be from. Like your personal .hgrc which specifies who you are in a commit, you can specify something like: “from = Developers someemail@example.com”

  • host = localhost
    This can normally be left alone, but possible values in the [smtp] section include a different host, like “host = example.com”, a different hostname for HELOing to the remote server, “local_hostname = LOLCAT.inurbox.com”, “username = someuser”, “password = orly”, “tls = True”, and “port = 26”.

  • baseurl = http://hgserver/…
    Normally, this can also be left alone, but if your repository is on the web, it helps. It is added as a variable to the template below.

  • test = True
    If this is left to “True”, Mercurial will print out what would happen (along with messages sent to people) if the push/etc went through. Set it to “False” when you’re ready to e-mail messages.

  • config = /path/to/subscription/file
    This is where things get somewhat interesting. The config itself points to another Mercurial-like configuration which has two types of subscription settings. It can be any file (even Mercurial revision controlled in the actual repository, so people can add/remove themselves).

    So create a file, possibly one directory outside of your repository (`vi ../subscription.conf`). Possible options are (per the NotifyExtension article again):


    [usersubs]
    # key is subscriber email, value is comma-separated list of glob patterns
    user@host = pattern

    [reposubs]
    # key is glob pattern, value is comma-separated list of subscriber emails
    pattern = user@host

    The glob matches against your repository’s root. In any case, [reposubs] probably works best for many people. Your config file will probably look like:

    [reposubs]
    * = developers@example.com

    Save it, and you should be set.

  • template = \ndetails: {baseurl}{webroot}/rev/{node|short}\nchangeset: {rev}:{node|short}\nuser: {author}\ndate: {date|date}\ndescription:\n{desc}\n

    This specifies what will be sent in the body of the e-mail. Removing “{baseurl}” will of course, remove the baseurl specified above. Modify to your heart’s content.

    Once all of this is done, save everything, and try a test push/pull to update the repository. You should see something on the order of:

    remote: adding changesets
    remote: adding manifests
    remote: adding file changes
    remote: added 1 changesets with 1 changes to 1 files
    remote: notify: sending 1 subscribers 1 changes

    If “test = True” is enabled (repository hgrc), you will get a printout of what would be sent.