subrepos: support remapping of .hgsub source paths
Given a .hgsub file containing
lib/libfoo = http://server/libfoo
the 'lib/libfoo' subrepo will be cloned from 'http://server/libfoo'.
This changeset introduces a remapping mechanism whereby the source
paths (the right-hand sides) in the .hgsub file can be remapped. This
subpaths section
[subpaths]
http://server = /local
will result in the 'lib/libfoo' subrepo being cloned from
'/local/libfoo' instead of from 'http://server/libfoo'.
The patterns (left-hand sides) are really regular expressions and the
replacement strings (right-hand sides) can refer to matched groups
using normal backreferences. This can be used for more complicated
replacements such as
[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 by which they are listed in the
config files.
--- a/mercurial/context.py Tue Aug 10 16:55:38 2010 +0200
+++ b/mercurial/context.py Thu Jul 15 18:10:05 2010 +0200
@@ -75,7 +75,7 @@
@propertycache
def substate(self):
- return subrepo.state(self)
+ return subrepo.state(self, self._repo.ui)
def __contains__(self, key):
return key in self._manifest
--- a/mercurial/subrepo.py Tue Aug 10 16:55:38 2010 +0200
+++ b/mercurial/subrepo.py Thu Jul 15 18:10:05 2010 +0200
@@ -12,7 +12,7 @@
nullstate = ('', '', 'empty')
-def state(ctx):
+def state(ctx, ui):
"""return a state dict, mapping subrepo paths configured in .hgsub
to tuple: (source from .hgsub, revision from .hgsubstate, kind
(key in types dict))
@@ -27,6 +27,9 @@
if '.hgsub' in ctx:
read('.hgsub')
+ for path, src in ui.configitems('subpaths'):
+ p.set('subpaths', path, src, ui.configsource('subpaths', path))
+
rev = {}
if '.hgsubstate' in ctx:
try:
@@ -45,6 +48,14 @@
raise util.Abort(_('missing ] in subrepo source'))
kind, src = src.split(']', 1)
kind = kind[1:]
+
+ for pattern, repl in p.items('subpaths'):
+ try:
+ src = re.sub(pattern, repl, src, 1)
+ except re.error, e:
+ raise util.Abort(_("bad subrepository pattern in %s: %s")
+ % (p.source('subpaths', pattern), e))
+
state[path] = (src.strip(), rev.get(path, ''), kind)
return state
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-subrepo-paths Thu Jul 15 18:10:05 2010 +0200
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+hg init outer
+cd outer
+
+echo 'sub = http://example.net/libfoo' > .hgsub
+hg add .hgsub
+
+echo '% hg debugsub with no remapping'
+hg debugsub
+
+cat > .hg/hgrc <<EOF
+[subpaths]
+http://example.net = ssh://localhost
+EOF
+
+echo '% hg debugsub with remapping'
+hg debugsub
+
+echo '% test bad subpaths pattern'
+cat > .hg/hgrc <<EOF
+[subpaths]
+.* = \1
+EOF
+hg debugsub 2>&1 | "$TESTDIR/filtertmp.py"
+
+exit 0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-subrepo-paths.out Thu Jul 15 18:10:05 2010 +0200
@@ -0,0 +1,10 @@
+% hg debugsub with no remapping
+path sub
+ source http://example.net/libfoo
+ revision
+% hg debugsub with remapping
+path sub
+ source ssh://localhost/libfoo
+ revision
+% test bad subpaths pattern
+abort: bad subrepository pattern in $HGTMP/test-subrepo-paths/outer/.hg/hgrc:2: invalid group reference