comparison mercurial/subrepo.py @ 11775:a8614c5a5e9a

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.
author Martin Geisler <mg@lazybytes.net>
date Thu, 15 Jul 2010 18:10:05 +0200
parents 324bad1dc230
children f3075ffa6b30
comparison
equal deleted inserted replaced
11774:91c4e6d2c9e5 11775:a8614c5a5e9a
10 import config, util, node, error 10 import config, util, node, error
11 hg = None 11 hg = None
12 12
13 nullstate = ('', '', 'empty') 13 nullstate = ('', '', 'empty')
14 14
15 def state(ctx): 15 def state(ctx, ui):
16 """return a state dict, mapping subrepo paths configured in .hgsub 16 """return a state dict, mapping subrepo paths configured in .hgsub
17 to tuple: (source from .hgsub, revision from .hgsubstate, kind 17 to tuple: (source from .hgsub, revision from .hgsubstate, kind
18 (key in types dict)) 18 (key in types dict))
19 """ 19 """
20 p = config.config() 20 p = config.config()
25 raise util.Abort(_("subrepo spec file %s not found") % f) 25 raise util.Abort(_("subrepo spec file %s not found") % f)
26 26
27 if '.hgsub' in ctx: 27 if '.hgsub' in ctx:
28 read('.hgsub') 28 read('.hgsub')
29 29
30 for path, src in ui.configitems('subpaths'):
31 p.set('subpaths', path, src, ui.configsource('subpaths', path))
32
30 rev = {} 33 rev = {}
31 if '.hgsubstate' in ctx: 34 if '.hgsubstate' in ctx:
32 try: 35 try:
33 for l in ctx['.hgsubstate'].data().splitlines(): 36 for l in ctx['.hgsubstate'].data().splitlines():
34 revision, path = l.split(" ", 1) 37 revision, path = l.split(" ", 1)
43 if src.startswith('['): 46 if src.startswith('['):
44 if ']' not in src: 47 if ']' not in src:
45 raise util.Abort(_('missing ] in subrepo source')) 48 raise util.Abort(_('missing ] in subrepo source'))
46 kind, src = src.split(']', 1) 49 kind, src = src.split(']', 1)
47 kind = kind[1:] 50 kind = kind[1:]
51
52 for pattern, repl in p.items('subpaths'):
53 try:
54 src = re.sub(pattern, repl, src, 1)
55 except re.error, e:
56 raise util.Abort(_("bad subrepository pattern in %s: %s")
57 % (p.source('subpaths', pattern), e))
58
48 state[path] = (src.strip(), rev.get(path, ''), kind) 59 state[path] = (src.strip(), rev.get(path, ''), kind)
49 60
50 return state 61 return state
51 62
52 def writestate(repo, state): 63 def writestate(repo, state):