Git vs. Mercurial

After using CVS and SVN for years now, I finally stumbled over distributed version control systems (DVCS). Beside the commercial BitKeeper there are various Open Source projects around. The most famous is probably GIT which was initially developed by Linus Torvalds and is now maintained by Junio C. Hamano. An other approach is Mercurial which started in the same time when GIT started. There are several other (bazaar, monoton), but I’ll focus on these. The systems have some concepts in common but differ at some point. I don’t want to give you a deep introduction to the DVCS approach, there are enough tutorials around that cover this topic well.
Git is more or less the most advanced Open Source DVCS around the block. It is written in C, extreme fast and uses SHA1 algorithm to clearly identify a commit making sure that every commit is unique over the world. It includes a huge set of commands to support the developer in their daily work. Obviously, as git was developed for the Linux kernel development, it brings a lot of features that are often used by the kernel maintainers. A good example for this is directly patching a source code from your local mbox. So the featurset of GIT is really huge. GIT contains about 130 different commands. For the advanced user, this might be nice, but getting in contact with DVCS systems, git might confuse most of the people and will be just overhead for most of the Open Source projects. From the performance perspective, git is very fast. Switching a branch with a few thousands files just takes a seconds. Also diff and merging is consdired to be fast on GIT. In contrast to Mercurial GIT also supports different branches per repository. This is quite useful especially for some nice testing on your own local branch. Mercurial allows this too, but with much more overhead and not as easy as in GIT.

Another point about GIT is for sure stability. It’s rock solid. The complete Linux kernel is maintained using GIT since two years now. If you take care of your repository GIT will seriously keep track of your files. To test integrity of your files, GIT uses SHA1 which also used to identify commits / files and other git objects.

Don’t forget to run the GIT garbage collector from time to time. Without that you might experience less performance. One major drawback for sure is the operating system support. In fact it only runs smooth on Linux and U*IX styled operating systems like FreeBSD. Windows support is only available using Cygwin or MinGW. Also GIT does not provide a fancy graphical interface like SmartCVS/SmartSVN or similar interfaces, but comes with a Tcl/TK written branch viewer. The documentation is quite good at this point and there are quick tutorial for user migrating from other common version control systems. A really cool feature at GIT is the possibility of providing own / per-repository abbreviations of commands. So you can set the

git cm

to

git commit -a

using

git-config alias.co ‘commit -a’

