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 commit -a
git-config alias.co ‘commit -a’
and therefore build your own set of commands you often use.
- Rich set of features
- Local Branches
- Quiet good documentation
- Nice configuration
- Good web interface
- 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.
- Easy to understand and use
- Incremental commit ids per-repsitory
- Very good documentation
- 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.