April 29, 2014 •

Mercurial is reaching version 3.0. Code freeze has begun on April 17, which means that Mercurial 3.0 will ship in early May. Here’s an glimpse into what’s going on with Mercurial development, as well as a short overview of upcoming new features, experimental and otherwise.

Changeset Evolution

This feature has been available as an Evolve extension since Mercurial 2.1, but is still under active development and is not enabled by default.

While Mercurial enables distributed version control, Changeset Evolution is a set of features that enables distributed history rewriting. “Distributed” is key here. Currently, there are only partial solutions to the problem of history rewriting. hg rebase and hg histedit are limited in what they can do, have trouble communicating changes with the rest of the team and make it hard (or nearly impossible, depending on which side you’re on) to get previous versions of changesets.

Mercurial itself tracks changes to files. Changeset Evolution enables tracking changes to changesets, recording which of them got deleted or superseded by a new version of the changeset. Obsolescence markers is what enables this functionality. Note that nothing is ever rewritten; obsolete changesets simply are hidden and can always be recovered.

Now, to enable collaborative history rewriting, this information has to be somehow communicated between parties. This is where Bundle2 comes in.

Bundle and Bundle2

Bundle2 implementation is still experimental in Mercurial 3.0 and should be enabled around 3.2 timeframe.

When cloning, pushing and pulling changesets (and running hg bundle), Mercurial exchanges changesets in the format called Bundle. Although battle-tested and extremely reliable, this format has a number of shortcomings:

  • Cannot be easily extended to transfer new types of payloads
  • Does not support exchanges of bookmarks and phase boundaries
  • Does not support more advanced delta-compression algorithms
  • Is only used for unidirectional communications

Bundle2 will be the replacement for current Bundle format, featuring better compression, extensibility and bidirectional communication. Additionally, it will significantly decrease the number of HTTP requests sent to the Mercurial server when performing pushes and pulls, because what currently requires separate trips to the server (get bundle, get bookmarks, get phase markers) will be shipped to the client in one go.

New Features

HTTP Authentication Improvements

Previously, Mercurial was not very smart about HTTP authentication, very much resembling a goldfish: it would try to connect to the server, receive 401, get authentication information (either from the user or from Keyring) and retry the request, authenticated, only to forget to authenticate the next request. This behavior was particularly bothersome for pushes, when all the effort of transmitting a potentially large bundle was wasted because the request was unauthenticated in the first place:

GET /hg/server?cmd=capabilities HTTP/1.1 401 260 - mercurial/proto-1.0
GET /hg/server?cmd=capabilities HTTP/1.1 200 147 - mercurial/proto-1.0
POST /hg/server?cmd=unbundle HTTP/1.1 401 260 - mercurial/proto-1.0
POST /hg/server?cmd=unbundle HTTP/1.1 200 42 - mercurial/proto-1.0

This is going to change in 3.0: Mercurial will remember that it needs to be authenticating and will not be trying to break into a password-protected door:

GET /hg/server?cmd=capabilities HTTP/1.1 401 260 - mercurial/proto-1.0
GET /hg/server?cmd=capabilities HTTP/1.1 200 147 - mercurial/proto-1.0
POST /hg/server?cmd=unbundle HTTP/1.1 200 42 - mercurial/proto-1.0

Usability Improvements

When executing hg push on a newly created repository, Mercurial errored out with a rather cryptic message:

$ hg init
$ hg ci -m "initial commit" –A # assuming there were changes
$ hg push
pushing to default-push
abort: repository default-push

Those familiar with Mercurial will immediately know what’s wrong here. Those who aren’t, however, are left to their own Google-foo. In 3.0, Mercurial will get a bit more helpful and offer to consult an exact section of a super-helpful built-in help.

More detailed help comes from yet another angle, future-proofing existing Mercurial.

hg config

Mercurial will get a new command, called hg config. It can be used in two flavors: running hg config will print names and values for all configuration items. Running hg config --edit will launch a configured editor to tweak a user-level configuration file. With --local switch you’ll be editing a repository-level configuration file, and with --global you’ll be editing a system-level configuration file.

comments powered by Disqus

HgLab is a behind-the-firewall self-hosted Mercurial server and source control management system which gives you:

  • Sophisticated Mercurial-based version control system
  • Straightforward setup on your servers
  • Powerful code collaboration platform
  • Seamless integration with your infrastructure - including ActiveDirectory

Get Started with Full-Featured 45-Day Evaluation →

Interested in HgLab and Mercurial? Want to know when new releases are out? Join the HgLab HQ Mailing List for to get notified when something interesting happens.

Subscribe to the HgLab HQ Newsletter →

Take HgLab for a Spin

Try HgLab now. Full-featured 45-day evaluation, no credit card required.