and therefore build your own set of commands you often use.
Summary

  • Pro
  • Fast
  • Rich set of features
  • Stable
  • Local Branches
  • Quiet good documentation
  • Nice configuration
  • Good web interface
  • Contra
    • No native windows support
    • Confusing set of commands for beginners
    • The only way to access non tagged commits are long SHA1 keys
    • Manual garbage collecting

    GIT is very powerful. It’s a great choice for very large (Open Source) projects. You get everything you need, but you must use Linux if you don’t like Cygwin (well doesn’t matter for me, I’m don’t use Windows at all). For smaller projects (which is approx. 95% of all OSS projects) GIT is just overkill. It works very fine, but it’s normally not needed and the set of features is just useless as the interaction with other persons is small.

    Mercurial (aka. HG, which is the element abbreviation for Mercurial) increase in popularity. It’s written in Python but is backed by some C extensions for the time consuming steps. It comes with a much lighter set of features than GIT but covers the most important commands and features (merging, pushing/pulling to ssh,http,sftp servers). Furthermore it has a great documentation as there is a small public available book on Mercurial, which makes it easy for beginners to get into distributed version control systems. It also proves stability and is used by a lot of big open source projects namely Mozilla, ALSA, OpenSolaris, XEN. Like GIT it uses SHA1 to track consistency of files and to identify commits. One of the big advantages of Mercurial which makes it easy to use especially for private projects is the usage of incremental version numbers per-repository. Every commit in a repository has a own incremental number that identifies the commit only for that repository as merging, branching, etc in a DVCS needs a unique number (which is the SHA1 key). But for the local copy it allows you to easily to jump to a certain revision (but for sure if you talk to someone you cannot speak of revision 1 or 132 of a certain file but you have to speak of the revision 4a4bddef221… of a file). Unlike GIT, Mercurial runs perfect on Windows machines.

    The only feature missing I miss in Mercurial is the possibility of having local branches in my repository. In GIT you can create a local branch, commit, merge, etc in your personal environment (also a push will make the branch visible on your public repository, and it might result in some merging-noise!). You do this in your local repository with some fancy commands. You can do this in Mercurial too, but as Mercurial doesn’t support different branches per repository (in fact a complete repository is considered as a branch in HG) you have to do a clone into a different directory on your hard disk. You will use your file system as a branching mechanism and branch identifier. So you probably will end up doing a lot of ‘cd ../main; hg merge; cd ../stable; hg commit’ commands. The advantage of this approach is keeping things simple and people will not doing a commit into the wrong branch as they might do in GIT (ops I really checked out *this* branch?). One of the probably nicest features in the build in webserver to serve Mercurial repository throughout the network which makes working together for a short time without having time to setup a complete environment very easy.
    Summary

    • Pro
    • Portable
    • Easy to understand and use
    • Incremental commit ids per-repsitory
    • Stable
    • Very good documentation
  • Contra
    • Not a big set of advanced features
    • No per-repository branching

    Mercurial is very easy. It perfectly fits most of the needs. As I didn’t test svnimport/cvsimport yet, I cannot compare both systems in that way. HG gives you the feeling of doing things easy and fast while using GIT I often end up reading man pages. For me the local branching is really annoying. Furthermore I discovered that between 0.9.0 and 0.9.2 the repository layout changed, which makes it impossible for me to push to my debian machine from my ubuntu without compiling Mercurial myself instead of using the deb packages. For most projects Mercurial is straight forward.

    Posted August 7th, 2007 in Open Source, Programming, Version Control. Tagged: , , .

    14 comments:

    1. Tom Tobin:

      Mercurial does indeed allow branches within a single repository:

      [url]http://www.selenic.com/mercurial/wiki/index.cgi/NamedBranches[/url]

    2. dsp:

      Yes, I read that too. For sure you are right, so it’s not a disadvantage, but i personally prefer the git way, its way more comfortable.

    3. Humberto Diógenes:

      Nice article! To me, one important advantage of Git over Mercurial now is the git-svn utility, which allows me to fully use git even with svn repositories.

      Mercurial has lots of options for reading a svn repository, but no easy way to push changes back (AFAIK).

      I didn’t understand what you meant here: “One of the probably nicest features in the build in webserver to serve Mercurial repository throughout the network which makes working together for a short time without having time to setup a complete environment very easy.”

    4. tonfa:

      “Furthermore I discovered that between 0.9.0 and 0.9.2 the repository layout changed, which makes it impossible for me to push to my debian machine from my ubuntu without compiling Mercurial myself instead of using the deb packages.”

      If you don’t try to locally use a new repo with an old hg you shouldn’t have any problem. The wire protocol didn’t change.

    5. dsp:

      Hmm in fact I initialized the hg repos on my laptop machine with the newer repository and uploaded it to my debian server to share it, but it doesn’t worked out for me. Maybe there is a simple solution.

      I have to take a look at mercurial again, at the moment I’m very happy with my (personal) git.

    6. dsp:

      I refered to the “hg serve” command that starts up a webserver. You now can easily browse the hg repos, without having to configure apache/cgi-bin, etc.

    7. bilbo:

      Wow! This article is great! I’ve recently started using git. However, it doesn’t have great windows support, so I started looking some more after hearing some good thing about Mercurial and Bazaar. This article has really helped me decide to give Mercurial a try.

    8. jengelh:

      ># The only way to access non tagged commits are long SHA1 keys

      You can use abbreviated ones.

      ># Manual garbage collecting

      I would particularly dislike it doing automatic collection every 1000 operations, especially on big repositories like the linux kernel.

    9. John Goerzen:

      A couple of comments:

      Git does have native Windows support these days. Also, manual garbage collection is no longer required, as Git will automatically do this when needed.

    10. dsp:

      Definatly true. It has windows support these days (not native, you still need msys), but acutally good enough to be worth using.

      Automatic garbage collection is great! I don’t know when it was introduced, but it’s good to know that it exists.

    11. Dardo Sordi:

      Have you tried git-instaweb ?

    12. Fredrik Bränström:

      Hg is the element abbreviation for Mercury.

      The lack of local branching in hg will probably be what will turn me off the most when I try it. But it seems like a nice option beside Git, I’ll probably stick with Git though. :)

    13. Kay:

      Of course now Mercurial supports per-repository branching..

      http://hgbook.red-bean.com/hgbookch8.html

    14. dsp:

      Yes, but they are for long living branches. So it’s from a design perspective more or less the same as CVS or SVN does and _not_ what git does with it’s short living branches.

    Leave a response: