Show More
@@ -0,0 +1,2 b'' | |||||
|
1 | $ LANG=nonexistent LC_ALL=nonexistent LANGUAGE=nonexistent hg version -q | |||
|
2 | Mercurial Distributed SCM (version *) (glob) |
@@ -40,6 +40,7 b' from mercurial.i18n import (' | |||||
40 | gettext, |
|
40 | gettext, | |
41 | _, |
|
41 | _, | |
42 | ) |
|
42 | ) | |
|
43 | from mercurial.utils import stringutil | |||
43 |
|
44 | |||
44 | table = commands.table |
|
45 | table = commands.table | |
45 | globalopts = commands.globalopts |
|
46 | globalopts = commands.globalopts | |
@@ -85,7 +86,9 b' def get_opts(opts):' | |||||
85 | if b'\n' in desc: |
|
86 | if b'\n' in desc: | |
86 | # only remove line breaks and indentation |
|
87 | # only remove line breaks and indentation | |
87 | desc = b' '.join(l.lstrip() for l in desc.split(b'\n')) |
|
88 | desc = b' '.join(l.lstrip() for l in desc.split(b'\n')) | |
88 | desc += default and _(b" (default: %s)") % bytes(default) or b"" |
|
89 | if default: | |
|
90 | default = stringutil.forcebytestr(default) | |||
|
91 | desc += _(b" (default: %s)") % default | |||
89 | yield (b", ".join(allopts), desc) |
|
92 | yield (b", ".join(allopts), desc) | |
90 |
|
93 | |||
91 |
|
94 |
@@ -84,10 +84,18 b' def shlexer(data=None, filepath=None, wo' | |||||
84 | return l |
|
84 | return l | |
85 |
|
85 | |||
86 |
|
86 | |||
|
87 | if pycompat.ispy3: | |||
|
88 | base64_encodebytes = base64.encodebytes | |||
|
89 | base64_decodebytes = base64.decodebytes | |||
|
90 | else: | |||
|
91 | base64_encodebytes = base64.encodestring | |||
|
92 | base64_decodebytes = base64.decodestring | |||
|
93 | ||||
|
94 | ||||
87 | def encodeargs(args): |
|
95 | def encodeargs(args): | |
88 | def encodearg(s): |
|
96 | def encodearg(s): | |
89 |
lines = base64 |
|
97 | lines = base64_encodebytes(s) | |
90 | lines = [l.splitlines()[0] for l in lines] |
|
98 | lines = [l.splitlines()[0] for l in pycompat.iterbytestr(lines)] | |
91 | return b''.join(lines) |
|
99 | return b''.join(lines) | |
92 |
|
100 | |||
93 | s = pickle.dumps(args) |
|
101 | s = pickle.dumps(args) | |
@@ -95,7 +103,7 b' def encodeargs(args):' | |||||
95 |
|
103 | |||
96 |
|
104 | |||
97 | def decodeargs(s): |
|
105 | def decodeargs(s): | |
98 |
s = base64 |
|
106 | s = base64_decodebytes(s) | |
99 | return pickle.loads(s) |
|
107 | return pickle.loads(s) | |
100 |
|
108 | |||
101 |
|
109 |
@@ -55,7 +55,7 b' try:' | |||||
55 | import warnings |
|
55 | import warnings | |
56 |
|
56 | |||
57 | warnings.filterwarnings( |
|
57 | warnings.filterwarnings( | |
58 |
|
|
58 | 'ignore', module='svn.core', category=DeprecationWarning | |
59 | ) |
|
59 | ) | |
60 | svn.core.SubversionException # trigger import to catch error |
|
60 | svn.core.SubversionException # trigger import to catch error | |
61 |
|
61 | |||
@@ -321,7 +321,26 b' def issvnurl(ui, url):' | |||||
321 | and path[2:6].lower() == b'%3a/' |
|
321 | and path[2:6].lower() == b'%3a/' | |
322 | ): |
|
322 | ): | |
323 | path = path[:2] + b':/' + path[6:] |
|
323 | path = path[:2] + b':/' + path[6:] | |
324 | path = urlreq.url2pathname(path) |
|
324 | # pycompat.fsdecode() / pycompat.fsencode() are used so that bytes | |
|
325 | # in the URL roundtrip correctly on Unix. urlreq.url2pathname() on | |||
|
326 | # py3 will decode percent-encoded bytes using the utf-8 encoding | |||
|
327 | # and the "replace" error handler. This means that it will not | |||
|
328 | # preserve non-UTF-8 bytes (https://bugs.python.org/issue40983). | |||
|
329 | # url.open() uses the reverse function (urlreq.pathname2url()) and | |||
|
330 | # has a similar problem | |||
|
331 | # (https://bz.mercurial-scm.org/show_bug.cgi?id=6357). It makes | |||
|
332 | # sense to solve both problems together and handle all file URLs | |||
|
333 | # consistently. For now, we warn. | |||
|
334 | unicodepath = urlreq.url2pathname(pycompat.fsdecode(path)) | |||
|
335 | if pycompat.ispy3 and u'\N{REPLACEMENT CHARACTER}' in unicodepath: | |||
|
336 | ui.warn( | |||
|
337 | _( | |||
|
338 | b'on Python 3, we currently do not support non-UTF-8 ' | |||
|
339 | b'percent-encoded bytes in file URLs for Subversion ' | |||
|
340 | b'repositories\n' | |||
|
341 | ) | |||
|
342 | ) | |||
|
343 | path = pycompat.fsencode(unicodepath) | |||
325 | except ValueError: |
|
344 | except ValueError: | |
326 | proto = b'file' |
|
345 | proto = b'file' | |
327 | path = os.path.abspath(url) |
|
346 | path = os.path.abspath(url) | |
@@ -516,7 +535,9 b' class svn_source(converter_source):' | |||||
516 | % (name, path) |
|
535 | % (name, path) | |
517 | ) |
|
536 | ) | |
518 | return None |
|
537 | return None | |
519 | self.ui.note(_(b'found %s at %r\n') % (name, path)) |
|
538 | self.ui.note( | |
|
539 | _(b'found %s at %r\n') % (name, pycompat.bytestr(path)) | |||
|
540 | ) | |||
520 | return path |
|
541 | return path | |
521 |
|
542 | |||
522 | rev = optrev(self.last_changed) |
|
543 | rev = optrev(self.last_changed) | |
@@ -597,7 +618,7 b' class svn_source(converter_source):' | |||||
597 | self.removed = set() |
|
618 | self.removed = set() | |
598 |
|
619 | |||
599 | files.sort() |
|
620 | files.sort() | |
600 | files = zip(files, [rev] * len(files)) |
|
621 | files = pycompat.ziplist(files, [rev] * len(files)) | |
601 | return (files, copies) |
|
622 | return (files, copies) | |
602 |
|
623 | |||
603 | def getchanges(self, rev, full): |
|
624 | def getchanges(self, rev, full): | |
@@ -641,9 +662,9 b' class svn_source(converter_source):' | |||||
641 | def checkrevformat(self, revstr, mapname=b'splicemap'): |
|
662 | def checkrevformat(self, revstr, mapname=b'splicemap'): | |
642 | """ fails if revision format does not match the correct format""" |
|
663 | """ fails if revision format does not match the correct format""" | |
643 | if not re.match( |
|
664 | if not re.match( | |
644 | r'svn:[0-9a-f]{8,8}-[0-9a-f]{4,4}-' |
|
665 | br'svn:[0-9a-f]{8,8}-[0-9a-f]{4,4}-' | |
645 | r'[0-9a-f]{4,4}-[0-9a-f]{4,4}-[0-9a-f]' |
|
666 | br'[0-9a-f]{4,4}-[0-9a-f]{4,4}-[0-9a-f]' | |
646 | r'{12,12}(.*)@[0-9]+$', |
|
667 | br'{12,12}(.*)@[0-9]+$', | |
647 | revstr, |
|
668 | revstr, | |
648 | ): |
|
669 | ): | |
649 | raise error.Abort( |
|
670 | raise error.Abort( | |
@@ -773,7 +794,7 b' class svn_source(converter_source):' | |||||
773 | self.convertfp.flush() |
|
794 | self.convertfp.flush() | |
774 |
|
795 | |||
775 | def revid(self, revnum, module=None): |
|
796 | def revid(self, revnum, module=None): | |
776 |
return b'svn:%s%s@% |
|
797 | return b'svn:%s%s@%d' % (self.uuid, module or self.module, revnum) | |
777 |
|
798 | |||
778 | def revnum(self, rev): |
|
799 | def revnum(self, rev): | |
779 | return int(rev.split(b'@')[-1]) |
|
800 | return int(rev.split(b'@')[-1]) | |
@@ -796,7 +817,7 b' class svn_source(converter_source):' | |||||
796 | # We do not know the latest changed revision, |
|
817 | # We do not know the latest changed revision, | |
797 | # keep the first one with changed paths. |
|
818 | # keep the first one with changed paths. | |
798 | break |
|
819 | break | |
799 | if revnum <= stop: |
|
820 | if stop is not None and revnum <= stop: | |
800 | break |
|
821 | break | |
801 |
|
822 | |||
802 | for p in paths: |
|
823 | for p in paths: | |
@@ -898,12 +919,12 b' class svn_source(converter_source):' | |||||
898 | if not copyfrom_path: |
|
919 | if not copyfrom_path: | |
899 | continue |
|
920 | continue | |
900 | self.ui.debug( |
|
921 | self.ui.debug( | |
901 |
b"copied to %s from %s@% |
|
922 | b"copied to %s from %s@%d\n" | |
902 | % (entrypath, copyfrom_path, ent.copyfrom_rev) |
|
923 | % (entrypath, copyfrom_path, ent.copyfrom_rev) | |
903 | ) |
|
924 | ) | |
904 | copies[self.recode(entrypath)] = self.recode(copyfrom_path) |
|
925 | copies[self.recode(entrypath)] = self.recode(copyfrom_path) | |
905 | elif kind == 0: # gone, but had better be a deleted *file* |
|
926 | elif kind == 0: # gone, but had better be a deleted *file* | |
906 |
self.ui.debug(b"gone from % |
|
927 | self.ui.debug(b"gone from %d\n" % ent.copyfrom_rev) | |
907 | pmodule, prevnum = revsplit(parents[0])[1:] |
|
928 | pmodule, prevnum = revsplit(parents[0])[1:] | |
908 | parentpath = pmodule + b"/" + entrypath |
|
929 | parentpath = pmodule + b"/" + entrypath | |
909 | fromkind = self._checkpath(entrypath, prevnum, pmodule) |
|
930 | fromkind = self._checkpath(entrypath, prevnum, pmodule) | |
@@ -1189,7 +1210,10 b' class svn_source(converter_source):' | |||||
1189 | return relative |
|
1210 | return relative | |
1190 |
|
1211 | |||
1191 | # The path is outside our tracked tree... |
|
1212 | # The path is outside our tracked tree... | |
1192 | self.ui.debug(b'%r is not under %r, ignoring\n' % (path, module)) |
|
1213 | self.ui.debug( | |
|
1214 | b'%r is not under %r, ignoring\n' | |||
|
1215 | % (pycompat.bytestr(path), pycompat.bytestr(module)) | |||
|
1216 | ) | |||
1193 | return None |
|
1217 | return None | |
1194 |
|
1218 | |||
1195 | def _checkpath(self, path, revnum, module=None): |
|
1219 | def _checkpath(self, path, revnum, module=None): |
@@ -4613,7 +4613,8 b' def log(ui, repo, *pats, **opts):' | |||||
4613 |
|
4613 | |||
4614 | With --graph the revisions are shown as an ASCII art DAG with the most |
|
4614 | With --graph the revisions are shown as an ASCII art DAG with the most | |
4615 | recent changeset at the top. |
|
4615 | recent changeset at the top. | |
4616 |
'o' is a changeset, '@' is a working directory parent, ' |
|
4616 | 'o' is a changeset, '@' is a working directory parent, '%' is a changeset | |
|
4617 | involved in an unresolved merge conflict, '_' closes a branch, | |||
4617 | 'x' is obsolete, '*' is unstable, and '+' represents a fork where the |
|
4618 | 'x' is obsolete, '*' is unstable, and '+' represents a fork where the | |
4618 | changeset from the lines below is a parent of the 'o' merge on the same |
|
4619 | changeset from the lines below is a parent of the 'o' merge on the same | |
4619 | line. |
|
4620 | line. |
@@ -178,9 +178,16 b' if ispy3:' | |||||
178 | if os.name == r'nt': |
|
178 | if os.name == r'nt': | |
179 | sysargv = [a.encode("mbcs", "ignore") for a in sys.argv] |
|
179 | sysargv = [a.encode("mbcs", "ignore") for a in sys.argv] | |
180 | else: |
|
180 | else: | |
|
181 | ||||
|
182 | def getdefaultlocale_if_known(): | |||
|
183 | try: | |||
|
184 | return locale.getdefaultlocale() | |||
|
185 | except ValueError: | |||
|
186 | return None, None | |||
|
187 | ||||
181 | encoding = ( |
|
188 | encoding = ( | |
182 | locale.getlocale()[1] |
|
189 | locale.getlocale()[1] | |
183 |
or |
|
190 | or getdefaultlocale_if_known()[1] | |
184 | or sys.getfilesystemencoding() |
|
191 | or sys.getfilesystemencoding() | |
185 | ) |
|
192 | ) | |
186 | sysargv = [a.encode(encoding, "surrogateescape") for a in sys.argv] |
|
193 | sysargv = [a.encode(encoding, "surrogateescape") for a in sys.argv] |
@@ -152,3 +152,23 b' Check tags are in UTF-8' | |||||
152 | f7e66f98380ed1e53a797c5c7a7a2616a7ab377d branch\xc3\xa9 (esc) |
|
152 | f7e66f98380ed1e53a797c5c7a7a2616a7ab377d branch\xc3\xa9 (esc) | |
153 |
|
153 | |||
154 | $ cd .. |
|
154 | $ cd .. | |
|
155 | ||||
|
156 | #if py3 | |||
|
157 | For now, on Python 3, we abort when encountering non-UTF-8 percent-encoded | |||
|
158 | bytes in a filename. | |||
|
159 | ||||
|
160 | $ hg convert file:///%ff test | |||
|
161 | initializing destination test repository | |||
|
162 | on Python 3, we currently do not support non-UTF-8 percent-encoded bytes in file URLs for Subversion repositories | |||
|
163 | file:///%ff does not look like a CVS checkout | |||
|
164 | $TESTTMP/file:/%ff does not look like a Git repository | |||
|
165 | file:///%ff does not look like a Subversion repository | |||
|
166 | file:///%ff is not a local Mercurial repository | |||
|
167 | file:///%ff does not look like a darcs repository | |||
|
168 | file:///%ff does not look like a monotone repository | |||
|
169 | file:///%ff does not look like a GNU Arch repository | |||
|
170 | file:///%ff does not look like a Bazaar repository | |||
|
171 | file:///%ff does not look like a P4 repository | |||
|
172 | abort: file:///%ff: missing or unsupported repository | |||
|
173 | [255] | |||
|
174 | #endif |
General Comments 0
You need to be logged in to leave comments.
Login now