This is a modification and elaboration of the procedure described in
You’re using Mercurial to source-control a project. You want to split a given subset off into a separate Mercurial repository. (For example, suppose you’ve decided that the subset should be a separately managed subproject.)
This article assumes that you’re starting with the following directory structure:
project/ .hg/ subdir1/ sub1-files subdir2/ sub2-files subdir3/ sub3-files root-files
and that your goal is to split subdir2 off into a separate Mercurial repository, while leaving everything else (subdir1, subdir3, and root-files) within the main repo.
Split into two repositories
- Change directory to project‘s parent (i.e. to project/..)
- Create a new repository newmain for the top-level project, consisting of everything except subdir2:
- Create a file rootmap containing:
hg --config extensions.hgext.convert= convert --filemap rootmap project newmain cd newmain; hg update
- Create a new sub-repository within newmain, consisting of only subdir2:
- Create a file submap containing:
include subdir2 rename subdir2 .
hg --config extensions.hgext.convert= convert --filemap submap project newsub cd newsub hg update
At this point, we have two new subdirectories, newmain and newsub, but they’re
entirely independent of each other. (The original project directory/repo has not been modified.)
The new directories look like:
newmain/ .hg/ subdir1/ sub1-files subdir3/ sub3-files root-files newsub/ .hg/ sub2-files
- Each of newmain and newsub contains a .hgdirectory; they’re both Mercurial repositories
- newmain does not contain a subdir2
- What was the content of project/subdir2 is now at the root level of newsub
Configuring the subrepository relationship
Now that we have newmain and newsub, the next step is to glue them together into a
subrepository configuration. The easiest way is to put newsub back into newmain/subdir2:
mv newsub newmain/subdir2 cd newmain echo subdir2 = subdir2 >.hgsub hg add .hgsub hg commit .hgsub
The result looks just like the original project layout, except that newmain/subdir2 is now a subrepository, rather than simply a directory within the newmain repository. Note that newmain/subdir2 is so far the only repository for the new subproject (though the revision history still exists in project).
If newsub really is an independent project, one probably wants to host its repository independently of project‘s. Suppose the new project should be called module-name:
mv newsub module-name cd newmain hg clone ../module-name echo subdir2 = ../module-name >.hgsub hg add .hgsub hg commit .hgsub
The result of this is, again, a newmain that looks like project except that newmain/subdir2 is a subrepository. The difference is that the main repository for the new project is module-name, and newmain/subdir2 is a clone of that.
Presumably one wants to install the new repository in place of the old one:
mv project project.OLD mv newmain project
- if necessary, update the path/URL on the right side of the “=” in .hgsuband commit the change
- check for any commits that might have been made to (what is now) project.OLD while you were making these changes, and so aren’t yet in (the new version of) project