Source Code Management (SCM) is a vital support tool for any serious code development, especially with many team members and for sharing as well as rollback opportunities. Today, I thought I’d introduce you to Distributed Version Control System (DVCS).
Regular SCM approaches
First of all, what I’d say SCM should offer is non-exclusive check-outs, i.e. that several developers can work on the same file, and then their changes are (hopefully) successfully merged. SourceSafe didn’t offer that, and was the reason for many development problems, especially in regards to exclusive check-outs (anyone remember files checked out to someone who had quit their job…?).
Team System and Subversion (and lots of other SCMs) offer developers to work on the same file, but with Team System, first it’s not optimal, and second, its tight integration to Visual Studio and just being one of many tools in a very large toolbox, at least throws me off.
That leaves us with Subversion, which is very wide-spread nowadays, and Google also chose it for Google Code, their online code hosting service.
The downside with the above
The problem with the mentioned tools/solutions is that they all depend on a central location, and neither of them is optimal when it comes to more complex development with a lot of code merging and branching going on. If we start with the central location issue, it means that the developer needs to have a constant connection to that central repository, and if not, there’s no way to get updates or, more importantly, version control different code steps that has just been developed locally.
Another downside with Subversion specifically, is that each folder of your project will get a hidden
.svn folder, which should be removed at deployment, and it definitely creates a world of pain if you mistakenly copy a Subversion-controlled folder into another folder already controlled by Subversion.
Enter Distributed Version Control System (DVCS)
The upside of using DVCS is that each developer have their own repository to which they can constantly commit and make changes to, even if there’s no connection available to the outside world. In a team project, it allows every developer this opportunity, and if they they need to exchange versions with each other, they can easily push and pull code from the other person’s repository.
It is also, very importantly, about conflict management. When you push your repository into someone else’s, your entire code is regarded as one revision, making sure all dependencies are in there and, likewise, making it much more easy to perform a complete rollback, if that were to become necessary.
The central location thing
However, there are naturally cases where one wants a central repository to be in sync with all different developer’s changes, and it might also be a public repository (especially in open-source cases) where this is the location from where all code should be offered. This is easily done with a DVCS, and when a developer takes out the code for the first thing, it’s not a check-out or update, it’s actual cloning of the central repository, so it then is completely stand-alone at the developer’s computer for code commits etc. The developer can then choose to push in his/her updates to the central location again.
For the lone ranger
Even if you don’t count on sharing your code with anyone, never ever, I find DVCS a great tool to version-control the code on my computer. That way I can consistently have back-ups and versioning for my code, in a very easy manner.
Don’t fear the reaper terminal
Now is a good time to mention that the examples I will show below will be written out in a terminal. If you’re not used to it, it might look scary at first, but don’t worry, I’m convinced you will soon feel how easy and clean it is, and that you get a good overview of everything’s that going on. In no time, you will probably feel just as cool as the Matrix guys…
Each code line will be preceded by a
$ character, and that’s just to indicate the start of a new line/command. The Terminal can be found in Windows at
Start > Run, enter
cmd and press enter and on a Mac it’s located at
/Applications/Utilities/Terminal. With Linux, it varies a bit between packages, but the most common places are at:
Applications menu > Accessories > Terminal(Gnome/Ubuntu).
Applications menu > System > Terminal(Xfce/Xubuntu)
KMenu > System > Terminal Program(named Konsole, applies to KDE/Kubuntu)
The DVCS of my choice for the moment, and the one I will use here, is Mercurial. It has gained a fair amount of popularity, and amongst the most well-known who uses it are Mozilla, Python and Adium, and a more extensive list is available in Some projects that use Mercurial.
First, you need to get Mercurial, and basically you can choose between downloading a binary package or download source code and build it (for you hardcore devs out there). My estimate is that Linux people will do just fine with the instructions in either of the two above links, but let’s be a bit clearer for you Windows and Mac folks.
The best bet is to go to Mercurial binary packages for Windows and Mac OS X and download an installer there. For those of you who are fans of Tortoise for Subversion, you could go for TortoiseHg.
For Mac OS X
Just like the Windows people, you can go to Mercurial binary packages for Windows and Mac OS X and find an installer there, or you can take your first plunge into the Terminal world. My recommendation is the latter, and then you have a couple of options.
Start with opening the Terminal. If you have a modern version of Python already installed, just type this on a line and press enter (remember: the
$ is just to indicate a new line/command which will be entered):
$ easy_install -U mercurial
Installation should start now. If that doesn’t work for you, or if you already have MacPorts installed (if not, it’s generally a good thing to have it, so install it then), type in this line in the Terminal:
sudo port install mercurial
Enter your password and off you go!
Taking the first baby steps with Mercurial
So, the above parts might have been messy for you, or you just got a hunger for something new. Either way, that’s usually the worst part, and now we’re on to some version control goodies!
I recommend for anyone to read Mercurial Quick Start, but I’ll walk you through some of the first easy steps.
Setting a username
The first step is to find and alter your user profile file, which will be found at
~/.hgrc for Mac and Linux (the
~ charecter indicates your Home folder. e.g.
/Users/robertnyman on a Mac), and at
%USERPROFILE%\Mercurial.ini in Windows. Open that file, and enter your desired username, like this:
[ui] username = Code Shaker <firstname.lastname@example.org>
Creating a repository
Navigate to your desired project folder, for instance named
test, and enter this line of code in the Terminal:
$ hg init
That’s it! Yes, really. You have now created a new Mercurial project, and can now start working with it any way you want to. What this in essence does is to create a hidden folder named
.hg in the root of your project. No more contamination of each folder, this is the only connection Mercurial needs.
Adding ignore list
Something to make your development life a bit more enjoyable is to add an ignore list, i.e. file types and file names which you don’t want to see when you work with Mercurial (for instance, the annoying
.DS_Store files for you Mac users). This is done by creating a file named
.hgignore in the root of your repository, and then give it content like this:
syntax: glob *.orig *.rej *~ *.o tests/*.err syntax: regexp .*\#.*\#$
As you can see, it’s easy to add/alter any of that code to match your needs.
Let’s go into your above created
testfolder, where you ran the
hg init command, and create three files:
Enter this line in the Terminal:
$ hg status
It checks the version control status of your current project, and the result will be:
? magic.css ? magic.html ? magic.js
The question mark before each file name indicates that it is not yet under source control. Like-wise, later on, an
A preceding the file name means it’s added to the repository, but never committed, and an
M shows that is in the repository, but that your version has changes in it (i.e. M as in Modified) which needs to be committed when ready.
Tip: you can write
st instead of
status, as it is a shortcut connection for the
To add a file, enter this command:
$ hg add
That command will add all unversioned files in your repository. If only want to add a certain file/certain files, enter the file name(s) as well:
$ hg add magic.html
Just as with the
add command, you can commit all added and recently modified in your repository, or you can specify which files you want to commit. Also remember that you need to specify a commit message, to be able to easily trace your changes and revision history.
$ hg commit -m "Commit of all files"
$ hg commit magic.css -m "Worked around weird CSS error"
Tip: you can write
ci instead of
commit, as it is a shortcut connection for the
Cloning is if you want to start your work with an already existing Mercurial project. What you do is that you clone that existing repository to get a complete local copy, and then you just work with it. It’s done like this:
$ hg clone http://selenic.com/hg/
If you want to push your changes into another repository, be it something you use as a central location or just one your team members, you use the
$ hg push http://selenic.com/hg/
The opposite to push is naturally pull, and is used to update your repository from another location:
$ hg pull http://selenic.com/hg/
Recommended is also to add the flag
-u to immediately get the updates into your files:
$ hg pull -u http://selenic.com/hg/
Adding default push and pull paths
In your repository, create a file named
hgrc under your
.hg file. In that file, enter this code:
[paths] default-push = http://selenic.com/hg/ default-pull = http://selenic.com/hg/
Then you can use the
pull command without adding any URL parameter.
If you want to share your code with the world, or just have a central backup location for yourself, there are some interesting Mercurial project hosting web sites out there. The three most well-known are Bitbucket, mozdev and SourceFoge, and others are available in the Free hosting of Mercurial repositories list.
Personally, I’ve only used Bitbucket so far, but I have been very happy with their services.
I hope this has been an exciting introduction to DVCS and that you have started to think about how to improve your own Source Code Management. My strong advice is to start and play around with this, and I promise you will like the new opportunities and more hassle-free code management.