<> <> = Subrepository Remapping Plan = This plan proposes a scheme for remapping the URLs used when cloning and pulling subrepos. Status: first part pushed as changeset [[http://hg.intevation.org/mercurial/crew/rev/a8614c5a5e9a|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.