30

25

In Subversion we use only one repository for all our projects and it works very well as we have only one revision number for projects and libraries.

We use the SVN revision number as build number, so it's really easy to match code version to each build of our products.

I'm totally new to Kiln, Mercurial and DVCS in general, but I think I can't use this same approach, right?

So should I use more than one repository? One repository per project maybe? What about our libraries and third party code that is shared among all projects?

Thanks for any comments.

flag

4 Answers

26

The short answer:

Yes, with a DVCS, you should use at least one separate repo per project, including shared projects and libraries.

The long answer:

We had basically the same setup here at Fog Creek when we were using Subversion. One big repo 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.

So let's say I need to deploy a new version of the Copilot website. To do it, I'll need a copy of website-stable and a copy of aardvark-stable. First, I tag each of those repos on my local machine (we have a batch file that does it for us, calculating out the tag number, e.g. Website000123). Then we kick off the build process with our tag, which clones both repos 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 I ever need to go back in time to that particular build, I can just run the same command, hg up -C Website000123 in each repo. 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.

We're currently working on some in-depth tutorials on exactly these sorts of topics. In the meantime, the following SE pages are a good start on some of the repo management topics I've mentioned here:

Update: The long-promised tutorial is out! Check it out HgInit.com

link|flag
In this set-up that you describe, are you using sub repositories or as there are not that many projects / repositories do you just mange this by hand? – Simon Mar 26 2010 at 15:30
@Simon: Subrepos didn't exist when we first set this up, so not yet for that project, though we are moving towards using them. Doing it without subrepos wasn't bad at all, though. – Tyler Hicks-Wright Mar 26 2010 at 17:39
2 
@Tyler Hicks-Wright: Would you be able to post a sample of your batch file (for tagging and tag numbering)? – triniMahn Oct 12 2010 at 14:02
4

Like you, I had one repository with Subversion. After I switched to Git I quickly discovered a DVCS doesn't work well with the one big bucket approach. I bit the bullet and started over by creating a separate repository for each project. I'm now moving to Mercurial (Kiln) and indeed have a separate repository for each project.

NOTE: I know I could have imported my existing Subversion repository. For me, it was easier create new local repositories for each current local working copy in its own directory. Nice and clean from the start, and I didn't care about losing my revision history and commit comments.

link|flag
2

My Lightbulb moment. Hg only looks down to a depth where it finds another repository, then it stops looking down that part of the folder tree.

In a folder path: if you have subfolder(s) with repo(s) then they are ignored by the repo at the higher level. So is everything lower than the subfolder. This is recursive. The repo in the parent folder will always stop when it finds another repo further down. Consider it a roadblock.

if you have subfolder(s) that don't have a repo then they are considered part of the first repo found on the way up the higher levels in their path.

If you have a repo with committed files in subfolders then later create a repo deeper down the path and try to commit changes inside that repo via the repo higher up the path that you were using earlier you will get an error telling you the file is in the other repo. You should probably forget it from the parent repo. Actually, I'm not sure what the best practise is for dealing with that.

To discover all this I created a folder structure and just used some dummy text files (use search to find assorted text files & copy across a few to each new folder) to muck around. Try it - in the 5 minutes it takes all will suddenly become clear.

None of this takes subrepos into account. I haven't mastered that bit, yet. Neither has TortoiseHg. It will commit to them (apparently) but it won't create nor organize them.

hope this helps.

link|flag
I tooled around a bit with subrepos and added an answer at kiln.stackexchange.com/questions/874/… Hope it helps. I really recommend taking a little time with some scrap text files and experimenting. That's all I have done. – CADbloke Jul 28 2010 at 3:02
0

How do you define "project"?

Let me explain my scenario: I have a product P to maintain, latest revision is 1.0

I have

  • one set of source files, with a 1.0 baseline, that contains all the released code.
  • one set of source files, starting with 1.0, but for the Patch development team to create patches 1.0.0.1, 1.0.0.2 ....
  • one set of source files, starting with 1.0, for the development team to work on release 1.1
  • one set of source files, starting with 1.0, for another development team to work on release 2.0
  • one set of external libraries (source) version 5.5 that our product compiles & uses in its builds. Each team may have to modify it for their new release.

Are you calling each one of the item a 'project'? or is it something else?

Same question reworded differently:

  1. How would you organize the product into 'repo'?
  2. How would you organize imported external source code? Often, we need to change external code (owned by other groups) to fit our model and suggest to them the change. They always oblige.
link|flag
I've moved this to its own question: kiln.stackexchange.com/questions/1214/… – Tyler Hicks-Wright Apr 22 2010 at 17:37

Your Answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.