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.
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).
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.
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!