Mercurial For Git Users

Git is the only version control system I’ve ever used. By the time I was ready to dive in to version control, it had already won the hearts and minds of developers, so I jumped on board.

Recently, I found myself working on a project under Mercurial version control. I’m always a bit fearful of version control because mistakes, especially when pushed to a remote, can be difficult to undo. It was somewhat harrowing to start committing to someone else’s repo even when you are familiar with the VCS in use; when you aren’t, it’s downright frightening! Fortunately, the differences between Git and Mercurial — at least to perform the basic tasks — are minimal.

Install Mercurial by downloading the installer from the Mercurial site or using Homebrew. The commands you’ll use to get started with your repo are basically the same as their Git counterparts (in terms of usage; what’s happening behind the scenes could be dramatically different).

Start a new repo in the current directory
hg init
Clone a remote repo
hg clone <URL>

In Git, we’re accustomed to making some changes, staging those changes, and committing. Mercurial (along with other VCSs apparently) does not require staging of files. Once a file has been added to the repo, it can then be committed. The one problem this caused for me is that I was unable to selectively commit files until I learned you could list the files along with the commit command in order to commit a subset of the changes.

I also use Git’s interactive staging to make my commits more atomic. An analog to this is available to Mercurial users through the record extension.

Add a file to the repo
hg add <file(s)>
Commit changes
hg commit [file(s)] [-m "Commit message"]
Commit file deletions
hg remove --after
Undo last commit keeping changes
hg rollback

The final piece of the puzzle necessary for collaboration is branching. In most collaborative scenarios, you’ll be creating branches and ultimately merging those into the default (Mercurial’s analog to master) branch.

Creating a branch
hg branch <name>
hg commit -m "New branch commit message"
Switch branches
hg update <name>
Push a new branch
hg push --new-branch
Merge branches
hg merge <name>

One notable difference about branches is that they cannot be deleted after merging. My understanding is that Mercurial will do a sort of trash collection and remove disused branch names from the branch list, but deleting a branch actually deletes the commits associated with it which could be problematic for other branches based on the deleted branch. Picture Michael J. Fox in Back to the Future disappearing from the photo as his parents relationship almost never happened. A fate such as this likely awaits your code if you start deleting Mercurial branches.

On a very surface level, those are the facts you need to know about Mercurial in order to start collaborating on a project. This post no doubt ignores almost all of the nuance and brilliance of Mercurial, but, if your only goal was to get up to speed quickly, you should now be ready to start writing and committing some code!