Version Control Demystified, Part 3: Git and Mercurial

by Tom on December 20, 2010

This post is the third in a series devoted to version control. In Part 1, I talked about version control features that are already integrated into everyday tools, such as Dropbox or Google Docs. In Part 2, I gave an introduction to Subversion, which is a ‘traditional’ command-line version control system. In this post, I will wrap up this series by writing about more modern approaches to version control such as Git and Mercurial, which are much easier to get started with, more powerful in the long term, and are rapidly growing in popularity.

Quick Start

Note: To install Git or Mercurial, you can grab installers from the project webpages (Git Downloads or Mercurial Downloads) or use MacPorts.

The concept behind Git and Mercurial is simple – get rid altogether of the client/server approach and instead treat a project directory as a directory where changes are tracked, and with all the version history self-contained. Imagine that you have an existing project in a directory called project. The following example shows how to start tracking changes in this directory:

$ cd project
$ git init  # Tell git to start tracking this directory
Initialized empty Git repository in /Users/tom/project/.git/
$ ls
README  main.py
$ git add .  # Add all files in the directory
$ git commit -m "Initial Commit"  # We commit the changes so far
[master (root-commit) 8cc2595] Initial Commit
 2 files changed, 8 insertions(+), 0 deletions(-)
 create mode 100644 README
 create mode 100644 main.py
$

That’s it! No setting up servers, no checking out of working copies – in a few commands, you’ve transformed an existing project directory into a full git repository. We can now make changes to a file and commit the changes:

$ echo "All rights reserved" >> README 
$ git add README  # You need to explicitly tell git which changes to commit
$ git commit -m "Added a line to README"
[master 742b6ca] Added a line to README
 1 files changed, 1 insertions(+), 0 deletions(-)

Using Mercurial is virtually the same, replacing git by hg. The only difference is that git requires you to add changed files to the next commit, whereas hg behaves more like svn in that it automatically will commit all modifications next time the user runs hg commit.

The above example shows only the very basic functionality of Git and Mercurial, and both tools have excellent documentation which I strongly recommend that you look at (For example the Git Community Book and Learn Mercurial). It is for of course possible to sync a Git or Mercurial repository with other users, or to a web service, but there is never the idea of an ‘original’ repository. All clones of a repository are equal, so that if one is lost the others still contain all the information about the history of the code. There are other very useful capabilities in both tools such as branching, which allows you to keep track of different variants of a project in a single directory (such as master and experimental branches).

Graphical Interfaces

One of the only slight disadvantages of Git and Mercurial compared to Subversion is that since the latter has been around for longer, there are some very nice Subversion graphical interfaces (such as Cornerstone). There are more and more GUIs for Git and Mercurial, but they have yet to reach the level of polish of some of the older tools. One very good Git GUI is GitX. In true ‘Git’ spirit, many forks of the project were created to improve on the original program, and the best fork to date is this one.

Hosting Repositories

There are several existing providers for free Git and Mercurial hosting. I personally really enjoy using GitHub, which adds a social dimension to coding. You can ‘follow’ other projects and very easily create ‘forks’ of other projects that you want to work on yourself. As an example, you can see my projects here. The equivalent for Mercurial is BitBucket, which is also very nice.

But… which should I learn?

Choosing between Git and Mercurial is not easy. Both are excellent tools, and I’ve personally settled on Git more because of the ecosystem (e.g. GitX and GitHub) than the capabilities of the tool itself. What are your thoughts on Git and Mercurial? Do you use either of them? Let’s hear from you!

{ 10 comments… read them below or add one }

1 John December 20, 2010 at 8:50 am

I’ve been using git for a few years. Initially, I chose git because it’s Subversion integration (git-svn) was much more advanced than the Mercurial equivalents (hg-svn or hgsubversion), but I think that’s no longer the case. A couple of months ago, I was asked to give an introductory lecture on version control, and I figured it’d be a good excuse to teach myself some Mercurial.

I was actually quite surprised to find how similar they are. I expected Mercurial to be a lot more user-friendly, while git would be significantly higher performance — that’s certainly the old stereotype, but, at least in the relatively limited comparisons I did, they seemed pretty much neck-and-neck in every respect. Both have some neat tricks the other doesn’t do by default (things like MQ or the git staging area), but there’s nothing really vital (and there are usually extensions available that add the functionality you need).

