Working with Mercurial — GSoC’17

An overview of my experiences working with Mercurial

Project: Release notes extension for Mercurial
Organisation: Python Software Foundation (Mercurial)
Mentors: Kevin Bullock, Augie Fackler and Pulkit Goyal

About Mercurial

Mercurial is a cross-platform, open source, distributed version control system written in Python. It’s fast, easy to learn and efficiently handles projects of any size and kind. You can customize its functionality according to your use with the help of extensions.

What areextensions? Extensions in mercurial allow us to add additional features using the Mercurial internal API, and access them from the hg command line interface. With just a couple of lines of code in a single Python file, you can add some really nice features to your hg instance. It’s that simple! A list of existing extensions is available on the Mercurial wiki.

Project Overview

My project was based on creating a release notes extension for Mercurial. Release notes are documents that consist of information like feature additions, bug fixes, performance changes etc.. The major function of this extension is to enable the users to automatically generate release notes by parsing the commit messages/description.

Preview of hg releasenotes --help

Getting the basics working

The basic work flow of the extension is that it first parses the commit messages and tags it to a particular section. A section is something like Bug Fixes, New Features, Performance Changes etc. as I mentioned earlier. For this part, we make use of reStructuredText(rST). Gregory Szorc, one of the contributors to Mercurial, had sent an initial patch to the mailing list regarding the extension and I developed over it. I improved the parsing around the commit messages by storing them in defined data structures like paragraphs and bullets. The patch adding these changes can be accessed here.

Need for De-Duplication

Next important thing was to take care of the de-duplication of note fragments. Many-a-times it is possible that there are several commit messages based on the same feature addition. To avoid the scenario of having the same content over and over inside the notes file, I worked on adding a similarity check function that ensured that the incoming notes were always unique. For the purpose of comparing two commit messages, I used fuzzy string comparison. I made use of this amazing library called fuzzywuzzy to implement this feature. In addition to this, I also added other hacks like checking for issue number (in case it’s a bug fix) to eliminate duplicate items. You can find more details about it here.

Custom admonitions for everyone

Furthermore, I also worked on a feature to add custom admonitions to the existing list of default admonitions. This task was accomplished by making use of a config file .hgreleasenotes. I made use of Mercurial internal API for parsing the config file and extracting (admonition, title) pair. This feature is really useful for people outside Mercurial who intend to use this extension.

Additional commands as flags

To make the releasenotes extension more robust, upon discussion with my mentors I decided to implement various features related to the extension as flags. In general, the command to generate release notes uses the--rev flag. Along with this, I worked on implementing three additional flags.

  • --check: Straight from the doctstrings, the purpose of this flag is to check the commit message for an invalid admonition. In case of an invalid admonition, the flag returns the name of admonition along with the changeset ID. I also made use of difflib.SequenceMatcher to suggest similar existing admonition based in place of the invalid one.
  • --list: This is a helper command for users to view the list of available admonitions along with their title. It is really helpful for users beginning to use this extension.
  • --sync: This command is still under the process of implementation. Once implemented successfully, it will be help user to synchronize the release notes file from the last synced changeset till the latest one. An extremely useful command since this relieves the user from the duty of remembering when he last updated the notes.

Besides this, I also maintained the test files for the extension to cover all the major use cases. The routine of sending patches, updating them and sending over again made me realize the importance of having a good test suite in place. It really eases the task of having to check the command by simply running the code over tests instead of executing the same command multiple times.

Future work

Some of the improvements that can be made in this extension are:

  • Improving the de-duplication task. Currently, the functions have been setup based on Mercurial development requirements. It can be replaced by a more dynamic check so that other developers can also leverage its functionality.
  • Linking release notes to hgweb. This is something that hasn’t been clearly thought upon but seems to be a really nice feature to have. I’ll discuss more about it at the next Mercurial sprint post GSoC period.

You can read more about my work on http://www.rishabh-madan.in.

Thanks to the whole Mercurial community for this wonderful opportunity. This is just the beginning of my journey with Mercurial and I hope to continue to work with the community on many more amazing projects.

Thanks to Kevin for helping me figure out both trivial and non-trivial problems, Augie for helping me with my noob doubts and Pulkit for helping me to get to know the community better. Special mentions for Yuya Nishihara who reviewed most of my patches and taught me a lot of nice things about Python.

Here is a list of patches I sent on the Mercurial devel mailing list. If you would like to use the extension, go to https://www.mercurial-scm.org/wiki/ReleasenotesExtension for more details on usage.