I have been very critical of distributed version control systems (DVCS) in the past. And like many things I thought in the past, I got older and wiser and now think I was wrong before. A few years ago I started using Mercurial and Git for some projects, and Git is pretty much a requirement if you want to work with open source code these days, especially on GitHub. These days, I only go back to using TFS or SVN if it’s a requirement for a certain customer (which it is surprisingly often).
However, getting started with a DVCS it is definitely a conceptual leap from what a lot of .NET developers are working with, since most of them are coming from a TFS/SourceSafe background, or maybe SVN. Once people make that leap, it the new approach makes a lot of sense, but I know from experience it can be really hard to make that leap when you’ve been used to one approach for most of your career.
Anyhow, while ramping up a developer for a client project that uses Mercurial, I found myself writing this quick conceptual explanation for the twentieth time, so I figured I’d put it here so I can just point to it in the future. Nothing new here, just my quick explanation.
Git and Mercurial are both distributed version control systems. This is a very different approach from TFS/VSS or even SVN (although SVN is closer). The core idea is that there is no single centralized server that you need to stay connective to. The repository you have on your own machine is a full blown Mercurial/Git repository, with a full history of the whole project, and you can commit, branch, merge, etc as much as you want with your local repository. Then when you are ready to release your changes into the wild (what you would normally consider checking into the central server in TFS or VSS), you pull the latest changes from the central repository (like GitHub or BitBucket), do any merging you need to do locally, and then push your changes up to the central server.
This may sound like basically the same thing as SVN but with an extra step (commit locally and then push to the central server, rather than just commiting straight to the central server), but it has its benefits. Normally if you are working against a central TFS/SVN server, you need to make sure you’re changes are solid and ready for release before checking anything in; before that point you changes are in limbo on your machine, either not checked in for several days (yikes), or you have to shelve them, which can be a pain if your source control platform even supports it. But in an DVCS, you can work on a feature, or several features locally, committing repeatedly as you go small incremental checkins, without having to worry about breaking anything for anyone else yet. Also, you can make local branches, so you can create a local branch to start working on a big feature that will take several days, but then when a production bug comes in you can switch back to the master/trunk/default branch quickly to fix it and release that fix, without disturbing your feature branch. While you can make these types of branches in TFS/SVN, they are always done on the server, which gets messy and complicated when you have a lot of developers. The DVCS approach lets you use work with all of your own mess locally, without having to clutter up anyone else’s workspace, or anyone cluttering yours. Then you can merge your feature changes into the trunk when it’s actually ready, or better yet before experimental features that never pan out, you can just throw that branch out and go back to the main trunk code.