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 = |
|
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