In brief: they both seem like great tools, and I’d struggle to make a real case for choosing one over the other. I’d go with whichever you can get the best local support for, or whichever you like the documentation for, or possibly, if you want hosted repositories, choose git because GitHub is awesome.

By the way, Joel Spolsky’s HgInit tutorial at http://hginit.com/ is well worth a look, specially if you’ve got minimal experience of version control. Pro Git at http://progit.org/ is also worth a look.

Reply

2 Marshall December 20, 2010 at 9:34 am

So I have to admit I’ve not really tried any of the distributed VCSes yet, but in part that’s because I don’t really see what the advantage woudl be for me. I *like* the concept of having a master repository, because it makes it very easy to share code with many collaborators in a straightforward manner. Even people who have no prior experience with VCS can get the concept pretty much instantaneously and be up and running very quickly. Is this still the case with hg or git? I’m not talking about the one-standalone-directory case, I care about the ‘eight people all working on one codebase’ case. Doesn’t the need to worry about pushing changes between different distributed repositories add a layer of complexity in this case?

Reply

3 John December 20, 2010 at 11:35 am

Marshall —

If you want to use git like Subversion, that’s easy!

Just create an empty, bare (ie, “git init –bare”) repository to be your master. Your collaborators can clone it, then work in a very Subversion-like manner: “git pull” to fetch and merge changes (equivalent to “svn up”), and “git push” to send your changes to the server (a combination of “git commit” and “git push” gives you the effect of “svn commit”).

As a bonus, of course, each collaborator has their own fully-functional repository. That means that, when you don’t have a network connection to the master, you can continue to commit locally, storing up a bunch of changes to be pushed back to the server when you have connectivity.

Reply

4 Dan December 20, 2010 at 3:45 pm

Another Git GUI that looks promising (currently in beta) is Tower.

Reply

5 Florian December 21, 2010 at 6:24 am

A very promising GUI seems to be SourceTree at http://www.sourcetreeapp.com/ which is able to handle Git and Mercurial (but I’m still evaluating it). It is not free, but a mac-only apllication, with a look-and-feel similar to the Subversion clients Versions or Cornerstone.

Reply

6 Cameron December 22, 2010 at 11:47 am

btw, just throw the ‘-a’ flag on the commit to get it to automatically update changes to files GIT is already tracking.

e.g.
% git commit -a -m “edited the README”

Reply

7 nick December 22, 2010 at 5:49 pm

Thanks for this series of posts. I realize the information exists elsewhere in the internet, but an example of what to do when you need to go back a version because you did something really ill-advised would be helpful. Aimed as it is at people with no experience, we’re kind of left at a point where we have version control set up but no idea what to do with it.

Reply

8 John December 23, 2010 at 1:29 pm

That’s a big question, and I imagine a full answer could easily fill several more blog posts!

Briefly, though, if you’ve made a commit to your git repository that you later regret, you can use the “git revert” command to effectively record the “anti-commit”. In general, modifying history is a bad idea, so this won’t remove the record of what you’ve previously done from your repository: rather, you’ll now see two commits: the faulty one, and the revert.

9 Duncan November 21, 2013 at 4:06 pm

I wanted to like git, but since every tutorial I read seemed to have as step 2, “go open an account on github”, it’s claims to being decentralised rang a bit hollow
I have since started using Mercurial and found it perfect for my needs, which are primarily maintaining groups of data files and analysis scripts on multiple machines (laptop, desktop, server at collaborator’s institution etc.). There is no need to host the files elsewhere than the working copies themselves.
A possible downside is that sharing with others may be a little more difficult, I’ve run into problems trying to clone via http with institutional IT firewalls etc.

Reply

10 John November 27, 2013 at 12:36 pm

Don’t all Mercurial tutorials suggest an account on Bitbucket? 🙂

Neither system is inherently any less (or more) decentralized than the other: it’s perfectly possible to use git without GitHub, just as it’s possible to use hg without Bitbucket. GitHub’s pretty slick, though.

Leave a Comment

Previous post:

Next post: