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 | 40 | gettext, |
|
41 | 41 | _, |
|
42 | 42 | ) |
|
43 | from mercurial.utils import stringutil | |
|
43 | 44 | |
|
44 | 45 | table = commands.table |
|
45 | 46 | globalopts = commands.globalopts |
@@ -85,7 +86,9 b' def get_opts(opts):' | |||
|
85 | 86 | if b'\n' in desc: |
|
86 | 87 | # only remove line breaks and indentation |
|
87 | 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 | 92 | yield (b", ".join(allopts), desc) |
|
90 | 93 | |
|
91 | 94 |
@@ -84,10 +84,18 b' def shlexer(data=None, filepath=None, wo' | |||
|
84 | 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 | 95 | def encodeargs(args): |
|
88 | 96 | def encodearg(s): |
|
89 |
lines = base64 |
|
|
90 | lines = [l.splitlines()[0] for l in lines] | |
|
97 | lines = base64_encodebytes(s) | |
|
98 | lines = [l.splitlines()[0] for l in pycompat.iterbytestr(lines)] | |
|
91 | 99 | return b''.join(lines) |
|
92 | 100 | |
|
93 | 101 | s = pickle.dumps(args) |
@@ -95,7 +103,7 b' def encodeargs(args):' | |||
|
95 | 103 | |
|
96 | 104 | |
|
97 | 105 | def decodeargs(s): |
|
98 |
s = base64 |
|
|
106 | s = base64_decodebytes(s) | |
|
99 | 107 | return pickle.loads(s) |
|
100 | 108 | |
|
101 | 109 |
@@ -55,7 +55,7 b' try:' | |||
|
55 | 55 | import warnings |
|
56 | 56 | |
|
57 | 57 | warnings.filterwarnings( |
|
58 |
|
|
|
58 | 'ignore', module='svn.core', category=DeprecationWarning | |
|
59 | 59 | ) |
|
60 | 60 | svn.core.SubversionException # trigger import to catch error |
|
61 | 61 | |
@@ -321,7 +321,26 b' def issvnurl(ui, url):' | |||
|
321 | 321 | and path[2:6].lower() == b'%3a/' |
|
322 | 322 | ): |
|
323 | 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 | 344 | except ValueError: |
|
326 | 345 | proto = b'file' |
|
327 | 346 | path = os.path.abspath(url) |
@@ -516,7 +535,9 b' class svn_source(converter_source):' | |||
|
516 | 535 | % (name, path) |
|
517 | 536 | ) |
|
518 | 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 | 541 | return path |
|
521 | 542 | |
|
522 | 543 | rev = optrev(self.last_changed) |
@@ -597,7 +618,7 b' class svn_source(converter_source):' | |||
|
597 | 618 | self.removed = set() |
|
598 | 619 | |
|
599 | 620 | files.sort() |
|
600 | files = zip(files, [rev] * len(files)) | |
|
621 | files = pycompat.ziplist(files, [rev] * len(files)) | |
|
601 | 622 | return (files, copies) |
|
602 | 623 | |
|
603 | 624 | def getchanges(self, rev, full): |
@@ -641,9 +662,9 b' class svn_source(converter_source):' | |||
|
641 | 662 | def checkrevformat(self, revstr, mapname=b'splicemap'): |
|
642 | 663 | """ fails if revision format does not match the correct format""" |
|
643 | 664 | if not re.match( |
|
644 | r'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]' | |
|
646 | r'{12,12}(.*)@[0-9]+$', | |
|
665 | br'svn:[0-9a-f]{8,8}-[0-9a-f]{4,4}-' | |
|
666 | br'[0-9a-f]{4,4}-[0-9a-f]{4,4}-[0-9a-f]' | |
|
667 | br'{12,12}(.*)@[0-9]+$', | |
|
647 | 668 | revstr, |
|
648 | 669 | ): |
|
649 | 670 | raise error.Abort( |
@@ -773,7 +794,7 b' class svn_source(converter_source):' | |||
|
773 | 794 | self.convertfp.flush() |
|
774 | 795 | |
|
775 | 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 | 799 | def revnum(self, rev): |
|
779 | 800 | return int(rev.split(b'@')[-1]) |
@@ -796,7 +817,7 b' class svn_source(converter_source):' | |||
|
796 | 817 | # We do not know the latest changed revision, |
|
797 | 818 | # keep the first one with changed paths. |
|
798 | 819 | break |
|
799 | if revnum <= stop: | |
|
820 | if stop is not None and revnum <= stop: | |
|
800 | 821 | break |
|
801 | 822 | |
|
802 | 823 | for p in paths: |
@@ -898,12 +919,12 b' class svn_source(converter_source):' | |||
|
898 | 919 | if not copyfrom_path: |
|
899 | 920 | continue |
|
900 | 921 | self.ui.debug( |
|
901 |
b"copied to %s from %s@% |
|
|
922 | b"copied to %s from %s@%d\n" | |
|
902 | 923 | % (entrypath, copyfrom_path, ent.copyfrom_rev) |
|
903 | 924 | ) |
|
904 | 925 | copies[self.recode(entrypath)] = self.recode(copyfrom_path) |
|
905 | 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 | 928 | pmodule, prevnum = revsplit(parents[0])[1:] |
|
908 | 929 | parentpath = pmodule + b"/" + entrypath |
|
909 | 930 | fromkind = self._checkpath(entrypath, prevnum, pmodule) |
@@ -1189,7 +1210,10 b' class svn_source(converter_source):' | |||
|
1189 | 1210 | return relative |
|
1190 | 1211 | |
|
1191 | 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 | 1217 | return None |
|
1194 | 1218 | |
|
1195 | 1219 | def _checkpath(self, path, revnum, module=None): |
@@ -4613,7 +4613,8 b' def log(ui, repo, *pats, **opts):' | |||
|
4613 | 4613 | |
|
4614 | 4614 | With --graph the revisions are shown as an ASCII art DAG with the most |
|
4615 | 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 | 4618 | 'x' is obsolete, '*' is unstable, and '+' represents a fork where the |
|
4618 | 4619 | changeset from the lines below is a parent of the 'o' merge on the same |
|
4619 | 4620 | line. |
@@ -178,9 +178,16 b' if ispy3:' | |||
|
178 | 178 | if os.name == r'nt': |
|
179 | 179 | sysargv = [a.encode("mbcs", "ignore") for a in sys.argv] |
|
180 | 180 | else: |
|
181 | ||
|
182 | def getdefaultlocale_if_known(): | |
|
183 | try: | |
|
184 | return locale.getdefaultlocale() | |
|
185 | except ValueError: | |
|
186 | return None, None | |
|
187 | ||
|
181 | 188 | encoding = ( |
|
182 | 189 | locale.getlocale()[1] |
|
183 |
or |
|
|
190 | or getdefaultlocale_if_known()[1] | |
|
184 | 191 | or sys.getfilesystemencoding() |
|
185 | 192 | ) |
|
186 | 193 | sysargv = [a.encode(encoding, "surrogateescape") for a in sys.argv] |
@@ -152,3 +152,23 b' Check tags are in UTF-8' | |||
|
152 | 152 | f7e66f98380ed1e53a797c5c7a7a2616a7ab377d branch\xc3\xa9 (esc) |
|
153 | 153 | |
|
154 | 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