Merge lp:~jelmer/brz/probe-hg into lp:brz

Proposed by Jelmer Vernooij
Status: Merged
Approved by: Jelmer Vernooij
Approved revision: no longer in the source branch.
Merge reported by: The Breezy Bot
Merged at revision: not available
Proposed branch: lp:~jelmer/brz/probe-hg
Merge into: lp:brz
Diff against target: 1016 lines (+328/-96)
31 files modified
breezy/annotate.py (+1/-1)
breezy/bedding.py (+3/-1)
breezy/builtins.py (+4/-1)
breezy/bzr/bundle/commands.py (+4/-1)
breezy/bzr/knitpack_repo.py (+4/-1)
breezy/bzr/knitrepo.py (+3/-1)
breezy/bzr/smart/ping.py (+2/-1)
breezy/bzr/versionedfile.py (+3/-1)
breezy/bzr/workingtree_4.py (+3/-1)
breezy/cmd_version_info.py (+3/-1)
breezy/conflicts.py (+1/-1)
breezy/diff.py (+3/-1)
breezy/errors.py (+0/-35)
breezy/filters/__init__.py (+4/-1)
breezy/foreign.py (+1/-4)
breezy/ignores.py (+3/-1)
breezy/lazy_import.py (+46/-17)
breezy/lockable_files.py (+3/-1)
breezy/merge_directive.py (+3/-1)
breezy/mergeable.py (+3/-1)
breezy/multiparent.py (+3/-1)
breezy/plugin.py (+4/-1)
breezy/plugins/hg/__init__.py (+177/-0)
breezy/plugins/netrc_credential_store/__init__.py (+1/-4)
breezy/plugins/upload/cmds.py (+1/-1)
breezy/tag.py (+4/-1)
breezy/tests/test_lazy_import.py (+10/-10)
breezy/trace.py (+3/-1)
breezy/transport/http/__init__.py (+21/-3)
breezy/workingtree.py (+3/-1)
doc/en/release-notes/brz-3.1.txt (+4/-0)
To merge this branch: bzr merge lp:~jelmer/brz/probe-hg
Reviewer Review Type Date Requested Status
Jelmer Vernooij Approve
Review via email: mp+375181@code.launchpad.net

Commit message

Add a Mercurial prober that mentions that mercurial repositories are unsupported.

Description of the change

Add a Mercurial prober that mentions that mercurial repositories are unsupported.

