As I already had the chance to write in a previous post, I really appreciate distributed version control systems; I consistently use them at work and for many of my side projects. I typically switch between git and mercurial repositories, with the former being my primary choice lately, and there is one specific command that always troubles me when I do that: pull.
There is one wonderful piece of inconsistency between the two systems, one that often leads to confusion for new adopters and unnecessary hassle for experienced users. If you are familiar with both systems, you may already be thinking about the culprits. If you are not, you may be more careful about the pull and fetch commands after reading this post.
Here is what the Git Reference says about fetch and pull:
git fetch download new branches and data from a remote repository
git pull fetch from a remote repo and try to merge into the current branch
And here is mercurial‘s documentation about pull:
A pull propagates changesets from a “remote” repository (the source) into a local repository (the destination). It can optionally update the working directory (specify option -u or –update).
See what we have now? A fetch on Git acts like a pull on Mercurial, and a git pull does a bit more than a hg pull.
Git and Mercurial were designed in parallel in the same period by different groups, so this inconsistency can partially be explained by their history and context. What troubles me, however, is that mercurial comes with an extension that can enable fetch. Guess what it does?
This extension is a convenience wrapper. In the simplest case, hg fetch acts like hg pull -u — it pulls changes from a remote repository into a local one and updates the working directory. (This is like the “update” command as found in Subversion or CVS.)
As if we needed more ambiguity, we now have in Mercurial a fetch command that does quite the same thing Git’s pull does.
Inconsistencies like this one are frequent in software development: they are a sign that we should pay more attention to what products and tools similar to ours are doing. This does not mean we should shamelessly copy what other people are doing or stop innovating just to ensure uniformity, but we should still strive for consistency across similar applications if that means less confusion for our users.