Mercurial Subrepos: A past example revisited with a new technique


A while ago, I did a back-to-back comparison of Git and Mercurial on how to create aggregate projects containing unrelated repositories. For Git, I used the submodule option. For Mercurial, I used the Forest Extension. Since then, Mercurial (1.3) has rolled out a new experimental feature called subrepositories (subrepos). This new experimental feature seems slated to replace the Forest extension as an official core feature.

I was curious how the procedure for the new subrepos differed from forests, so I have revisited the earlier example I did using LuaDoc, and repeated it using subrepos.

The original Mercurial repositories for the underlying subrepos are in the same place from the Forest example, so all that is unchanged. So we just need to create a new repository containing all the other projects as subrepos. So first, we grab all the underlying projects.

$ mkdir LuaDocSubrepos
											$ cd LuaDocSubrepos
											$ hg clone lua
											$ hg clone luasocket
											$ hg clone luasql
											$ hg clone luafilesystem
											$ hg clone lualogging
											$ hg clone luadoc

Next, we need to create a new special file called .hgsub which holds the URLs to the underlying subrepositories. Our .hgsub file looks like this:

lua =
											luasocket =
											luasql =
											luafilesystem =
											lualogging =
											luadoc =

Finally, we create our new repository, add the .hgsub file, and commit it. If successful, a new special file called .hgsubstate will be generated and it will contain a list of the subrepos and some hash numbers. I then push the repository to a server so you can clone it. (I omit adding the CMake files here for brevity. See the old Forest entry for more details on that.)

$ hg init
											$ hg add .hgsub
											$ hg commit -m "Initial Subrepos repository creation"
											$ hg push

You can find the repository at Assembla I pushed to located here:

LuaDoc Mercurial Subrepos Repository

Your Turn:

So now you can grab it from the public server. Unlike Git and Mercurial with the Forest extension, this is just a one step process.

$ hg clone MyLuaDocSubrepos


I think this is slightly easier than using the Forest extension. And it is really nice to not have to tell people I want to share my projects with that they need to install an extension. It's hard enough to just get them to install Mercurial (or Git) for that matter.

This example doesn't demonstrate it, but for one of my other projects (which I hope to be talking publicly about real soon), I found creating submodules of submodules was a little easier than with the Forest extension. With the Forest, I would have to invoke fseed at each level when I first clone which was kind of annoying. Submodules seem to automatically recurse on clone so everything is in front of you after the initial clone.

Also, as an aside, I originally tried omitting the initial clone of all the underlying projects. My thinking was that the only important part was creating the .hgsub file. But as it turned out, this didn't work. When I commited the .hgsub, subdirectories were created but they were empty. And the .hgsubstate file contained hashs that were all 0. And when I tried to make a new clone of this, all the subrepos remained empty.

Finally, in all the different techniques (Git included), I wish there was a way to easily change the designated parents for the sub-respositories. For collaboration, I set up everything to point to a server, but for private development branches, I really prefer to clone locally. But in all these techniques, the server is hardcoded.

Reference Articles:

Copyright © PlayControl Software, LLC / Eric Wing