Merge lp:~spiv/bzr-loom/plugin-init into lp:bzr-loom

Proposed by Andrew Bennetts
Status: Work in progress
Proposed branch: lp:~spiv/bzr-loom/plugin-init
Merge into: lp:bzr-loom
Diff against target: 836 lines (+244/-220)
2 files modified
branch.py (+89/-210)
formats.py (+155/-10)
To merge this branch: bzr merge lp:~spiv/bzr-loom/plugin-init
Reviewer Review Type Date Requested Status
Loom Developers Pending
Review via email: mp+32559@code.launchpad.net

Description of the change

This branch does a couple of loosely related things:
 * makes sure InterLoomBranch is always registered, by moving its definition to formats.py. I don't think this is a great solution, but it does solve the problem. Certainly by the time formats.register.formats() has been called that InterLoomBranch ought to be installed one way or another I think. This fixes bug 617212.
 * replaces "import bzrlib.branch" etc with "from bzrlib import branch" etc, following bzrlib's own conventions in format.py and branch.py. This also makes explicit a bunch of import dependencies like bzrlib.inventory that were only implicitly imported before.
 * uses lazy_import where appropriate in format.py and branch.py (and don't use it when not helpful... register_formats is always called by __init__.py so bzrlib.branch will unavoidably be imported).

I've verified that bzr with no plugins other than loom this saves 25 open syscalls (out of ~1500, as measured with strace: BZR_PLUGIN_PATH='-user:-core:-site' BZR_PLUGINS_AT=loom@$(pwd) strace -e stat64,open -c bzr.dev st). There's no noticeable time difference on a warm system, but this does suggest it is slightly more efficient this way, or at least no worse.

To post a comment you must log in.
Revision history for this message
Robert Collins (lifeless) wrote :

On Fri, Aug 13, 2010 at 7:13 PM, Andrew Bennetts
<email address hidden> wrote:
> Andrew Bennetts has proposed merging lp:~spiv/bzr-loom/plugin-init into lp:bzr-loom.
>
> Requested reviews:
>  Loom Developers (bzr-loom-devs)
> Related bugs:
>  #617212 "bzr selftest -s bt.per_interbranch Loom" finds 0 tests
>  https://bugs.launchpad.net/bugs/617212
>
>
> This branch does a couple of loosely related things:
>  * makes sure InterLoomBranch is always registered, by moving its definition to formats.py.  I don't think this is a great solution, but it does solve the problem.  Certainly by the time formats.register.formats() has been called that InterLoomBranch ought to be installed one way or another I think.  This fixes bug 617212.

Probably ok.

>  * replaces "import bzrlib.branch" etc with "from bzrlib import branch" etc, following bzrlib's own conventions in format.py and branch.py.  This also makes explicit a bunch of import dependencies like bzrlib.inventory that were only implicitly imported before.

This is going to be really confusing. Loom has its own 'branch'
module, so please don't do that. (Not to mention that I am not
convinced by the bzr convention anyhow. If you feel you must do that,
please do _mod_bzrlib_branch or something to make in unambiguous.
Personally though, import bzrlib.branch is pretty nice.

>  * uses lazy_import where appropriate in format.py and branch.py (and don't use it when not helpful... register_formats is always called by __init__.py so bzrlib.branch will unavoidably be imported).

I would keep it lazy myself, if we fix bzrlib to not load
bzrlib.branch when registering formats, it would be a shame to have to
rework this because of an arbitrary change

-Rob

Unmerged revisions

127. By Andrew Bennetts

Follow bzrlib conventions for imports, use lazy_imports in branch.py, and register InterLoomBranch in formats.py so that it is always registered for the bzr per_interbranch test suite.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'branch.py'
2--- branch.py 2010-07-16 08:30:13 +0000
3+++ branch.py 2010-08-13 07:13:40 +0000
4@@ -26,17 +26,29 @@
5
6 from StringIO import StringIO
7
8-import bzrlib.branch
9-from bzrlib import bzrdir
10+from bzrlib.lazy_import import lazy_import
11+lazy_import(globals(), """
12+from bzrlib import (
13+ bzrdir,
14+ inventory,
15+ lockable_files,
16+ lockdir,
17+ remote,
18+ revision as _mod_revision,
19+ symbol_versioning,
20+ trace,
21+ ui,
22+ urlutils,
23+ )
24+""")
25+from bzrlib import (
26+ branch as _mod_branch,
27+ errors,
28+ tree as _mod_tree,
29+ )
30+
31+
32 from bzrlib.decorators import needs_read_lock, needs_write_lock
33-import bzrlib.errors
34-import bzrlib.osutils
35-from bzrlib import remote, symbol_versioning
36-import bzrlib.trace
37-import bzrlib.ui
38-from bzrlib.revision import is_null, NULL_REVISION
39-import bzrlib.tree
40-import bzrlib.urlutils
41
42 import formats
43 import loom_io
44@@ -57,12 +69,12 @@
45 loom.unlock()
46
47
48-class AlreadyLoom(bzrlib.errors.BzrError):
49+class AlreadyLoom(errors.BzrError):
50
51 _fmt = """Loom %(loom)s is already a loom."""
52
53 def __init__(self, loom):
54- bzrlib.errors.BzrError.__init__(self)
55+ errors.BzrError.__init__(self)
56 self.loom = loom
57
58
59@@ -81,9 +93,9 @@
60 raise AlreadyLoom(branch)
61 try:
62 format = {
63- bzrlib.branch.BzrBranchFormat5: BzrBranchLoomFormat1,
64- bzrlib.branch.BzrBranchFormat6: BzrBranchLoomFormat6,
65- bzrlib.branch.BzrBranchFormat7: BzrBranchLoomFormat7,
66+ _mod_branch.BzrBranchFormat5: BzrBranchLoomFormat1,
67+ _mod_branch.BzrBranchFormat6: BzrBranchLoomFormat6,
68+ _mod_branch.BzrBranchFormat7: BzrBranchLoomFormat7,
69 }[branch._format.__class__]()
70 except KeyError:
71 raise UnsupportedBranchFormat(branch._format)
72@@ -96,26 +108,26 @@
73 NotALoom = formats.NotALoom
74
75
76-class LoomThreadError(bzrlib.errors.BzrError):
77+class LoomThreadError(errors.BzrError):
78 """Base class for Loom-Thread errors."""
79
80 def __init__(self, branch, thread):
81- bzrlib.errors.BzrError.__init__(self)
82+ errors.BzrError.__init__(self)
83 self.branch = branch
84 self.thread = thread
85
86
87-class UnrecordedRevision(bzrlib.errors.BzrError):
88+class UnrecordedRevision(errors.BzrError):
89
90 _fmt = """The revision %(revision_id)s is not recorded in the loom %(branch)s."""
91
92 def __init__(self, branch, revision_id):
93- bzrlib.errors.BzrError.__init__(self)
94+ errors.BzrError.__init__(self)
95 self.branch = branch
96 self.revision_id = revision_id
97
98
99-class UnsupportedBranchFormat(bzrlib.errors.BzrError):
100+class UnsupportedBranchFormat(errors.BzrError):
101
102 _fmt = """The branch format %(format)s is not supported by loomify."""
103
104@@ -138,7 +150,7 @@
105 _fmt = """No such thread '%(thread)s'."""
106
107
108-class NoLowerThread(bzrlib.errors.BzrError):
109+class NoLowerThread(errors.BzrError):
110
111 _fmt = """No lower thread exists."""
112
113@@ -148,7 +160,7 @@
114 _fmt = """Cannot combine threads on the bottom thread."""
115
116
117-class LoomMetaTree(bzrlib.tree.Tree):
118+class LoomMetaTree(_mod_tree.Tree):
119 """A 'tree' object that is used to commit the loom meta branch."""
120
121 def __init__(self, loom_meta_ie, loom_stream, loom_sha1):
122@@ -156,7 +168,7 @@
123
124 :param loom_content_lines: the unicode content to be used for the loom.
125 """
126- self._inventory = bzrlib.inventory.Inventory()
127+ self._inventory = inventory.Inventory()
128 self.inventory.add(loom_meta_ie)
129 self._loom_stream = loom_stream
130 self._loom_sha1 = loom_sha1
131@@ -203,7 +215,7 @@
132 # all threads gone
133 # revert to being a normal branch: revert to an empty revision
134 # history.
135- self.generate_revision_history(bzrlib.revision.NULL_REVISION)
136+ self.generate_revision_history(_mod_revision.NULL_REVISION)
137 return
138 # TODO, calculate the offset of removed threads.
139 # i.e. if there are ten threads removed, and current_index is 5,
140@@ -215,19 +227,19 @@
141 self._set_nick(threads[-1][0])
142 new_rev = threads[-1][1]
143 if new_rev == EMPTY_REVISION:
144- new_rev = bzrlib.revision.NULL_REVISION
145+ new_rev = _mod_revision.NULL_REVISION
146 self.generate_revision_history(new_rev)
147 return
148 # non-end thread removed.
149 self._set_nick(threads[current_index][0])
150 new_rev = threads[current_index][1]
151 if new_rev == EMPTY_REVISION:
152- new_rev = bzrlib.revision.NULL_REVISION
153+ new_rev = _mod_revision.NULL_REVISION
154 self.generate_revision_history(new_rev)
155 elif self.last_revision() != threads_dict[self.nick]:
156 new_rev = threads_dict[self.nick]
157 if new_rev == EMPTY_REVISION:
158- new_rev = bzrlib.revision.NULL_REVISION
159+ new_rev = _mod_revision.NULL_REVISION
160 self.generate_revision_history(new_rev)
161
162 def bind(self, other):
163@@ -237,7 +249,7 @@
164 :type other: Branch
165 """
166 # Looms are not currently bindable.
167- raise bzrlib.errors.UpgradeRequired(self.base)
168+ raise errors.UpgradeRequired(self.base)
169
170 @needs_read_lock
171 def clone(self, to_bzrdir, revision_id=None, repository_policy=None):
172@@ -258,7 +270,7 @@
173 result = format.initialize(to_bzrdir)
174 if repository_policy is not None:
175 repository_policy.configure_branch(result)
176- bzrlib.branch.InterBranch.get(self, result).copy_content_into(
177+ _mod_branch.InterBranch.get(self, result).copy_content_into(
178 revision_id=revision_id)
179 return result
180
181@@ -268,7 +280,7 @@
182 This is a short term measure to get to an all-tests passing status.
183 """
184 format = self.repository.bzrdir.checkout_metadir()
185- format.set_branch_format(bzrlib.branch.BzrBranchFormat6())
186+ format.set_branch_format(_mod_branch.BzrBranchFormat6())
187 return format
188
189 def get_loom_state(self):
190@@ -282,7 +294,7 @@
191 def get_old_bound_location(self):
192 """Return the URL of the branch we used to be bound to."""
193 # No binding for looms yet.
194- raise bzrlib.errors.UpgradeRequired(self.base)
195+ raise errors.UpgradeRequired(self.base)
196
197 def get_threads(self, rev_id):
198 """Return the threads from a loom revision.
199@@ -294,7 +306,7 @@
200 symbol_versioning.warn('NULL_REVISION should be used for the null'
201 ' revision instead of None, as of bzr 0.90.',
202 DeprecationWarning, stacklevel=2)
203- if is_null(rev_id):
204+ if _mod_revision.is_null(rev_id):
205 return []
206 content = self._loom_content(rev_id)
207 return self._parse_loom(content)
208@@ -308,14 +320,14 @@
209 threads = self.get_loom_state().get_threads()
210 for thread_name, thread_revision, _parents in threads:
211 thread_transport = root_transport.clone(thread_name)
212- user_location = bzrlib.urlutils.unescape_for_display(
213+ user_location = urlutils.unescape_for_display(
214 thread_transport.base, 'utf-8')
215 try:
216 control_dir = bzrdir.BzrDir.open(thread_transport.base,
217 possible_transports=[thread_transport])
218 tree, branch = control_dir._get_tree_branch()
219- except bzrlib.errors.NotBranchError:
220- bzrlib.trace.note('Creating branch at %s' % user_location)
221+ except errors.NotBranchError:
222+ trace.note('Creating branch at %s' % user_location)
223 branch = bzrdir.BzrDir.create_branch_convenience(
224 thread_transport.base,
225 possible_transports=[thread_transport])
226@@ -323,11 +335,11 @@
227 thread_transport.base)
228 else:
229 if thread_revision == branch.last_revision():
230- bzrlib.trace.note('Skipping up-to-date branch at %s'
231- % user_location)
232+ trace.note('Skipping up-to-date branch at %s'
233+ % user_location)
234 continue
235 else:
236- bzrlib.trace.note('Updating branch at %s' % user_location)
237+ trace.note('Updating branch at %s' % user_location)
238 if tree is not None:
239 tree.pull(self, stop_revision=thread_revision)
240 else:
241@@ -369,7 +381,7 @@
242 revision_for_thread = self.last_revision()
243 else:
244 revision_for_thread = threads[insertion_point - 1][1]
245- if is_null(revision_for_thread):
246+ if _mod_revision.is_null(revision_for_thread):
247 revision_for_thread = EMPTY_REVISION
248 threads.insert(
249 insertion_point,
250@@ -432,10 +444,10 @@
251 threads = state.get_threads()
252 # check the semantic value, not the serialised value for equality.
253 if old_threads == threads:
254- raise bzrlib.errors.PointlessCommit
255+ raise errors.PointlessCommit
256 builder = self.get_commit_builder(parents)
257- loom_ie = bzrlib.inventory.make_entry(
258- 'file', 'loom', bzrlib.inventory.ROOT_ID, 'loom_meta_tree')
259+ loom_ie = inventory.make_entry(
260+ 'file', 'loom', inventory.ROOT_ID, 'loom_meta_tree')
261 writer = loom_io.LoomWriter()
262 loom_stream = StringIO()
263 new_threads = [thread[0:2] for thread in threads]
264@@ -443,8 +455,8 @@
265 loom_stream.seek(0)
266 loom_tree = LoomMetaTree(loom_ie, loom_stream, loom_sha1)
267 if getattr(builder, 'record_root_entry', False):
268- root_ie = bzrlib.inventory.make_entry(
269- 'directory', '', None, bzrlib.inventory.ROOT_ID)
270+ root_ie = inventory.make_entry(
271+ 'directory', '', None, inventory.ROOT_ID)
272 builder.record_entry_contents(root_ie, [], '', loom_tree,
273 ('directory', None, None, None))
274 builder.record_entry_contents(
275@@ -469,7 +481,7 @@
276 state = self.get_loom_state()
277 threads = state.get_threads()
278 assert thread_name in state.get_threads_dict()
279- if is_null(revision_id):
280+ if _mod_revision.is_null(revision_id):
281 revision_id = EMPTY_REVISION
282 for position, (name, rev, parents) in enumerate(threads):
283 if name == thread_name:
284@@ -555,7 +567,7 @@
285 if len(threads):
286 # looms are enabled:
287 lastrev = self.last_revision()
288- if is_null(lastrev):
289+ if _mod_revision.is_null(lastrev):
290 lastrev = EMPTY_REVISION
291 if dict(state.get_threads_dict())[self.nick][0] != lastrev:
292 self.record_thread(self.nick, lastrev)
293@@ -604,11 +616,11 @@
294
295 @staticmethod
296 def make_result():
297- return bzrlib.branch.PullResult()
298+ return _mod_branch.PullResult()
299
300 @staticmethod
301 def post_hooks():
302- return bzrlib.branch.Branch.hooks['post_pull']
303+ return _mod_branch.Branch.hooks['post_pull']
304
305 def plain_transfer(self, result, run_hooks, stop_revision, overwrite):
306 # no thread commits ever
307@@ -617,7 +629,7 @@
308 if new_rev is None:
309 new_rev = self.source.last_revision()
310 if new_rev == EMPTY_REVISION:
311- new_rev = bzrlib.revision.NULL_REVISION
312+ new_rev = _mod_revision.NULL_REVISION
313 self.target.repository.fetch(self.source.repository,
314 revision_id=new_rev)
315 if not overwrite:
316@@ -625,11 +637,10 @@
317 new_rev)
318 last_rev = self.target.last_revision()
319 # get_ancestry returns None for NULL_REVISION currently.
320- if last_rev == NULL_REVISION:
321+ if last_rev == _mod_revision.NULL_REVISION:
322 last_rev = None
323 if last_rev not in new_rev_ancestry:
324- raise bzrlib.errors.DivergedBranches(
325- self.target, self.source)
326+ raise errors.DivergedBranches(self.target, self.source)
327 self.target.generate_revision_history(new_rev)
328 # get the final result object details
329 self.do_hooks(result, run_hooks)
330@@ -639,9 +650,9 @@
331 possible_transports=None, _override_hook_target=None, local=False):
332 """Implementation of push and pull"""
333 if local:
334- raise bzrlib.errors.LocalRequiresBoundBranch()
335+ raise errors.LocalRequiresBoundBranch()
336 # pull the loom, and position our
337- pb = bzrlib.ui.ui_factory.nested_progress_bar()
338+ pb = ui.ui_factory.nested_progress_bar()
339 try:
340 result = self.prepare_result(_override_hook_target)
341 self.target.lock_write()
342@@ -662,7 +673,7 @@
343 source_ancestry = self.source.repository.get_ancestry(
344 source_loom_rev)
345 if my_state.get_parents()[0] not in source_ancestry:
346- raise bzrlib.errors.DivergedBranches(
347+ raise errors.DivergedBranches(
348 self.target, self.source)
349 # fetch the loom content
350 self.target.repository.fetch(self.source.repository,
351@@ -679,7 +690,7 @@
352 # thread to include all content.
353 for rev_id in reversed(revisions):
354 if rev_id not in (EMPTY_REVISION,
355- bzrlib.revision.NULL_REVISION):
356+ _mod_revision.NULL_REVISION):
357 # fetch the loom content for this revision
358 self.target.repository.fetch(self.source.repository,
359 revision_id=rev_id)
360@@ -697,7 +708,7 @@
361 # and position the branch on the top loom
362 new_rev = threads[-1][1]
363 if new_rev == EMPTY_REVISION:
364- new_rev = bzrlib.revision.NULL_REVISION
365+ new_rev = _mod_revision.NULL_REVISION
366 self.target.generate_revision_history(new_rev)
367 self.do_hooks(result, run_hooks)
368 return result
369@@ -712,14 +723,14 @@
370
371 @staticmethod
372 def make_result():
373- return bzrlib.branch.BranchPushResult()
374+ return _mod_branch.BranchPushResult()
375
376 @staticmethod
377 def post_hooks():
378- return bzrlib.branch.Branch.hooks['post_push']
379-
380-
381-class LoomBranch(LoomSupport, bzrlib.branch.BzrBranch5):
382+ return _mod_branch.Branch.hooks['post_push']
383+
384+
385+class LoomBranch(LoomSupport, _mod_branch.BzrBranch5):
386 """The Loom branch.
387
388 A mixin is used as the easiest migration path to support branch6. A
389@@ -727,7 +738,7 @@
390 """
391
392
393-class LoomBranch6(LoomSupport, bzrlib.branch.BzrBranch6):
394+class LoomBranch6(LoomSupport, _mod_branch.BzrBranch6):
395 """Branch6 Loom branch.
396
397 A mixin is used as the easiest migration path to support branch6. A
398@@ -735,7 +746,7 @@
399 """
400
401
402-class LoomBranch7(LoomSupport, bzrlib.branch.BzrBranch7):
403+class LoomBranch7(LoomSupport, _mod_branch.BzrBranch7):
404 """Branch6 Loom branch.
405
406 A mixin is used as the easiest migration path to support branch7.
407@@ -752,7 +763,7 @@
408 def initialize(self, a_bzrdir, name=None):
409 """Create a branch of this format in a_bzrdir."""
410 if name is not None:
411- raise bzrlib.errors.NoColocatedBranchSupport(self)
412+ raise errors.NoColocatedBranchSupport(self)
413 super(LoomFormatMixin, self).initialize(a_bzrdir, name=None)
414 branch_transport = a_bzrdir.get_branch_transport(self)
415 files = []
416@@ -762,8 +773,8 @@
417 writer.write(state_stream)
418 state_stream.seek(0)
419 files.append(('last-loom', state_stream))
420- control_files = bzrlib.lockable_files.LockableFiles(
421- branch_transport, 'lock', bzrlib.lockdir.LockDir)
422+ control_files = lockable_files.LockableFiles(
423+ branch_transport, 'lock', lockdir.LockDir)
424 control_files.lock_write()
425 try:
426 for name, stream in files:
427@@ -783,13 +794,13 @@
428 it is unused.
429 """
430 if not _found:
431- format = BranchFormat.find_format(a_bzrdir)
432+ format = _mod_branch.BranchFormat.find_format(a_bzrdir)
433 assert format.__class__ == self.__class__
434 if name is not None:
435- raise bzrlib.errors.NoColocatedBranchSupport(self)
436+ raise errors.NoColocatedBranchSupport(self)
437 transport = a_bzrdir.get_branch_transport(None)
438- control_files = bzrlib.lockable_files.LockableFiles(
439- transport, 'lock', bzrlib.lockdir.LockDir)
440+ control_files = lockable_files.LockableFiles(
441+ transport, 'lock', lockdir.LockDir)
442 return self._branch_class(_format=self,
443 _control_files=control_files,
444 a_bzrdir=a_bzrdir,
445@@ -815,7 +826,7 @@
446
447
448
449-class BzrBranchLoomFormat1(LoomFormatMixin, bzrlib.branch.BzrBranchFormat5):
450+class BzrBranchLoomFormat1(LoomFormatMixin, _mod_branch.BzrBranchFormat5):
451 """Loom's first format.
452
453 This format is an extension to BzrBranchFormat5 with the following changes:
454@@ -828,7 +839,7 @@
455 """
456
457 _branch_class = LoomBranch
458- _parent_classs = bzrlib.branch.BzrBranchFormat5
459+ _parent_classs = _mod_branch.BzrBranchFormat5
460
461 def get_format_string(self):
462 """See BranchFormat.get_format_string()."""
463@@ -842,7 +853,7 @@
464 return "Bazaar-NG Loom format 1"
465
466
467-class BzrBranchLoomFormat6(LoomFormatMixin, bzrlib.branch.BzrBranchFormat6):
468+class BzrBranchLoomFormat6(LoomFormatMixin, _mod_branch.BzrBranchFormat6):
469 """Loom's second edition - based on bzr's Branch6.
470
471 This format is an extension to BzrBranchFormat6 with the following changes:
472@@ -855,7 +866,7 @@
473 """
474
475 _branch_class = LoomBranch6
476- _parent_classs = bzrlib.branch.BzrBranchFormat6
477+ _parent_classs = _mod_branch.BzrBranchFormat6
478
479 def get_format_string(self):
480 """See BranchFormat.get_format_string()."""
481@@ -869,7 +880,7 @@
482 return "bzr loom format 6 (based on bzr branch format 6)\n"
483
484
485-class BzrBranchLoomFormat7(LoomFormatMixin, bzrlib.branch.BzrBranchFormat7):
486+class BzrBranchLoomFormat7(LoomFormatMixin, _mod_branch.BzrBranchFormat7):
487 """Loom's second edition - based on bzr's Branch7.
488
489 This format is an extension to BzrBranchFormat7 with the following changes:
490@@ -882,7 +893,7 @@
491 """
492
493 _branch_class = LoomBranch7
494- _parent_classs = bzrlib.branch.BzrBranchFormat7
495+ _parent_classs = _mod_branch.BzrBranchFormat7
496
497 def get_format_string(self):
498 """See BranchFormat.get_format_string()."""
499@@ -896,136 +907,4 @@
500 return "bzr loom format 7 (based on bzr branch format 7)\n"
501
502
503-# Handle the smart server:
504-
505-class InterLoomBranch(bzrlib.branch.GenericInterBranch):
506-
507- @classmethod
508- def _get_branch_formats_to_test(klass):
509- return [
510- (bzrlib.branch.BranchFormat._default_format,
511- BzrBranchLoomFormat7()),
512- (BzrBranchLoomFormat7(),
513- bzrlib.branch.BranchFormat._default_format),
514- (BzrBranchLoomFormat7(), BzrBranchLoomFormat7()),
515- ]
516-
517- def unwrap_branch(self, branch):
518- if isinstance(branch, remote.RemoteBranch):
519- branch._ensure_real()
520- return branch._real_branch
521- return branch
522-
523- @classmethod
524- def is_compatible(klass, source, target):
525- # 1st cut: special case and handle all *->Loom and Loom->*
526- return klass.branch_is_loom(source) or klass.branch_is_loom(target)
527-
528- def get_loom_state(self, branch):
529- branch = self.unwrap_branch(branch)
530- return branch.get_loom_state()
531-
532- def get_threads(self, branch, revision_id):
533- branch = self.unwrap_branch(branch)
534- return branch.get_threads(revision_id)
535-
536- @classmethod
537- def branch_is_loom(klass, branch):
538- format = klass.unwrap_format(branch._format)
539- return isinstance(format, LoomFormatMixin)
540-
541- @needs_write_lock
542- def copy_content_into(self, revision_id=None):
543- if not self.__class__.branch_is_loom(self.source):
544- # target is loom, but the generic code path works Just Fine for
545- # regular to loom copy_content_into.
546- return super(InterLoomBranch, self).copy_content_into(
547- revision_id=revision_id)
548- # XXX: hint for bzrlib - break this into two routines, one for
549- # copying the last-rev pointer, one for copying parent etc.
550- source_nick = self.source.nick
551- state = self.get_loom_state(self.source)
552- parents = state.get_parents()
553- if parents:
554- loom_tip = parents[0]
555- else:
556- loom_tip = None
557- threads = self.get_threads(self.source, state.get_basis_revision_id())
558- if revision_id not in (None, NULL_REVISION):
559- if threads:
560- # revision_id should be in the loom, or its an error
561- found_threads = [thread for thread, rev in threads
562- if rev == revision_id]
563- if not found_threads:
564- # the thread we have been asked to set in the remote
565- # side has not been recorded yet, so its data is not
566- # present at this point.
567- raise UnrecordedRevision(self.source, revision_id)
568-
569- # pull in the warp, which was skipped during the initial pull
570- # because the front end does not know what to pull.
571- # nb: this is mega huge hacky. THINK. RBC 2006062
572- nested = bzrlib.ui.ui_factory.nested_progress_bar()
573- try:
574- if parents:
575- self.target.repository.fetch(self.source.repository,
576- revision_id=parents[0])
577- if threads:
578- for thread, rev_id in reversed(threads):
579- # fetch the loom content for this revision
580- self.target.repository.fetch(self.source.repository,
581- revision_id=rev_id)
582- finally:
583- nested.finished()
584- state = loom_state.LoomState()
585- try:
586- require_loom_branch(self.target)
587- if threads:
588- last_rev = threads[-1][1]
589- if last_rev == EMPTY_REVISION:
590- last_rev = bzrlib.revision.NULL_REVISION
591- self.target.generate_revision_history(last_rev)
592- state.set_parents([loom_tip])
593- state.set_threads(
594- (thread + ([thread[1]],) for thread in threads)
595- )
596- else:
597- # no threads yet, be a normal branch.
598- self.source._synchronize_history(self.target, revision_id)
599- target_loom = self.unwrap_branch(self.target)
600- target_loom._set_last_loom(state)
601- except NotALoom:
602- self.source._synchronize_history(self.target, revision_id)
603- try:
604- parent = self.source.get_parent()
605- except bzrlib.errors.InaccessibleParent, e:
606- bzrlib.trace.mutter('parent was not accessible to copy: %s', e)
607- else:
608- if parent:
609- self.target.set_parent(parent)
610- if threads:
611- self.target._set_nick(threads[-1][0])
612-
613- @needs_write_lock
614- def pull(self, overwrite=False, stop_revision=None,
615- run_hooks=True, possible_transports=None, _override_hook_target=None,
616- local=False):
617- """Perform a pull, reading from self.source and writing to self.target.
618-
619- If the source branch is a non-loom branch, the pull is done against the
620- current warp. If it is a loom branch, then the pull is done against the
621- entire loom and the current thread set to the top thread.
622- """
623- # Special code only needed when both source and targets are looms:
624- if (self.__class__.branch_is_loom(self.target) and
625- self.__class__.branch_is_loom(self.source)):
626- return _Puller(self.source, self.target).transfer(overwrite, stop_revision,
627- run_hooks, possible_transports, _override_hook_target, local)
628- return super(InterLoomBranch, self).pull(
629- overwrite=overwrite, stop_revision=stop_revision,
630- possible_transports=possible_transports,
631- _override_hook_target=_override_hook_target, local=local,
632- run_hooks=run_hooks)
633-
634-
635-bzrlib.branch.InterBranch.register_optimiser(InterLoomBranch)
636+
637
638=== modified file 'formats.py'
639--- formats.py 2010-06-18 04:44:52 +0000
640+++ formats.py 2010-08-13 07:13:40 +0000
641@@ -27,12 +27,21 @@
642 'require_loom_branch',
643 ]
644
645+from bzrlib import errors
646+
647 from bzrlib.lazy_import import lazy_import
648-import bzrlib.errors
649-
650 lazy_import(globals(), """
651+from bzrlib import (
652+ remote,
653+ revision as _mod_revision,
654+ trace,
655+ ui,
656+ )
657+import branch as _loom_branch
658+import loom_state
659+""")
660 from bzrlib import branch as _mod_branch
661-""")
662+from bzrlib.decorators import needs_write_lock
663
664
665 _LOOM_FORMATS = {
666@@ -44,15 +53,14 @@
667 def register_formats():
668 if getattr(_mod_branch, 'MetaDirBranchFormatFactory', None):
669 branch_formats = [_mod_branch.MetaDirBranchFormatFactory(format_string,
670- "bzrlib.plugins.loom.branch", format_class) for
671+ "bzrlib.plugins.loom.branch", format_class) for
672 (format_string, format_class) in _LOOM_FORMATS.iteritems()]
673 else:
674 # Compat for folk not running bleeding edge. Like me as I commit this.
675- import branch
676 branch_formats = [
677- branch.BzrBranchLoomFormat1(),
678- branch.BzrBranchLoomFormat6(),
679- branch.BzrBranchLoomFormat7(),
680+ _loom_branch.BzrBranchLoomFormat1(),
681+ _loom_branch.BzrBranchLoomFormat6(),
682+ _loom_branch.BzrBranchLoomFormat7(),
683 ]
684 map(_mod_branch.BranchFormat.register_format, branch_formats)
685
686@@ -64,11 +72,148 @@
687
688
689 # TODO: define errors without importing all errors.
690-class NotALoom(bzrlib.errors.BzrError):
691+class NotALoom(errors.BzrError):
692
693 _fmt = ("The branch %(branch)s is not a loom. "
694 "You can use 'bzr loomify' to make it into a loom.")
695
696 def __init__(self, branch):
697- bzrlib.errors.BzrError.__init__(self)
698+ errors.BzrError.__init__(self)
699 self.branch = branch
700+
701+
702+class InterLoomBranch(_mod_branch.GenericInterBranch):
703+ """Handle the smart server."""
704+
705+ @classmethod
706+ def _get_branch_formats_to_test(klass):
707+ return [
708+ (_mod_branch.BranchFormat._default_format,
709+ _loom_branch.BzrBranchLoomFormat7()),
710+ (_loom_branch.BzrBranchLoomFormat7(),
711+ _mod_branch.BranchFormat._default_format),
712+ (_loom_branch.BzrBranchLoomFormat7(),
713+ _loom_branch.BzrBranchLoomFormat7()),
714+ ]
715+
716+ def unwrap_branch(self, branch):
717+ if isinstance(branch, remote.RemoteBranch):
718+ branch._ensure_real()
719+ return branch._real_branch
720+ return branch
721+
722+ @classmethod
723+ def is_compatible(klass, source, target):
724+ # 1st cut: special case and handle all *->Loom and Loom->*
725+ return klass.branch_is_loom(source) or klass.branch_is_loom(target)
726+
727+ def get_loom_state(self, branch):
728+ branch = self.unwrap_branch(branch)
729+ return branch.get_loom_state()
730+
731+ def get_threads(self, branch, revision_id):
732+ branch = self.unwrap_branch(branch)
733+ return branch.get_threads(revision_id)
734+
735+ @classmethod
736+ def branch_is_loom(klass, branch):
737+ format = klass.unwrap_format(branch._format)
738+ return isinstance(format, _loom_branch.LoomFormatMixin)
739+
740+ @needs_write_lock
741+ def copy_content_into(self, revision_id=None):
742+ if not self.__class__.branch_is_loom(self.source):
743+ # target is loom, but the generic code path works Just Fine for
744+ # regular to loom copy_content_into.
745+ return super(InterLoomBranch, self).copy_content_into(
746+ revision_id=revision_id)
747+ # XXX: hint for bzrlib - break this into two routines, one for
748+ # copying the last-rev pointer, one for copying parent etc.
749+ source_nick = self.source.nick
750+ state = self.get_loom_state(self.source)
751+ parents = state.get_parents()
752+ if parents:
753+ loom_tip = parents[0]
754+ else:
755+ loom_tip = None
756+ threads = self.get_threads(self.source, state.get_basis_revision_id())
757+ if revision_id not in (None, _mod_revision.NULL_REVISION):
758+ if threads:
759+ # revision_id should be in the loom, or its an error
760+ found_threads = [thread for thread, rev in threads
761+ if rev == revision_id]
762+ if not found_threads:
763+ # the thread we have been asked to set in the remote
764+ # side has not been recorded yet, so its data is not
765+ # present at this point.
766+ raise _loom_branch.UnrecordedRevision(
767+ self.source, revision_id)
768+
769+ # pull in the warp, which was skipped during the initial pull
770+ # because the front end does not know what to pull.
771+ # nb: this is mega huge hacky. THINK. RBC 2006062
772+ nested = ui.ui_factory.nested_progress_bar()
773+ try:
774+ if parents:
775+ self.target.repository.fetch(self.source.repository,
776+ revision_id=parents[0])
777+ if threads:
778+ for thread, rev_id in reversed(threads):
779+ # fetch the loom content for this revision
780+ self.target.repository.fetch(self.source.repository,
781+ revision_id=rev_id)
782+ finally:
783+ nested.finished()
784+ state = loom_state.LoomState()
785+ try:
786+ require_loom_branch(self.target)
787+ if threads:
788+ last_rev = threads[-1][1]
789+ if last_rev == _loom_branch.EMPTY_REVISION:
790+ last_rev = _mod_revision.NULL_REVISION
791+ self.target.generate_revision_history(last_rev)
792+ state.set_parents([loom_tip])
793+ state.set_threads(
794+ (thread + ([thread[1]],) for thread in threads)
795+ )
796+ else:
797+ # no threads yet, be a normal branch.
798+ self.source._synchronize_history(self.target, revision_id)
799+ target_loom = self.unwrap_branch(self.target)
800+ target_loom._set_last_loom(state)
801+ except NotALoom:
802+ self.source._synchronize_history(self.target, revision_id)
803+ try:
804+ parent = self.source.get_parent()
805+ except errors.InaccessibleParent, e:
806+ trace.mutter('parent was not accessible to copy: %s', e)
807+ else:
808+ if parent:
809+ self.target.set_parent(parent)
810+ if threads:
811+ self.target._set_nick(threads[-1][0])
812+
813+ @needs_write_lock
814+ def pull(self, overwrite=False, stop_revision=None,
815+ run_hooks=True, possible_transports=None, _override_hook_target=None,
816+ local=False):
817+ """Perform a pull, reading from self.source and writing to self.target.
818+
819+ If the source branch is a non-loom branch, the pull is done against the
820+ current warp. If it is a loom branch, then the pull is done against the
821+ entire loom and the current thread set to the top thread.
822+ """
823+ # Special code only needed when both source and targets are looms:
824+ if (self.__class__.branch_is_loom(self.target) and
825+ self.__class__.branch_is_loom(self.source)):
826+ puller = _loom_branch._Puller(self.source, self.target)
827+ return puller.transfer(overwrite, stop_revision,
828+ run_hooks, possible_transports, _override_hook_target, local)
829+ return super(InterLoomBranch, self).pull(
830+ overwrite=overwrite, stop_revision=stop_revision,
831+ possible_transports=possible_transports,
832+ _override_hook_target=_override_hook_target, local=local,
833+ run_hooks=run_hooks)
834+
835+
836+_mod_branch.InterBranch.register_optimiser(InterLoomBranch)

Subscribers

People subscribed via source and target branches