comparison hgext/convert/filemap.py @ 17797:e4da793998bf

convert: normalize paths in filemaps (issue3612) convert doesn't normalise double slashes in paths. Path normalization is applied when a path is loaded into filemap and when a file lookup request is issued to filemap.
author Huayang <huayang@fb.com>
date Fri, 05 Oct 2012 16:27:34 -0700
parents 5fa09a3b0034
children 42455ebbab9f
comparison
equal deleted inserted replaced
17796:1b51638bf44a 17797:e4da793998bf
2 # Copyright 2007 Alexis S. L. Carvalho <alexis@cecm.usp.br> 2 # Copyright 2007 Alexis S. L. Carvalho <alexis@cecm.usp.br>
3 # 3 #
4 # This software may be used and distributed according to the terms of the 4 # This software may be used and distributed according to the terms of the
5 # GNU General Public License version 2 or any later version. 5 # GNU General Public License version 2 or any later version.
6 6
7 import posixpath
7 import shlex 8 import shlex
8 from mercurial.i18n import _ 9 from mercurial.i18n import _
9 from mercurial import util 10 from mercurial import util
10 from common import SKIPREV, converter_source 11 from common import SKIPREV, converter_source
11 12
13 e = len(name) 14 e = len(name)
14 while e != -1: 15 while e != -1:
15 yield name[:e], name[e + 1:] 16 yield name[:e], name[e + 1:]
16 e = name.rfind('/', 0, e) 17 e = name.rfind('/', 0, e)
17 yield '.', name 18 yield '.', name
19
20 def normalize(path):
21 ''' We use posixpath.normpath to support cross-platform path format.
22 However, it doesn't handle None input. So we wrap it up. '''
23 if path is None:
24 return None
25 return posixpath.normpath(path)
18 26
19 class filemapper(object): 27 class filemapper(object):
20 '''Map and filter filenames when importing. 28 '''Map and filter filenames when importing.
21 A name can be mapped to itself, a new name, or None (omit from new 29 A name can be mapped to itself, a new name, or None (omit from new
22 repository).''' 30 repository).'''
51 lex = shlex.shlex(open(path), path, True) 59 lex = shlex.shlex(open(path), path, True)
52 lex.wordchars += '!@#$%^&*()-=+[]{}|;:,./<>?' 60 lex.wordchars += '!@#$%^&*()-=+[]{}|;:,./<>?'
53 cmd = lex.get_token() 61 cmd = lex.get_token()
54 while cmd: 62 while cmd:
55 if cmd == 'include': 63 if cmd == 'include':
56 name = lex.get_token() 64 name = normalize(lex.get_token())
57 errs += check(name, self.exclude, 'exclude') 65 errs += check(name, self.exclude, 'exclude')
58 self.include[name] = name 66 self.include[name] = name
59 elif cmd == 'exclude': 67 elif cmd == 'exclude':
60 name = lex.get_token() 68 name = normalize(lex.get_token())
61 errs += check(name, self.include, 'include') 69 errs += check(name, self.include, 'include')
62 errs += check(name, self.rename, 'rename') 70 errs += check(name, self.rename, 'rename')
63 self.exclude[name] = name 71 self.exclude[name] = name
64 elif cmd == 'rename': 72 elif cmd == 'rename':
65 src = lex.get_token() 73 src = normalize(lex.get_token())
66 dest = lex.get_token() 74 dest = normalize(lex.get_token())
67 errs += check(src, self.exclude, 'exclude') 75 errs += check(src, self.exclude, 'exclude')
68 self.rename[src] = dest 76 self.rename[src] = dest
69 elif cmd == 'source': 77 elif cmd == 'source':
70 errs += self.parse(lex.get_token()) 78 errs += self.parse(normalize(lex.get_token()))
71 else: 79 else:
72 self.ui.warn(_('%s:%d: unknown directive %r\n') % 80 self.ui.warn(_('%s:%d: unknown directive %r\n') %
73 (lex.infile, lex.lineno, cmd)) 81 (lex.infile, lex.lineno, cmd))
74 errs += 1 82 errs += 1
75 cmd = lex.get_token() 83 cmd = lex.get_token()
76 return errs 84 return errs
77 85
78 def lookup(self, name, mapping): 86 def lookup(self, name, mapping):
87 name = normalize(name)
79 for pre, suf in rpairs(name): 88 for pre, suf in rpairs(name):
80 try: 89 try:
81 return mapping[pre], pre, suf 90 return mapping[pre], pre, suf
82 except KeyError: 91 except KeyError:
83 pass 92 pass