— 17 Feb 2018

Squashing Commits in Mercurial

I’m new to Mercurial, so this is definitely not something trivial for me. 😅 I’m writing this down here in case others may find it useful, including Future Me (I’m that forgetful).

The problem

I was working on an issue and committed my patch before realizing that I still need to do another thing. So I committed my latest update before I realized that I need to do something else, and I need to merge all of these different commits into one commit since they’re related to one particular issue. Moreover, I needed to rewrite my commit message because I didn’t follow the convention the first time.

There are three different commits that I’d like to merge into one commit, with the final commit message modified.

The solution

I needed something similar to git rebase, which doesn’t exist in Mercurial unless you use extensions.

Upon searching I figured that there are a few ways to do this: by using the MqExtension extension, using the Histedit extension, and using the Rebase Extension. All three extensions are already distributed along with Mercurial releases, so you don’t need to install them. However, you still need to enable them before using.

What worked for me the first time was Histedit, a history editing plugin for Mercurial, so that’s the extension I’m going to use throughout this post. What I found useful is that Histedit also works similarly to git rebase --interactive, which is nice when you’re already used to its git counterpart.

Enabling histedit

To enable the Histedit extension (or any extension), open the file $HOME/.hgrc. This will open a Mercurial configuration file that is set per user. Mercurial also has other configuration files, which you should check out if you have different needs.

Find a line that says [extensions]. This line is a header for the section that keeps track of which extensions you’re using. An example would be something like this:

Since Histedit is already installed along with the Mercurial release–unlike the reviewboard extension, for example–we do not need to specify the path to the extension. We can just simply add histedit = and we’re good to go.

Squashing the commits

To start working with histedit, run the following command:

hg histedit -r-3

You can change the number 3 according to your need. If you only need to squash the last two commits, then run hg histedit -r-2. In my case, since I wanted to squash the last three commits, I ran hg histedit -r-3 instead.