##// END OF EJS Templates
convert: correctly convert paths to UTF-8 for Subversion...
Manuel Jacob -
r45561:e3b19004 stable
parent child Browse files
Show More
@@ -3,6 +3,8 b''
3 # Copyright(C) 2007 Daniel Holth et al
3 # Copyright(C) 2007 Daniel Holth et al
4 from __future__ import absolute_import
4 from __future__ import absolute_import
5
5
6 import codecs
7 import locale
6 import os
8 import os
7 import re
9 import re
8 import xml.dom.minidom
10 import xml.dom.minidom
@@ -63,6 +65,38 b' except ImportError:'
63 svn = None
65 svn = None
64
66
65
67
68 # In Subversion, paths are Unicode (encoded as UTF-8), which Subversion
69 # converts from / to native strings when interfacing with the OS. When passing
70 # paths to Subversion, we have to recode them such that it roundstrips with
71 # what Subversion is doing.
72
73 fsencoding = None
74
75
76 def init_fsencoding():
77 global fsencoding, fsencoding_is_utf8
78 if fsencoding is not None:
79 return
80 if pycompat.iswindows:
81 # On Windows, filenames are Unicode, but we store them using the MBCS
82 # encoding.
83 fsencoding = 'mbcs'
84 else:
85 # This is the encoding used to convert UTF-8 back to natively-encoded
86 # strings in Subversion 1.14.0 or earlier with APR 1.7.0 or earlier.
87 with util.with_lc_ctype():
88 fsencoding = locale.nl_langinfo(locale.CODESET) or 'ISO-8859-1'
89 fsencoding = codecs.lookup(fsencoding).name
90 fsencoding_is_utf8 = fsencoding == codecs.lookup('utf-8').name
91
92
93 def fs2svn(s):
94 if fsencoding_is_utf8:
95 return s
96 else:
97 return s.decode(fsencoding).encode('utf-8')
98
99
66 class SvnPathNotFound(Exception):
100 class SvnPathNotFound(Exception):
67 pass
101 pass
68
102
@@ -117,7 +151,7 b' def geturl(path):'
117 path = b'/' + util.normpath(path)
151 path = b'/' + util.normpath(path)
118 # Module URL is later compared with the repository URL returned
152 # Module URL is later compared with the repository URL returned
119 # by svn API, which is UTF-8.
153 # by svn API, which is UTF-8.
120 path = encoding.tolocal(path)
154 path = fs2svn(path)
121 path = b'file://%s' % quote(path)
155 path = b'file://%s' % quote(path)
122 return svn.core.svn_path_canonicalize(path)
156 return svn.core.svn_path_canonicalize(path)
123
157
@@ -347,6 +381,17 b' def issvnurl(ui, url):'
347 except ValueError:
381 except ValueError:
348 proto = b'file'
382 proto = b'file'
349 path = os.path.abspath(url)
383 path = os.path.abspath(url)
384 try:
385 path.decode(fsencoding)
386 except UnicodeDecodeError:
387 ui.warn(
388 _(
389 b'Subversion requires that paths can be converted to '
390 b'Unicode using the current locale encoding (%s)\n'
391 )
392 % pycompat.sysbytes(fsencoding)
393 )
394 return False
350 if proto == b'file':
395 if proto == b'file':
351 path = util.pconvert(path)
396 path = util.pconvert(path)
352 elif proto in (b'http', 'https'):
397 elif proto in (b'http', 'https'):
@@ -384,6 +429,7 b' class svn_source(converter_source):'
384 def __init__(self, ui, repotype, url, revs=None):
429 def __init__(self, ui, repotype, url, revs=None):
385 super(svn_source, self).__init__(ui, repotype, url, revs=revs)
430 super(svn_source, self).__init__(ui, repotype, url, revs=revs)
386
431
432 init_fsencoding()
387 if not (
433 if not (
388 url.startswith(b'svn://')
434 url.startswith(b'svn://')
389 or url.startswith(b'svn+ssh://')
435 or url.startswith(b'svn+ssh://')
@@ -163,6 +163,26 b" Subversion sources don't support non-ASC"
163 abort: http://localhost:$HGPORT/\xff: missing or unsupported repository (esc)
163 abort: http://localhost:$HGPORT/\xff: missing or unsupported repository (esc)
164 [255]
164 [255]
165
165
166 In Subversion, paths are Unicode (encoded as UTF-8). Therefore paths that can't
167 be converted between UTF-8 and the locale encoding (which is always ASCII in
168 tests) don't work.
169
170 $ cp -R svn-repo $XFF
171 $ hg convert $XFF test
172 initializing destination test repository
173 Subversion requires that paths can be converted to Unicode using the current locale encoding (ascii)
174 \xff does not look like a CVS checkout (glob) (esc)
175 $TESTTMP/\xff does not look like a Git repository (esc)
176 \xff does not look like a Subversion repository (glob) (esc)
177 \xff is not a local Mercurial repository (glob) (esc)
178 \xff does not look like a darcs repository (glob) (esc)
179 \xff does not look like a monotone repository (glob) (esc)
180 \xff does not look like a GNU Arch repository (glob) (esc)
181 \xff does not look like a Bazaar repository (glob) (esc)
182 cannot find required "p4" tool
183 abort: \xff: missing or unsupported repository (glob) (esc)
184 [255]
185
166 #if py3
186 #if py3
167 For now, on Python 3, we abort when encountering non-UTF-8 percent-encoded
187 For now, on Python 3, we abort when encountering non-UTF-8 percent-encoded
168 bytes in a filename.
188 bytes in a filename.
General Comments 0
You need to be logged in to leave comments. Login now