Serving Mercurial repositories with hgweb and mercurial-server

I really like using mercurial-server [] for hosting my Mercurial repositories. Because it uses SSH and public keys, it’s quite secure, and works well with multiple users. However, it doesn’t have public access for pulling repositories. For that reason, I also use hgweb (shipped with Mercurial) to make my repositories publicly accessible and pullable, especially with the highlight module (also shipped with Mercurial) that uses Pygments [] for syntax highlighting.

So in this post, I’ll be explaining how to use mercurial-server to host your repositories, while also having them publicly browsable and pullable with hgweb. I’ll also be demonstrating how to hide repositories from hgweb, while still keeping them working with mercurial-server.

First, I assume you have a working mercurial-server set up. If you do not, the documentation for it is available here [].

To have hgweb serve our repositories, we must first make a configuration file for hgweb. The configuration file should look like this:

/var/lib/mercurial-server/repos/ = /var/lib/mercurial-server/repos/

hgext.highlight =

allow_archive = bz2
pygments_style = vs
style = monoblue

You can, of course, tweak this configuration to meet your needs. The [collections] section should stay the same, however, unless your mercurial-server saves the repositories in a non-default folder.

You can also disable the highlight extension by removing the [extensions] section and the hgext.highlight line. You need to do this, for example, if you do not have the Pygments library installed. However, I highly recommend it for browsing the source code. The pygments_style line should also be removed if you disable the highlight extension. I like the vs style (Visual Studio), but there are quite a few different styles that Pygment has out of the box. If you want to see the styles available to you, run the Python interpreter (python) and run:

from pygments.styles import get_all_styles
print list(get_all_styles())

You can choose between different styles for hgweb as well. I prefer monoblue myself, but there are quite a few options that come with Mercurial, and you can download even more online. If you want to see all of the hgweb styles available, in a shell run:

ls /usr/lib/python*/site-packages/mercurial/templates/
# Note: only the directories are styles!
# If ls does not show colors, try adding the "--color" option.

The allow_archive line tells hgweb to allow users to download a .tar.bz2 archive of the repository. You can also add gz and/or zip to allow users to download a .tar.gz or .zip archive. They are comma-separated, so use bz2, gzip, zip to offer all three.

Next, you should add a contact and description for your repositories. If you don’t, Mercurial will just show “unknown” for Description and Contact. To add them, first change into the repository’s folder:

cd /var/lib/mercurial-server/repos/$REPO_NAME

Then, create/edit the file .hg/hgrc and add the following:

contact = Your Name <your@email.address>
description = My Mercurial repository

Additionally, for any repository you do not want to be shown in hgweb (which will also prevent people from pulling the repository using hgweb), add the following instead:

deny_read = *

You also need to set the ownership of the hgrc files to the mercurial-server user, hg. To do that, it’s easiest just to set the ownership of the entire repos folder (which is safe, because mercurial-server always owns the entire folder anyway) by running:

chown -R hg: /var/lib/mercurial-server/repos/
# Failing to do this will cause warnings about untrusted files anytime
# someone pushes or pulls using mercurial-server!

Finally, you need to configure your web server to use hgweb. This part is web server dependent. However, before you configure your web server, you need to choose the interface hgweb will use to communicate with your web server.

  • CGI
    • Pros: easy to set up, no overhead when not being used, software updates happen immediately
    • Cons: forks a new process for each request so slightly slower page loads for small requests (insignificant for large requests, such as pulling a repository)
  • FastCGI
    • Pros: no forking overhead so each request starts being processed immediately
    • Cons: always running so takes up more RAM, more complex to set up, not officially supported by Mercurial (although a FastCGI script is provided), software updates require a restart of the FastCGI script
  • WSGI
    • Pros: no forking overhead like FastCGI, software updates happen immediately
    • Cons: more complex to set up, always running so takes up more RAM, requires either a Python interpreter in your web server (Apache) or a separate process (most other web servers)

No matter what you choose, the setup process is documented here []. Remember to point hgweb at the configuration file you created!

The end result should look something like this []. That installation of hgweb does not support pushing; mercurial-server handles all pushes. However, both hgweb and mercurial-server share repositories, so when I push to mercurial-server, it can be seen on hgweb immediately.

Hopefully this HOWTO was helpful! Feel free to leave comments if you have any questions or concerns. If you have any suggestions, please feel free to leave them here!

Thanks for reading,

Leave a Reply

Your email address will not be published. Required fields are marked *

Unable to load the Are You a Human PlayThru™. Please contact the site owner to report the problem.