Since Mercurial and Git are Distributed Version Control Systems (DVCSs), you should use at least use one separate repository per project, including shared projects and libraries.

Check out  HgInit.com for getting started with Mercurial.

When we were using Subversion here at Fog Creek Software, we had one big repository for everything. When we switched over to Mercurial, we quickly learned that DVCSs don’t work the same way, and aren’t really suited for one large repository like that. Now we have several repositories for each project.

For example, with Copilot, we have several different moving parts that are relatively independent of each other:

  • Helpers (downloadable EXE clients)
  • Reflector (server that links communication between helpers)
  • Website
  • Billing System
  • Aardvark (shared library used by the reflector, website, and billing system)

For each of those parts, we’ve created a separate repository group and we keep a devel and stable repository in each of those groups. New features go into devel and eventually get merged forward to stable, while bug fixes go into stable and get merged back into devel.

To keep everything in sync for deploy, we use tags. In Subversion, tags are a pain because they’re really not a tag as much as they are a full copy of your code in a different directory. With Mercurial, a tag is more like meta data on the repository, and you just treat them like a version number.

For example, to deploy a new version of the Copilot website  copy website-stable and aardvark-stable. Then tag each of those repositories on your local machine (you can easily have a batch file that does this for you, calculating out the tag number, e.g. Website000123). Then kick off the build process with the tag, which clones both repositories from the server into a build directory and runs hg up -C Website000123 to update them to the tag. Then it builds and deploys.

If you need to go back in time to that particular build, I can just run the same command, hg up -C Website000123 in each repository. You should notice that we tag both the Website and the Aardvark repos with Website000123, instead of tagging Aardvark with Aardvark000123. This is because we’ll also be tagging Aardvark for our reflector builds (Reflector000456) when they go out, and we want to be able to know which was which.

In addition, the following articles are a good start on some of the repository management topics mentioned here: