/!\ This page is primarily intended for Mercurial's developers.

/!\ This page is no longer relevant but is kept for historical purposes.

Subrepository Remapping Plan

<!> This plan proposes a scheme for remapping the URLs used when cloning and pulling subrepos. Status: first part pushed as changeset a8614c5a5e9a, second part put in the SubpathsExtension

The Problem

Consider a .hgsub file that reads

libs/libfoo = http://hg.company.com/libraries/libfoo

Now imagine that the company is bought by another company and that the Mercurial server changes its name. It could also happen that the repository is simply renamed because the server layout is reorganized. To handle this, one updates the .hgsub file to point to the new location of the repository.

This creates a problem when updating to old revisions: Mercurial will use the old version of the .hgsub file, the one that still refers to the old server, which is long gone.

A solution to this would be to keep a remapping table around that lets users remap old URLs to new URLs.

The solution

The solution is to introduce a level of indirection, which allows the right side of entries in .hgsub to be interpreted with respect to revision-independent information. This allows entries in .hgsub to use "symbolic" names rather than fixed paths:

libs/foo = libfoo

With the application of the extra information, libfoo can be remapped to http://hg.company.com/libraries/libfoo.

This mechanism can also be used by people who have hard coded paths and now need to remap them because of repository reorganization. In that case, there will be no symbolic names, instead there will only be URLs and the remapping will work on URLs only.

The hgrc File

The mapping is defined in a new configuration section called subpaths. This is where the user can remap the paths. Each entry maps the right side of an entry in .hgsub to a path. Example ~/.hgrc file:

[subpaths]
libfoo = http://hg.company.com/libraries/libfoo

The left-hand sides specify a regular expression to search for and the right-hand side specifies a replacement string. The replacement string can use backreferences for more complex situations such as this example

[subpaths]
http://server/(.*)-hg/ = http://hg.server/\1/

which replaces http://server/foo-hg/ with http://hg.server/foo/.

All patterns are applied in the order in which they are defined in the config files. By applying all patterns, it is possible to first map symbolic names into real URLs, and then remap those URLs further, for example to accomodate for a local SSH tunnel. Imagine we have the following files:

.hgsub:
libs/foo = libfoo

.hg/subpaths:
[subpaths]
libfoo = http://server.com/libfoo

.hg/hgrc:
[subpaths]
^http://server.com/ = ssh://localhost:1234/

The libs/foo subrepository will then be checked out from ssh://localhost:1234/libfoo because the libfoo symbolic name is first mapped into http://server.com/libfoo which is further mapped into ssh://localhost:1234/libfoo.

Distribution

/!\ This is not implemented in Mercurial. See the ProjrcExtension instead.

The normal configuration files are not transferred on clone, push, or pull, and so one must manually copy the remapping around. This is a problem for projects that use symbolic names for the subrepositories like the libfoo right-hand side used above. Such a project always needs a mapping and it would be nice if that mapping could be provided along with the project when it is cloned.

The .hg/subpaths File

This is a new file that resides in the .hg directory of a repository. It is not version controlled. Entries are the same as for hgrc files and only the subpaths section is read. Example .hg/subpaths file:

[subpaths]
libfoo = http://hg.company.com/libraries/libfoo

If present, the .hg/subpaths file is used to remap subrepository paths. Mappings defined in normal configuration files override those in the subpaths file.

The entries in the subpaths file are propagated via the PushkeyConcept: the subpaths file is reproduced in clones of a repository and refreshed with every pull from the repository. The local subpaths file is completely overwritten with the entries obtained from the repository you pull from. This is the reason for using a new file for the "project default mapping": it should not be mixed with the user's own mapping since that will make it impossible to overwrite it on a subsequent pull.

This design allows the project manager to maintain the mappings in the subpaths file in a central repository and be sure that the entire team, which is perhaps distributed in different sites, is using the up-to-date mappings in their clones without having to set up some additional proocedure to synchronize hgrc files.

Teams can still override the subpaths file with their local hgrc files, as explained above.

SubrepoRemappingPlan (last edited 2012-10-25 21:19:00 by mpm)