Imagine a bacon-wrapped Ferrari. Still not better than our free technical reports.
See all our reports

Nine awesome features and extensions for Mercurial (Hg)

logo-droplets-200

Years and years ago, ZeroTurnaround’s small, geeky engineering team started looking into Git and Mercurial. We had been using Subversion for ages, and felt like it was time to look into other alternatives, namely to migrate to a decentralized version control system (DVCS) so that we could alienate our partners in life by committing code while on vacation with them. This was back when it wasn’t possible to use Git on our Windows workstations and recently-released Kiln was supporting only Mercurial. So, not wanting to wait for things to improve on their own, we chose to use Mercurial rather than Git.

Now, years later, I can’t tell you if we made the right decision but I do know that a lot has changed on how source code is managed. DVCS systems have made the life of developers just so much simpler and pack so much power that it would be a shame not to take advantage of it. Also, I’ve noticed that developers very often use only a subset of features of their version control systems.

After some preaching around the office and emails to the engineering team, I got this urge to share my experiences with Mercurial. I chose a list of 9 Mercurial features/extensions that I find useful, powerful or just like and I really do have them enabled in my .hgrc file.

Rebase

The Rebase extension is a very powerful one and great for productivity. I personally use this daily, since the repository I work with gets a lot of heat, with dozens of added changesets a day in at least in 4 different branches. Most of the time, when I want to push something I already need to pull a little.

There is a deprecated extension that makes this pulling a less cumbersome: the fetch extension. It will pull and then do a merge for you with a message “Automated merge with ….”. These will litter your changeset history with merge messages!

Another option would be to pull and rebase. Or in short hg pull --rebase. The result is that it will move your local changes onto to the most recent head of the checked-out branch. If it doesn’t succeed, you need to manually merge but that is always the case when you have conflicts. Most of the time you will save a merge!

Histedit

The Histedit extension is probably the most powerful of all the extensions mentioned here. The usage scenario for this plugin is to go over your commits and reorder them and/or fold them into fewer ones. Imagine you were working on feature X and made some commits to implement it. Later on you feel that it would be really nice if these commits would be just a single commit for easier reviewing.

This is where the extension comes to play. You can fire up for example hg histedit -o and it will drop you into an editor with the list of outgoing changesets and you can pick an action what to do with each of them. You can reorder, pick, fold, edit or drop them as you please.

You can do these operations on local changes and not on the permanent history of the repository (see Mercurial Phases for more).

Shelve

This is an extension that is bundled with Mercurial 2.8 and offers an easy way to shelve away your local changes so that you can either be interrupted with other work or you can go back to the branch you were thinking you were at :).

For example, let’s say you have made some local changes that you don’t want to commit yet but at the same time you want to do a quick bug fix. Shelve comes in helpful here.

toomasr@cigarillo ~/tmp/tmp » hg shelve
shelved as default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved

Now your work has been shelved away under a name default. Later on you can call unshelve

toomasr@cigarillo-2 ~/tmp/tmp » hg unshelve default
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)

And voila! You have your old state back and you can continue from where you left off. Handy, right?

Unbundle

Have you seen the message saved backup bundle to projectX/.hg/strip-backup/7bf31c6f3fec-backup.hg? Well, nice to know, but what do you do with it? These are the Mercurial backup files and you can restore your previous state by issuing hg unbundle and specifying which backup bundle you want to unbundle. This is the undo mechanism for tasks that change and destroy history.

Purge

Purge is another extension that I use daily. I don’t know if I’m super sloppy but I very often have some files lying around in my repository that are not supposed to be there. Maybe they are some temporary files that I haven’t put into .hgignore or just some data files that I’ve used but have not intended to keep.

This is where hg purge comes into play. This command will remove all files and directories that are not being tracked in the current repository.

Alias

Mercurial has built in aliases so that you don’t have to rely on your system aliases. You can define your Hg aliases in a section in your configuration file.

[alias]
# lets introduce hg blame
blame = annotate --user -c
# short log
llog = log --limit 10

Color

You like terminal colours? Well go and enable the extension. Quick! I have no idea why this isn’t enabled by default.

Color

Progress

So now you have color in your terminal, so how about some progress bars? Sure thing, go enable the progress extension and you’ll get your progress bars.

Pager

Are you tired of piping Hg commands to less or more or what not? Well there is an extension for that. After 4 lines of configuration you will have a pager for your commands. It also supports having a pager for only couple of the commands. It actually has more options that you would think a pager could have :)

Conclusions

Needless to say, Mercurial has a lot of extensions. These are only the best 9 that I could think of, but if my “grepping” skills are correct, then there are 193 as of today. What extensions do you like? Please share them with us in the comments section below, or by tweeting @toomasr or @RebelLabs!

 

  • Oleg Šelajev
  • http://www.zeroturnaround.com/ Toomas Römer

    I have it enabled but when writing this post I realised I don’t use it! Do you use it regularly?

  • Oleg Šelajev

    Not directly, but I have it in an alias, so whenever I ask for a log, I use that.
    Something like: alias lh=’hg glog -b “`hg branch`” -l’

  • http://blog.blzr.me/ Constantine

    We store docs next to the code in our repository and render markdown using https://bitbucket.org/celdredge/hgext.markdown

  • http://www.zeroturnaround.com/ Toomas Römer

    Cool, the DIY solution if not using BitBucket or similar service.

  • Allan Peda

    hg purge looks scary to me.

  • Bryan

    it was useful for our automated build server to make sure you have a clean directory to build from

  • http://www.zeroturnaround.com/ Toomas Römer

    Don’t run it without “hg st” before. There you’ll see what is not considered part of the repository and that will get purged.

  • panzi

    For these things I use thg http://tortoisehg.bitbucket.org/. I use it to view the graph and browse files at different versions.

  • SteveFink

    I prefer ‘hg purge -p’ for the pre-check.

  • Nick

    How about crecord?

  • Martin Geisler

    Just use “.” for the current branch name: “hg log -b .”.

  • Martin Geisler

    The graphlog extension is now part of core Mercurial, so “hg log -G” always works now.

  • Oleg Šelajev

    Thanks for the tip. I guess, I’ve had that alias since forever.

  • http://www.zeroturnaround.com/ Toomas Römer

    Looks awesome, have to check it out. How is your experience with it?