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.
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!
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).
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
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?
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 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.
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
You like terminal colours? Well go and enable the extension. Quick! I have no idea why this isn’t enabled by default.
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.
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 :)
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 @ZeroTurnaround!