To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) :
review: Approve
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'breezy/annotate.py'
2--- breezy/annotate.py 2019-06-16 01:03:51 +0000
3+++ breezy/annotate.py 2020-01-11 17:50:43 +0000
4@@ -36,12 +36,12 @@
5 import patiencediff
6
7 from breezy import (
8- errors,
9 tsort,
10 )
11 """)
12 from . import (
13 config,
14+ errors,
15 osutils,
16 )
17 from .repository import _strip_NULL_ghosts
18
19=== modified file 'breezy/bedding.py'
20--- breezy/bedding.py 2019-06-16 19:53:27 +0000
21+++ breezy/bedding.py 2020-01-11 17:50:43 +0000
22@@ -25,12 +25,14 @@
23 from .lazy_import import lazy_import
24 lazy_import(globals(), """
25 from breezy import (
26- errors,
27 osutils,
28 trace,
29 win32utils,
30 )
31 """)
32+from . import (
33+ errors,
34+ )
35 from .sixish import (
36 PY3,
37 )
38
39=== modified file 'breezy/builtins.py'
40--- breezy/builtins.py 2019-10-13 18:52:37 +0000
41+++ breezy/builtins.py 2020-01-11 17:50:43 +0000
42@@ -25,6 +25,10 @@
43 import breezy.bzr
44 import breezy.git
45
46+from . import (
47+ errors,
48+ )
49+
50 from . import lazy_import
51 lazy_import.lazy_import(globals(), """
52 import time
53@@ -38,7 +42,6 @@
54 directory_service,
55 delta,
56 config as _mod_config,
57- errors,
58 globbing,
59 gpg,
60 hooks,
61
62=== modified file 'breezy/bzr/bundle/commands.py'
63--- breezy/bzr/bundle/commands.py 2019-07-25 22:19:30 +0000
64+++ breezy/bzr/bundle/commands.py 2020-01-11 17:50:43 +0000
65@@ -23,11 +23,14 @@
66
67 from __future__ import absolute_import
68
69+from ... import (
70+ errors,
71+ )
72+
73 from ...lazy_import import lazy_import
74 lazy_import(globals(), """
75 from breezy import (
76 branch,
77- errors,
78 merge_directive,
79 revision as _mod_revision,
80 urlutils,
81
82=== modified file 'breezy/bzr/knitpack_repo.py'
83--- breezy/bzr/knitpack_repo.py 2019-01-09 00:04:02 +0000
84+++ breezy/bzr/knitpack_repo.py 2020-01-11 17:50:43 +0000
85@@ -18,6 +18,10 @@
86
87 from __future__ import absolute_import
88
89+from .. import (
90+ errors,
91+ )
92+
93 from ..lazy_import import lazy_import
94 lazy_import(globals(), """
95 import time
96@@ -25,7 +29,6 @@
97 from breezy import (
98 controldir,
99 debug,
100- errors,
101 osutils,
102 revision as _mod_revision,
103 trace,
104
105=== modified file 'breezy/bzr/knitrepo.py'
106--- breezy/bzr/knitrepo.py 2018-11-30 12:39:04 +0000
107+++ breezy/bzr/knitrepo.py 2020-01-11 17:50:43 +0000
108@@ -22,7 +22,6 @@
109
110 from breezy import (
111 controldir,
112- errors,
113 lockable_files,
114 lockdir,
115 osutils,
116@@ -38,6 +37,9 @@
117 xml7,
118 )
119 """)
120+from .. import (
121+ errors,
122+ )
123 from ..repository import (
124 InterRepository,
125 IsInWriteGroupError,
126
127=== modified file 'breezy/bzr/smart/ping.py'
128--- breezy/bzr/smart/ping.py 2018-08-08 02:10:06 +0000
129+++ breezy/bzr/smart/ping.py 2020-01-11 17:50:43 +0000
130@@ -23,11 +23,12 @@
131 from ...sixish import viewitems
132
133 lazy_import(globals(), """
134-from breezy import errors
135 from breezy.bzr.smart.client import _SmartClient
136 from breezy.transport import get_transport
137 """)
138
139+from breezy import errors
140+
141
142 class cmd_ping(Command):
143 """Pings a Bazaar smart server.
144
145=== modified file 'breezy/bzr/versionedfile.py'
146--- breezy/bzr/versionedfile.py 2019-06-16 15:20:09 +0000
147+++ breezy/bzr/versionedfile.py 2020-01-11 17:50:43 +0000
148@@ -29,7 +29,6 @@
149 from breezy import (
150 annotate,
151 bencode,
152- errors,
153 graph as _mod_graph,
154 osutils,
155 multiparent,
156@@ -43,6 +42,9 @@
157 knit,
158 )
159 """)
160+from .. import (
161+ errors,
162+ )
163 from ..registry import Registry
164 from ..sixish import (
165 BytesIO,
166
167=== modified file 'breezy/bzr/workingtree_4.py'
168--- breezy/bzr/workingtree_4.py 2020-01-11 14:56:33 +0000
169+++ breezy/bzr/workingtree_4.py 2020-01-11 17:50:43 +0000
170@@ -38,7 +38,6 @@
171 cleanup,
172 controldir,
173 debug,
174- errors,
175 filters as _mod_filters,
176 osutils,
177 revision as _mod_revision,
178@@ -53,6 +52,9 @@
179 )
180 """)
181
182+from .. import (
183+ errors,
184+ )
185 from .inventory import Inventory, ROOT_ID, entry_factory
186 from ..lock import LogicalLockResult
187 from ..lockable_files import LockableFiles
188
189=== modified file 'breezy/cmd_version_info.py'
190--- breezy/cmd_version_info.py 2018-11-12 01:41:38 +0000
191+++ breezy/cmd_version_info.py 2020-01-11 17:50:43 +0000
192@@ -23,13 +23,15 @@
193 lazy_import(globals(), """
194 from breezy import (
195 branch,
196- errors,
197 version_info_formats,
198 workingtree,
199 )
200 from breezy.i18n import gettext
201 """)
202
203+from . import (
204+ errors,
205+ )
206 from .commands import Command
207 from .option import Option, RegistryOption
208 from .sixish import text_type
209
210=== modified file 'breezy/conflicts.py'
211--- breezy/conflicts.py 2019-06-22 11:16:17 +0000
212+++ breezy/conflicts.py 2020-01-11 17:50:43 +0000
213@@ -27,7 +27,6 @@
214 import errno
215
216 from breezy import (
217- errors,
218 osutils,
219 rio,
220 trace,
221@@ -38,6 +37,7 @@
222 """)
223 from . import (
224 cache_utf8,
225+ errors,
226 commands,
227 option,
228 registry,
229
230=== modified file 'breezy/diff.py'
231--- breezy/diff.py 2019-12-23 01:39:21 +0000
232+++ breezy/diff.py 2020-01-11 17:50:43 +0000
233@@ -31,7 +31,6 @@
234 from breezy import (
235 cleanup,
236 controldir,
237- errors,
238 osutils,
239 textfile,
240 timestamp,
241@@ -42,6 +41,9 @@
242 from breezy.i18n import gettext
243 """)
244
245+from . import (
246+ errors,
247+ )
248 from .registry import (
249 Registry,
250 )
251
252=== modified file 'breezy/errors.py'
253--- breezy/errors.py 2019-09-01 16:44:05 +0000
254+++ breezy/errors.py 2020-01-11 17:50:43 +0000
255@@ -2027,41 +2027,6 @@
256 self.revision_id = revision_id
257
258
259-class IllegalUseOfScopeReplacer(InternalBzrError):
260-
261- _fmt = ("ScopeReplacer object %(name)r was used incorrectly:"
262- " %(msg)s%(extra)s")
263-
264- def __init__(self, name, msg, extra=None):
265- BzrError.__init__(self)
266- self.name = name
267- self.msg = msg
268- if extra:
269- self.extra = ': ' + str(extra)
270- else:
271- self.extra = ''
272-
273-
274-class InvalidImportLine(InternalBzrError):
275-
276- _fmt = "Not a valid import statement: %(msg)\n%(text)s"
277-
278- def __init__(self, text, msg):
279- BzrError.__init__(self)
280- self.text = text
281- self.msg = msg
282-
283-
284-class ImportNameCollision(InternalBzrError):
285-
286- _fmt = ("Tried to import an object to the same name as"
287- " an existing object. %(name)s")
288-
289- def __init__(self, name):
290- BzrError.__init__(self)
291- self.name = name
292-
293-
294 class NotAMergeDirective(BzrError):
295 """File starting with %(firstline)r is not a merge directive"""
296
297
298=== modified file 'breezy/filters/__init__.py'
299--- breezy/filters/__init__.py 2018-11-11 04:08:32 +0000
300+++ breezy/filters/__init__.py 2020-01-11 17:50:43 +0000
301@@ -48,12 +48,15 @@
302 lazy_import(globals(), """
303 from breezy import (
304 config,
305- errors,
306 osutils,
307 registry,
308 )
309 """)
310
311+from .. import (
312+ errors,
313+ )
314+
315
316 class ContentFilter(object):
317
318
319=== modified file 'breezy/foreign.py'
320--- breezy/foreign.py 2018-11-18 19:48:57 +0000
321+++ breezy/foreign.py 2020-01-11 17:50:43 +0000
322@@ -24,13 +24,10 @@
323 )
324 from .repository import Repository
325 from .revision import Revision
326-from .lazy_import import lazy_import
327-lazy_import(globals(), """
328-from breezy import (
329+from . import (
330 errors,
331 registry,
332 )
333-""")
334
335
336 class VcsMapping(object):
337
338=== modified file 'breezy/ignores.py'
339--- breezy/ignores.py 2019-11-19 18:10:28 +0000
340+++ breezy/ignores.py 2020-01-11 17:50:43 +0000
341@@ -27,11 +27,13 @@
342 lazy_import(globals(), """
343 from breezy import (
344 atomicfile,
345- bedding,
346 globbing,
347 trace,
348 )
349 """)
350+from . import (
351+ bedding,
352+ )
353
354 # ~/.config/breezy/ignore will be filled out using
355 # this ignore list, if it does not exist
356
357=== modified file 'breezy/lazy_import.py'
358--- breezy/lazy_import.py 2018-11-12 01:41:38 +0000
359+++ breezy/lazy_import.py 2020-01-11 17:50:43 +0000
360@@ -43,6 +43,43 @@
361
362 from __future__ import absolute_import
363
364+from .errors import BzrError, InternalBzrError
365+
366+
367+class ImportNameCollision(InternalBzrError):
368+
369+ _fmt = ("Tried to import an object to the same name as"
370+ " an existing object. %(name)s")
371+
372+ def __init__(self, name):
373+ BzrError.__init__(self)
374+ self.name = name
375+
376+
377+class IllegalUseOfScopeReplacer(InternalBzrError):
378+
379+ _fmt = ("ScopeReplacer object %(name)r was used incorrectly:"
380+ " %(msg)s%(extra)s")
381+
382+ def __init__(self, name, msg, extra=None):
383+ BzrError.__init__(self)
384+ self.name = name
385+ self.msg = msg
386+ if extra:
387+ self.extra = ': ' + str(extra)
388+ else:
389+ self.extra = ''
390+
391+
392+class InvalidImportLine(InternalBzrError):
393+
394+ _fmt = "Not a valid import statement: %(msg)\n%(text)s"
395+
396+ def __init__(self, text, msg):
397+ BzrError.__init__(self)
398+ self.text = text
399+ self.msg = msg
400+
401
402 class ScopeReplacer(object):
403 """A lazy object that will replace itself in the appropriate scope.
404@@ -84,8 +121,9 @@
405 scope = object.__getattribute__(self, '_scope')
406 obj = factory(self, scope, name)
407 if obj is self:
408- raise errors.IllegalUseOfScopeReplacer(name, msg="Object tried"
409- " to replace itself, check it's not using its own scope.")
410+ raise IllegalUseOfScopeReplacer(
411+ name, msg="Object tried"
412+ " to replace itself, check it's not using its own scope.")
413
414 # Check if another thread has jumped in while obj was generated.
415 real_obj = object.__getattribute__(self, '_real_obj')
416@@ -99,7 +137,7 @@
417
418 # Raise if proxying is disabled as obj has already been generated.
419 if not ScopeReplacer._should_proxy:
420- raise errors.IllegalUseOfScopeReplacer(
421+ raise IllegalUseOfScopeReplacer(
422 name, msg="Object already replaced, did you assign it"
423 " to another variable?")
424 return real_obj
425@@ -260,8 +298,8 @@
426 elif line.startswith('from '):
427 self._convert_from_str(line)
428 else:
429- raise errors.InvalidImportLine(line,
430- "doesn't start with 'import ' or 'from '")
431+ raise InvalidImportLine(
432+ line, "doesn't start with 'import ' or 'from '")
433
434 def _convert_import_str(self, import_str):
435 """This converts a import string into an import map.
436@@ -286,7 +324,7 @@
437 name = as_hunks[1].strip()
438 module_path = as_hunks[0].strip().split('.')
439 if name in self.imports:
440- raise errors.ImportNameCollision(name)
441+ raise ImportNameCollision(name)
442 if not module_path[0]:
443 raise ImportError(path)
444 # No children available in 'import foo as bar'
445@@ -345,7 +383,7 @@
446 else:
447 name = module = path
448 if name in self.imports:
449- raise errors.ImportNameCollision(name)
450+ raise ImportNameCollision(name)
451 self.imports[name] = (from_module_path, module, {})
452
453 def _canonicalize_import_text(self, text):
454@@ -377,7 +415,7 @@
455 else:
456 out.append(line.replace('(', '').replace(')', ''))
457 if cur is not None:
458- raise errors.InvalidImportLine(cur, 'Unmatched parenthesis')
459+ raise InvalidImportLine(cur, 'Unmatched parenthesis')
460 return out
461
462
463@@ -408,12 +446,3 @@
464 # This is just a helper around ImportProcessor.lazy_import
465 proc = ImportProcessor(lazy_import_class=lazy_import_class)
466 return proc.lazy_import(scope, text)
467-
468-
469-# The only module that this module depends on is 'breezy.errors'. But it
470-# can actually be imported lazily, since we only need it if there is a
471-# problem.
472-
473-lazy_import(globals(), """
474-from breezy import errors
475-""")
476
477=== modified file 'breezy/lockable_files.py'
478--- breezy/lockable_files.py 2018-11-11 04:08:32 +0000
479+++ breezy/lockable_files.py 2020-01-11 17:50:43 +0000
480@@ -20,13 +20,15 @@
481 lazy_import(globals(), """
482 from breezy import (
483 counted_lock,
484- errors,
485 lock,
486 transactions,
487 urlutils,
488 )
489 """)
490
491+from . import (
492+ errors,
493+ )
494 from .decorators import (
495 only_raises,
496 )
497
498=== modified file 'breezy/merge_directive.py'
499--- breezy/merge_directive.py 2019-07-27 22:47:49 +0000
500+++ breezy/merge_directive.py 2020-01-11 17:50:43 +0000
501@@ -26,7 +26,6 @@
502 cleanup,
503 diff,
504 email_message,
505- errors,
506 gpg,
507 hooks,
508 registry,
509@@ -42,6 +41,9 @@
510 serializer as bundle_serializer,
511 )
512 """)
513+from . import (
514+ errors,
515+ )
516 from .sixish import (
517 BytesIO,
518 )
519
520=== modified file 'breezy/mergeable.py'
521--- breezy/mergeable.py 2019-06-30 10:50:40 +0000
522+++ breezy/mergeable.py 2020-01-11 17:50:43 +0000
523@@ -19,7 +19,6 @@
524 from .lazy_import import lazy_import
525 lazy_import(globals(), """
526 from breezy import (
527- errors,
528 transport as _mod_transport,
529 urlutils,
530 )
531@@ -28,6 +27,9 @@
532 from breezy.i18n import gettext
533 """)
534
535+from . import (
536+ errors,
537+ )
538 from .sixish import (
539 BytesIO,
540 )
541
542=== modified file 'breezy/multiparent.py'
543--- breezy/multiparent.py 2019-03-02 21:46:18 +0000
544+++ breezy/multiparent.py 2020-01-11 17:50:43 +0000
545@@ -28,10 +28,12 @@
546
547 from breezy import (
548 bencode,
549- errors,
550 ui,
551 )
552 """)
553+from . import (
554+ errors,
555+ )
556 from .i18n import gettext
557 from .sixish import (
558 BytesIO,
559
560=== modified file 'breezy/plugin.py'
561--- breezy/plugin.py 2019-10-14 00:07:00 +0000
562+++ breezy/plugin.py 2020-01-11 17:50:43 +0000
563@@ -51,12 +51,15 @@
564 from breezy import (
565 bedding,
566 debug,
567- errors,
568 help_topics,
569 trace,
570 )
571 """)
572
573+from . import (
574+ errors,
575+ )
576+
577
578 _MODULE_PREFIX = "breezy.plugins."
579
580
581=== added directory 'breezy/plugins/hg'
582=== added file 'breezy/plugins/hg/__init__.py'
583--- breezy/plugins/hg/__init__.py 1970-01-01 00:00:00 +0000
584+++ breezy/plugins/hg/__init__.py 2020-01-11 17:50:43 +0000
585@@ -0,0 +1,177 @@
586+# Copyright (C) 2019 Jelmer Vernooij <jelmer@jelmer.uk>
587+#
588+# This program is free software; you can redistribute it and/or modify
589+# it under the terms of the GNU General Public License as published by
590+# the Free Software Foundation; version 3 of the License or
591+# (at your option) a later version.
592+#
593+# This program is distributed in the hope that it will be useful,
594+# but WITHOUT ANY WARRANTY; without even the implied warranty of
595+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
596+# GNU General Public License for more details.
597+#
598+# You should have received a copy of the GNU General Public License
599+# along with this program; if not, write to the Free Software
600+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
601+
602+"""Mercurial foreign branch support.
603+
604+Currently only tells the user that Mercurial is not supported.
605+"""
606+
607+from __future__ import absolute_import
608+
609+from ... import (
610+ controldir,
611+ errors,
612+ )
613+
614+from ... import version_info # noqa: F401
615+
616+
617+class MercurialUnsupportedError(errors.UnsupportedFormatError):
618+
619+ _fmt = ('Mercurial branches are not yet supported. '
620+ 'To convert Mercurial branches to Bazaar branches or vice versa, '
621+ 'use the fastimport format. ')
622+
623+
624+class LocalHgDirFormat(controldir.ControlDirFormat):
625+ """Mercurial directory format."""
626+
627+ def get_converter(self):
628+ raise NotImplementedError(self.get_converter)
629+
630+ def get_format_description(self):
631+ return "Local Mercurial control directory"
632+
633+ def initialize_on_transport(self, transport):
634+ raise errors.UninitializableFormat(self)
635+
636+ def is_supported(self):
637+ return False
638+
639+ def supports_transport(self, transport):
640+ return False
641+
642+ def check_support_status(self, allow_unsupported, recommend_upgrade=True,
643+ basedir=None):
644+ raise MercurialUnsupportedError()
645+
646+ def open(self, transport):
647+ # Raise NotBranchError if there is nothing there
648+ LocalHgProber().probe_transport(transport)
649+ raise NotImplementedError(self.open)
650+
651+
652+class LocalHgProber(controldir.Prober):
653+
654+ @classmethod
655+ def priority(klass, transport):
656+ return 100
657+
658+ @staticmethod
659+ def _has_hg_dumb_repository(transport):
660+ try:
661+ return transport.has_any([".hg/requires", ".hg/00changelog.i"])
662+ except (errors.NoSuchFile, errors.PermissionDenied,
663+ errors.InvalidHttpResponse):
664+ return False
665+
666+ @classmethod
667+ def probe_transport(klass, transport):
668+ """Our format is present if the transport has a '.hg/' subdir."""
669+ if klass._has_hg_dumb_repository(transport):
670+ return HgDirFormat()
671+ raise errors.NotBranchError(path=transport.base)
672+
673+ @classmethod
674+ def known_formats(cls):
675+ return [LocalHgDirFormat()]
676+
677+
678+class SmartHgDirFormat(controldir.ControlDirFormat):
679+ """Mercurial directory format."""
680+
681+ def get_converter(self):
682+ raise NotImplementedError(self.get_converter)
683+
684+ def get_format_description(self):
685+ return "Smart Mercurial control directory"
686+
687+ def initialize_on_transport(self, transport):
688+ raise errors.UninitializableFormat(self)
689+
690+ def is_supported(self):
691+ return False
692+
693+ def supports_transport(self, transport):
694+ return False
695+
696+ def check_support_status(self, allow_unsupported, recommend_upgrade=True,
697+ basedir=None):
698+ raise MercurialUnsupportedError()
699+
700+ def open(self, transport):
701+ # Raise NotBranchError if there is nothing there
702+ SmartHgProber().probe_transport(transport)
703+ raise NotImplementedError(self.open)
704+
705+
706+class SmartHgProber(controldir.Prober):
707+
708+ # Perhaps retrieve list from mercurial.hg.schemes ?
709+ _supported_schemes = ["http", "https"]
710+
711+ @classmethod
712+ def priority(klass, transport):
713+ return 90
714+
715+ @staticmethod
716+ def _has_hg_http_smart_server(transport, external_url):
717+ """Check if there is a Mercurial smart server at the remote location.
718+
719+ :param transport: Transport to check
720+ :param externa_url: External URL for transport
721+ :return: Boolean indicating whether transport is backed onto hg
722+ """
723+ from breezy.urlutils import urlparse
724+ parsed_url = urlparse.urlparse(external_url)
725+ parsed_url = parsed_url._replace(
726+ query='cmd=capabilities', path=parsed_url.path.rstrip('/') + '/hg')
727+ url = urlparse.urlunparse(parsed_url)
728+ resp = transport.request(
729+ 'GET', url, headers={'Accept': 'application/mercurial-0.1'})
730+ if resp.status == 404:
731+ return False
732+ ct = resp.getheader("Content-Type")
733+ if ct is None:
734+ return False
735+ return ct.startswith("application/mercurial")
736+
737+ @classmethod
738+ def probe_transport(klass, transport):
739+ try:
740+ external_url = transport.external_url()
741+ except errors.InProcessTransport:
742+ raise errors.NotBranchError(path=transport.base)
743+ scheme = external_url.split(":")[0]
744+ if scheme not in klass._supported_schemes:
745+ raise errors.NotBranchError(path=transport.base)
746+ from breezy import urlutils
747+ external_url = urlutils.split_segment_parameters(external_url)[0]
748+ # Explicitly check for .hg directories here, so we avoid
749+ # loading foreign branches through Mercurial.
750+ if (external_url.startswith("http:") or
751+ external_url.startswith("https:")):
752+ if klass._has_hg_http_smart_server(transport, external_url):
753+ return SmartHgDirFormat()
754+ raise errors.NotBranchError(path=transport.base)
755+
756+ @classmethod
757+ def known_formats(cls):
758+ return [SmartHgDirFormat()]
759+
760+
761+controldir.ControlDirFormat.register_prober(LocalHgProber)
762+controldir.ControlDirFormat.register_prober(SmartHgProber)
763
764=== modified file 'breezy/plugins/netrc_credential_store/__init__.py'
765--- breezy/plugins/netrc_credential_store/__init__.py 2018-11-11 04:08:32 +0000
766+++ breezy/plugins/netrc_credential_store/__init__.py 2020-01-11 17:50:43 +0000
767@@ -23,16 +23,13 @@
768
769 from ... import (
770 config,
771+ errors,
772 lazy_import,
773 )
774
775 lazy_import.lazy_import(globals(), """
776 import errno
777 import netrc
778-
779-from breezy import (
780- errors,
781- )
782 """)
783
784
785
786=== modified file 'breezy/plugins/upload/cmds.py'
787--- breezy/plugins/upload/cmds.py 2019-09-21 23:05:12 +0000
788+++ breezy/plugins/upload/cmds.py 2020-01-11 17:50:43 +0000
789@@ -21,6 +21,7 @@
790 from ... import (
791 commands,
792 config,
793+ errors,
794 lazy_import,
795 option,
796 osutils,
797@@ -30,7 +31,6 @@
798
799 from breezy import (
800 controldir,
801- errors,
802 globbing,
803 ignores,
804 revision,
805
806=== modified file 'breezy/tag.py'
807--- breezy/tag.py 2019-06-22 16:20:00 +0000
808+++ breezy/tag.py 2020-01-11 17:50:43 +0000
809@@ -40,11 +40,14 @@
810 from breezy import (
811 bencode,
812 cleanup,
813- errors,
814 trace,
815 )
816 """)
817
818+from . import (
819+ errors,
820+ )
821+
822
823 def _reconcile_tags(source_dict, dest_dict, overwrite):
824 """Do a two-way merge of two tag dictionaries.
825
826=== modified file 'breezy/tests/test_lazy_import.py'
827--- breezy/tests/test_lazy_import.py 2018-11-11 04:08:32 +0000
828+++ breezy/tests/test_lazy_import.py 2020-01-11 17:50:43 +0000
829@@ -354,7 +354,7 @@
830
831 # However, the next access on test_obj3 should raise an error
832 # because only now are we able to detect the problem.
833- self.assertRaises(errors.IllegalUseOfScopeReplacer,
834+ self.assertRaises(lazy_import.IllegalUseOfScopeReplacer,
835 getattr, test_obj3, 'foo')
836
837 self.assertEqual([('__getattribute__', 'foo'),
838@@ -448,7 +448,7 @@
839
840 self.assertEqual(InstrumentedReplacer,
841 object.__getattribute__(test_obj7, '__class__'))
842- e = self.assertRaises(errors.IllegalUseOfScopeReplacer, test_obj7)
843+ e = self.assertRaises(lazy_import.IllegalUseOfScopeReplacer, test_obj7)
844 self.assertIn("replace itself", e.msg)
845 self.assertEqual([('__call__', (), {}),
846 'factory'], actions)
847@@ -917,7 +917,7 @@
848
849 def test_missing_trailing(self):
850 proc = lazy_import.ImportProcessor()
851- self.assertRaises(errors.InvalidImportLine,
852+ self.assertRaises(lazy_import.InvalidImportLine,
853 proc._canonicalize_import_text,
854 "from foo import (\n bar\n")
855
856@@ -1016,13 +1016,13 @@
857
858 def test_incorrect_line(self):
859 proc = lazy_import.ImportProcessor()
860- self.assertRaises(errors.InvalidImportLine,
861+ self.assertRaises(lazy_import.InvalidImportLine,
862 proc._build_map, 'foo bar baz')
863- self.assertRaises(errors.InvalidImportLine,
864+ self.assertRaises(lazy_import.InvalidImportLine,
865 proc._build_map, 'improt foo')
866- self.assertRaises(errors.InvalidImportLine,
867+ self.assertRaises(lazy_import.InvalidImportLine,
868 proc._build_map, 'importfoo')
869- self.assertRaises(errors.InvalidImportLine,
870+ self.assertRaises(lazy_import.InvalidImportLine,
871 proc._build_map, 'fromimport')
872
873 def test_name_collision(self):
874@@ -1031,11 +1031,11 @@
875
876 # All of these would try to create an object with the
877 # same name as an existing object.
878- self.assertRaises(errors.ImportNameCollision,
879+ self.assertRaises(lazy_import.ImportNameCollision,
880 proc._build_map, 'import bar as foo')
881- self.assertRaises(errors.ImportNameCollision,
882+ self.assertRaises(lazy_import.ImportNameCollision,
883 proc._build_map, 'from foo import bar as foo')
884- self.assertRaises(errors.ImportNameCollision,
885+ self.assertRaises(lazy_import.ImportNameCollision,
886 proc._build_map, 'from bar import foo')
887
888 def test_relative_imports(self):
889
890=== modified file 'breezy/trace.py'
891--- breezy/trace.py 2019-07-13 14:35:12 +0000
892+++ breezy/trace.py 2020-01-11 17:50:43 +0000
893@@ -74,11 +74,13 @@
894 from breezy import (
895 bedding,
896 debug,
897- errors,
898 osutils,
899 ui,
900 )
901 """)
902+from . import (
903+ errors,
904+ )
905
906 from .sixish import (
907 PY3,
908
909=== modified file 'breezy/transport/http/__init__.py'
910--- breezy/transport/http/__init__.py 2020-01-10 02:20:50 +0000
911+++ breezy/transport/http/__init__.py 2020-01-11 17:50:43 +0000
912@@ -1037,6 +1037,9 @@
913 newurl = headers.get('uri')
914 else:
915 return
916+
917+ newurl = urljoin(req.get_full_url(), newurl)
918+
919 if self._debuglevel >= 1:
920 print('Redirected to: %s (followed: %r)' % (newurl,
921 req.follow_redirections))
922@@ -1044,8 +1047,6 @@
923 req.redirected_to = newurl
924 return fp
925
926- newurl = urljoin(req.get_full_url(), newurl)
927-
928 # This call succeeds or raise an error. urllib_request returns
929 # if redirect_request returns None, but our
930 # redirect_request never returns None.
931@@ -1830,6 +1831,7 @@
932 400,
933 403,
934 404, # Not found
935+ 405, # Method not allowed
936 416,
937 422,
938 501, # Not implemented
939@@ -2018,6 +2020,10 @@
940 return self._actual.code
941
942 @property
943+ def reason(self):
944+ return self._actual.reason
945+
946+ @property
947 def data(self):
948 if self._data is None:
949 self._data = self._actual.read()
950@@ -2081,16 +2087,28 @@
951 if range_header is not None:
952 bytes = 'bytes=' + range_header
953 headers = {'Range': bytes}
954+ else:
955+ range_header = None
956
957 response = self.request('GET', abspath, headers=headers)
958
959 if response.status == 404: # not found
960 raise errors.NoSuchFile(abspath)
961- elif response.status in (400, 416):
962+ elif response.status == 416:
963 # We don't know which, but one of the ranges we specified was
964 # wrong.
965 raise errors.InvalidHttpRange(abspath, range_header,
966 'Server return code %d' % response.status)
967+ elif response.status == 400:
968+ if range_header:
969+ # We don't know which, but one of the ranges we specified was
970+ # wrong.
971+ raise errors.InvalidHttpRange(
972+ abspath, range_header,
973+ 'Server return code %d' % response.status)
974+ else:
975+ raise errors.InvalidHttpResponse(
976+ abspath, 'Unexpected status %d' % response.status)
977 elif response.status not in (200, 206):
978 raise errors.InvalidHttpResponse(
979 abspath, 'Unexpected status %d' % response.status)
980
981=== modified file 'breezy/workingtree.py'
982--- breezy/workingtree.py 2020-01-10 01:37:30 +0000
983+++ breezy/workingtree.py 2020-01-11 17:50:43 +0000
984@@ -43,7 +43,6 @@
985 from breezy import (
986 cleanup,
987 conflicts as _mod_conflicts,
988- errors,
989 filters as _mod_filters,
990 merge,
991 revision as _mod_revision,
992@@ -56,6 +55,9 @@
993 )
994 """)
995
996+from . import (
997+ errors,
998+ )
999 from .controldir import (
1000 ControlComponent,
1001 ControlComponentFormatRegistry,
1002
1003=== modified file 'doc/en/release-notes/brz-3.1.txt'
1004--- doc/en/release-notes/brz-3.1.txt 2020-01-02 11:31:03 +0000
1005+++ doc/en/release-notes/brz-3.1.txt 2020-01-11 17:50:43 +0000
1006@@ -46,6 +46,10 @@
1007 have installed and speeds up import time since psutil brings in
1008 various other modules. (Jelmer Vernooij)
1009
1010+ * Add a basic Mercurial plugin that mentions that .hg repositories
1011+ are unsupported when the user attempts to access one.
1012+ (Jelmer Vernooij)
1013+
1014 * The ``2a`` format now officially supports storing tree references.
1015 It always partially supported storing tree reference data,
1016 and would happily pull in tree reference data from other repository

Subscribers

People subscribed via source and target branches