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
=== modified file 'branch.py'
--- branch.py 2010-07-16 08:30:13 +0000
+++ branch.py 2010-08-13 07:13:40 +0000
@@ -26,17 +26,29 @@
2626
27from StringIO import StringIO27from StringIO import StringIO
2828
29import bzrlib.branch29from bzrlib.lazy_import import lazy_import
30from bzrlib import bzrdir30lazy_import(globals(), """
31from bzrlib import (
32 bzrdir,
33 inventory,
34 lockable_files,
35 lockdir,
36 remote,
37 revision as _mod_revision,
38 symbol_versioning,
39 trace,
40 ui,
41 urlutils,
42 )
43""")
44from bzrlib import (
45 branch as _mod_branch,
46 errors,
47 tree as _mod_tree,
48 )
49
50
31from bzrlib.decorators import needs_read_lock, needs_write_lock51from bzrlib.decorators import needs_read_lock, needs_write_lock
32import bzrlib.errors
33import bzrlib.osutils
34from bzrlib import remote, symbol_versioning
35import bzrlib.trace
36import bzrlib.ui
37from bzrlib.revision import is_null, NULL_REVISION
38import bzrlib.tree
39import bzrlib.urlutils
4052
41import formats53import formats
42import loom_io54import loom_io
@@ -57,12 +69,12 @@
57 loom.unlock()69 loom.unlock()
5870
5971
60class AlreadyLoom(bzrlib.errors.BzrError):72class AlreadyLoom(errors.BzrError):
6173
62 _fmt = """Loom %(loom)s is already a loom."""74 _fmt = """Loom %(loom)s is already a loom."""
6375
64 def __init__(self, loom):76 def __init__(self, loom):
65 bzrlib.errors.BzrError.__init__(self)77 errors.BzrError.__init__(self)
66 self.loom = loom78 self.loom = loom
6779
6880
@@ -81,9 +93,9 @@
81 raise AlreadyLoom(branch)93 raise AlreadyLoom(branch)
82 try:94 try:
83 format = {95 format = {
84 bzrlib.branch.BzrBranchFormat5: BzrBranchLoomFormat1,96 _mod_branch.BzrBranchFormat5: BzrBranchLoomFormat1,
85 bzrlib.branch.BzrBranchFormat6: BzrBranchLoomFormat6,97 _mod_branch.BzrBranchFormat6: BzrBranchLoomFormat6,
86 bzrlib.branch.BzrBranchFormat7: BzrBranchLoomFormat7,98 _mod_branch.BzrBranchFormat7: BzrBranchLoomFormat7,
87 }[branch._format.__class__]()99 }[branch._format.__class__]()
88 except KeyError:100 except KeyError:
89 raise UnsupportedBranchFormat(branch._format)101 raise UnsupportedBranchFormat(branch._format)
@@ -96,26 +108,26 @@
96NotALoom = formats.NotALoom108NotALoom = formats.NotALoom
97109
98110
99class LoomThreadError(bzrlib.errors.BzrError):111class LoomThreadError(errors.BzrError):
100 """Base class for Loom-Thread errors."""112 """Base class for Loom-Thread errors."""
101113
102 def __init__(self, branch, thread):114 def __init__(self, branch, thread):
103 bzrlib.errors.BzrError.__init__(self)115 errors.BzrError.__init__(self)
104 self.branch = branch116 self.branch = branch
105 self.thread = thread117 self.thread = thread
106118
107119
108class UnrecordedRevision(bzrlib.errors.BzrError):120class UnrecordedRevision(errors.BzrError):
109121
110 _fmt = """The revision %(revision_id)s is not recorded in the loom %(branch)s."""122 _fmt = """The revision %(revision_id)s is not recorded in the loom %(branch)s."""
111123
112 def __init__(self, branch, revision_id):124 def __init__(self, branch, revision_id):
113 bzrlib.errors.BzrError.__init__(self)125 errors.BzrError.__init__(self)
114 self.branch = branch126 self.branch = branch
115 self.revision_id = revision_id127 self.revision_id = revision_id
116128
117129
118class UnsupportedBranchFormat(bzrlib.errors.BzrError):130class UnsupportedBranchFormat(errors.BzrError):
119131
120 _fmt = """The branch format %(format)s is not supported by loomify."""132 _fmt = """The branch format %(format)s is not supported by loomify."""
121133
@@ -138,7 +150,7 @@
138 _fmt = """No such thread '%(thread)s'."""150 _fmt = """No such thread '%(thread)s'."""
139151
140152
141class NoLowerThread(bzrlib.errors.BzrError):153class NoLowerThread(errors.BzrError):
142154
143 _fmt = """No lower thread exists."""155 _fmt = """No lower thread exists."""
144156
@@ -148,7 +160,7 @@
148 _fmt = """Cannot combine threads on the bottom thread."""160 _fmt = """Cannot combine threads on the bottom thread."""
149161
150162
151class LoomMetaTree(bzrlib.tree.Tree):163class LoomMetaTree(_mod_tree.Tree):
152 """A 'tree' object that is used to commit the loom meta branch."""164 """A 'tree' object that is used to commit the loom meta branch."""
153165
154 def __init__(self, loom_meta_ie, loom_stream, loom_sha1):166 def __init__(self, loom_meta_ie, loom_stream, loom_sha1):
@@ -156,7 +168,7 @@
156168
157 :param loom_content_lines: the unicode content to be used for the loom.169 :param loom_content_lines: the unicode content to be used for the loom.
158 """170 """
159 self._inventory = bzrlib.inventory.Inventory()171 self._inventory = inventory.Inventory()
160 self.inventory.add(loom_meta_ie)172 self.inventory.add(loom_meta_ie)
161 self._loom_stream = loom_stream173 self._loom_stream = loom_stream
162 self._loom_sha1 = loom_sha1174 self._loom_sha1 = loom_sha1
@@ -203,7 +215,7 @@
203 # all threads gone215 # all threads gone
204 # revert to being a normal branch: revert to an empty revision216 # revert to being a normal branch: revert to an empty revision
205 # history.217 # history.
206 self.generate_revision_history(bzrlib.revision.NULL_REVISION)218 self.generate_revision_history(_mod_revision.NULL_REVISION)
207 return219 return
208 # TODO, calculate the offset of removed threads.220 # TODO, calculate the offset of removed threads.
209 # i.e. if there are ten threads removed, and current_index is 5, 221 # i.e. if there are ten threads removed, and current_index is 5,
@@ -215,19 +227,19 @@
215 self._set_nick(threads[-1][0])227 self._set_nick(threads[-1][0])
216 new_rev = threads[-1][1]228 new_rev = threads[-1][1]
217 if new_rev == EMPTY_REVISION:229 if new_rev == EMPTY_REVISION:
218 new_rev = bzrlib.revision.NULL_REVISION230 new_rev = _mod_revision.NULL_REVISION
219 self.generate_revision_history(new_rev)231 self.generate_revision_history(new_rev)
220 return232 return
221 # non-end thread removed.233 # non-end thread removed.
222 self._set_nick(threads[current_index][0])234 self._set_nick(threads[current_index][0])
223 new_rev = threads[current_index][1]235 new_rev = threads[current_index][1]
224 if new_rev == EMPTY_REVISION:236 if new_rev == EMPTY_REVISION:
225 new_rev = bzrlib.revision.NULL_REVISION237 new_rev = _mod_revision.NULL_REVISION
226 self.generate_revision_history(new_rev)238 self.generate_revision_history(new_rev)
227 elif self.last_revision() != threads_dict[self.nick]:239 elif self.last_revision() != threads_dict[self.nick]:
228 new_rev = threads_dict[self.nick]240 new_rev = threads_dict[self.nick]
229 if new_rev == EMPTY_REVISION:241 if new_rev == EMPTY_REVISION:
230 new_rev = bzrlib.revision.NULL_REVISION242 new_rev = _mod_revision.NULL_REVISION
231 self.generate_revision_history(new_rev)243 self.generate_revision_history(new_rev)
232244
233 def bind(self, other):245 def bind(self, other):
@@ -237,7 +249,7 @@
237 :type other: Branch249 :type other: Branch
238 """250 """
239 # Looms are not currently bindable.251 # Looms are not currently bindable.
240 raise bzrlib.errors.UpgradeRequired(self.base)252 raise errors.UpgradeRequired(self.base)
241253
242 @needs_read_lock254 @needs_read_lock
243 def clone(self, to_bzrdir, revision_id=None, repository_policy=None):255 def clone(self, to_bzrdir, revision_id=None, repository_policy=None):
@@ -258,7 +270,7 @@
258 result = format.initialize(to_bzrdir)270 result = format.initialize(to_bzrdir)
259 if repository_policy is not None:271 if repository_policy is not None:
260 repository_policy.configure_branch(result)272 repository_policy.configure_branch(result)
261 bzrlib.branch.InterBranch.get(self, result).copy_content_into(273 _mod_branch.InterBranch.get(self, result).copy_content_into(
262 revision_id=revision_id)274 revision_id=revision_id)
263 return result275 return result
264276
@@ -268,7 +280,7 @@
268 This is a short term measure to get to an all-tests passing status.280 This is a short term measure to get to an all-tests passing status.
269 """281 """
270 format = self.repository.bzrdir.checkout_metadir()282 format = self.repository.bzrdir.checkout_metadir()
271 format.set_branch_format(bzrlib.branch.BzrBranchFormat6())283 format.set_branch_format(_mod_branch.BzrBranchFormat6())
272 return format284 return format
273285
274 def get_loom_state(self):286 def get_loom_state(self):
@@ -282,7 +294,7 @@
282 def get_old_bound_location(self):294 def get_old_bound_location(self):
283 """Return the URL of the branch we used to be bound to."""295 """Return the URL of the branch we used to be bound to."""
284 # No binding for looms yet.296 # No binding for looms yet.
285 raise bzrlib.errors.UpgradeRequired(self.base)297 raise errors.UpgradeRequired(self.base)
286298
287 def get_threads(self, rev_id):299 def get_threads(self, rev_id):
288 """Return the threads from a loom revision.300 """Return the threads from a loom revision.
@@ -294,7 +306,7 @@
294 symbol_versioning.warn('NULL_REVISION should be used for the null'306 symbol_versioning.warn('NULL_REVISION should be used for the null'
295 ' revision instead of None, as of bzr 0.90.',307 ' revision instead of None, as of bzr 0.90.',
296 DeprecationWarning, stacklevel=2)308 DeprecationWarning, stacklevel=2)
297 if is_null(rev_id):309 if _mod_revision.is_null(rev_id):
298 return []310 return []
299 content = self._loom_content(rev_id)311 content = self._loom_content(rev_id)
300 return self._parse_loom(content)312 return self._parse_loom(content)
@@ -308,14 +320,14 @@
308 threads = self.get_loom_state().get_threads()320 threads = self.get_loom_state().get_threads()
309 for thread_name, thread_revision, _parents in threads:321 for thread_name, thread_revision, _parents in threads:
310 thread_transport = root_transport.clone(thread_name)322 thread_transport = root_transport.clone(thread_name)
311 user_location = bzrlib.urlutils.unescape_for_display(323 user_location = urlutils.unescape_for_display(
312 thread_transport.base, 'utf-8')324 thread_transport.base, 'utf-8')
313 try:325 try:
314 control_dir = bzrdir.BzrDir.open(thread_transport.base,326 control_dir = bzrdir.BzrDir.open(thread_transport.base,
315 possible_transports=[thread_transport])327 possible_transports=[thread_transport])
316 tree, branch = control_dir._get_tree_branch()328 tree, branch = control_dir._get_tree_branch()
317 except bzrlib.errors.NotBranchError:329 except errors.NotBranchError:
318 bzrlib.trace.note('Creating branch at %s' % user_location)330 trace.note('Creating branch at %s' % user_location)
319 branch = bzrdir.BzrDir.create_branch_convenience(331 branch = bzrdir.BzrDir.create_branch_convenience(
320 thread_transport.base,332 thread_transport.base,
321 possible_transports=[thread_transport])333 possible_transports=[thread_transport])
@@ -323,11 +335,11 @@
323 thread_transport.base)335 thread_transport.base)
324 else:336 else:
325 if thread_revision == branch.last_revision():337 if thread_revision == branch.last_revision():
326 bzrlib.trace.note('Skipping up-to-date branch at %s'338 trace.note('Skipping up-to-date branch at %s'
327 % user_location)339 % user_location)
328 continue340 continue
329 else:341 else:
330 bzrlib.trace.note('Updating branch at %s' % user_location)342 trace.note('Updating branch at %s' % user_location)
331 if tree is not None:343 if tree is not None:
332 tree.pull(self, stop_revision=thread_revision)344 tree.pull(self, stop_revision=thread_revision)
333 else:345 else:
@@ -369,7 +381,7 @@
369 revision_for_thread = self.last_revision()381 revision_for_thread = self.last_revision()
370 else:382 else:
371 revision_for_thread = threads[insertion_point - 1][1]383 revision_for_thread = threads[insertion_point - 1][1]
372 if is_null(revision_for_thread):384 if _mod_revision.is_null(revision_for_thread):
373 revision_for_thread = EMPTY_REVISION385 revision_for_thread = EMPTY_REVISION
374 threads.insert(386 threads.insert(
375 insertion_point,387 insertion_point,
@@ -432,10 +444,10 @@
432 threads = state.get_threads()444 threads = state.get_threads()
433 # check the semantic value, not the serialised value for equality.445 # check the semantic value, not the serialised value for equality.
434 if old_threads == threads:446 if old_threads == threads:
435 raise bzrlib.errors.PointlessCommit447 raise errors.PointlessCommit
436 builder = self.get_commit_builder(parents)448 builder = self.get_commit_builder(parents)
437 loom_ie = bzrlib.inventory.make_entry(449 loom_ie = inventory.make_entry(
438 'file', 'loom', bzrlib.inventory.ROOT_ID, 'loom_meta_tree')450 'file', 'loom', inventory.ROOT_ID, 'loom_meta_tree')
439 writer = loom_io.LoomWriter()451 writer = loom_io.LoomWriter()
440 loom_stream = StringIO()452 loom_stream = StringIO()
441 new_threads = [thread[0:2] for thread in threads]453 new_threads = [thread[0:2] for thread in threads]
@@ -443,8 +455,8 @@
443 loom_stream.seek(0)455 loom_stream.seek(0)
444 loom_tree = LoomMetaTree(loom_ie, loom_stream, loom_sha1)456 loom_tree = LoomMetaTree(loom_ie, loom_stream, loom_sha1)
445 if getattr(builder, 'record_root_entry', False):457 if getattr(builder, 'record_root_entry', False):
446 root_ie = bzrlib.inventory.make_entry(458 root_ie = inventory.make_entry(
447 'directory', '', None, bzrlib.inventory.ROOT_ID)459 'directory', '', None, inventory.ROOT_ID)
448 builder.record_entry_contents(root_ie, [], '', loom_tree,460 builder.record_entry_contents(root_ie, [], '', loom_tree,
449 ('directory', None, None, None))461 ('directory', None, None, None))
450 builder.record_entry_contents(462 builder.record_entry_contents(
@@ -469,7 +481,7 @@
469 state = self.get_loom_state()481 state = self.get_loom_state()
470 threads = state.get_threads()482 threads = state.get_threads()
471 assert thread_name in state.get_threads_dict()483 assert thread_name in state.get_threads_dict()
472 if is_null(revision_id):484 if _mod_revision.is_null(revision_id):
473 revision_id = EMPTY_REVISION485 revision_id = EMPTY_REVISION
474 for position, (name, rev, parents) in enumerate(threads):486 for position, (name, rev, parents) in enumerate(threads):
475 if name == thread_name:487 if name == thread_name:
@@ -555,7 +567,7 @@
555 if len(threads):567 if len(threads):
556 # looms are enabled:568 # looms are enabled:
557 lastrev = self.last_revision()569 lastrev = self.last_revision()
558 if is_null(lastrev):570 if _mod_revision.is_null(lastrev):
559 lastrev = EMPTY_REVISION571 lastrev = EMPTY_REVISION
560 if dict(state.get_threads_dict())[self.nick][0] != lastrev:572 if dict(state.get_threads_dict())[self.nick][0] != lastrev:
561 self.record_thread(self.nick, lastrev)573 self.record_thread(self.nick, lastrev)
@@ -604,11 +616,11 @@
604616
605 @staticmethod617 @staticmethod
606 def make_result():618 def make_result():
607 return bzrlib.branch.PullResult()619 return _mod_branch.PullResult()
608620
609 @staticmethod621 @staticmethod
610 def post_hooks():622 def post_hooks():
611 return bzrlib.branch.Branch.hooks['post_pull']623 return _mod_branch.Branch.hooks['post_pull']
612624
613 def plain_transfer(self, result, run_hooks, stop_revision, overwrite):625 def plain_transfer(self, result, run_hooks, stop_revision, overwrite):
614 # no thread commits ever626 # no thread commits ever
@@ -617,7 +629,7 @@
617 if new_rev is None:629 if new_rev is None:
618 new_rev = self.source.last_revision()630 new_rev = self.source.last_revision()
619 if new_rev == EMPTY_REVISION:631 if new_rev == EMPTY_REVISION:
620 new_rev = bzrlib.revision.NULL_REVISION632 new_rev = _mod_revision.NULL_REVISION
621 self.target.repository.fetch(self.source.repository,633 self.target.repository.fetch(self.source.repository,
622 revision_id=new_rev)634 revision_id=new_rev)
623 if not overwrite:635 if not overwrite:
@@ -625,11 +637,10 @@
625 new_rev)637 new_rev)
626 last_rev = self.target.last_revision()638 last_rev = self.target.last_revision()
627 # get_ancestry returns None for NULL_REVISION currently.639 # get_ancestry returns None for NULL_REVISION currently.
628 if last_rev == NULL_REVISION:640 if last_rev == _mod_revision.NULL_REVISION:
629 last_rev = None641 last_rev = None
630 if last_rev not in new_rev_ancestry:642 if last_rev not in new_rev_ancestry:
631 raise bzrlib.errors.DivergedBranches(643 raise errors.DivergedBranches(self.target, self.source)
632 self.target, self.source)
633 self.target.generate_revision_history(new_rev)644 self.target.generate_revision_history(new_rev)
634 # get the final result object details645 # get the final result object details
635 self.do_hooks(result, run_hooks)646 self.do_hooks(result, run_hooks)
@@ -639,9 +650,9 @@
639 possible_transports=None, _override_hook_target=None, local=False):650 possible_transports=None, _override_hook_target=None, local=False):
640 """Implementation of push and pull"""651 """Implementation of push and pull"""
641 if local:652 if local:
642 raise bzrlib.errors.LocalRequiresBoundBranch()653 raise errors.LocalRequiresBoundBranch()
643 # pull the loom, and position our654 # pull the loom, and position our
644 pb = bzrlib.ui.ui_factory.nested_progress_bar()655 pb = ui.ui_factory.nested_progress_bar()
645 try:656 try:
646 result = self.prepare_result(_override_hook_target)657 result = self.prepare_result(_override_hook_target)
647 self.target.lock_write()658 self.target.lock_write()
@@ -662,7 +673,7 @@
662 source_ancestry = self.source.repository.get_ancestry(673 source_ancestry = self.source.repository.get_ancestry(
663 source_loom_rev)674 source_loom_rev)
664 if my_state.get_parents()[0] not in source_ancestry:675 if my_state.get_parents()[0] not in source_ancestry:
665 raise bzrlib.errors.DivergedBranches(676 raise errors.DivergedBranches(
666 self.target, self.source)677 self.target, self.source)
667 # fetch the loom content678 # fetch the loom content
668 self.target.repository.fetch(self.source.repository,679 self.target.repository.fetch(self.source.repository,
@@ -679,7 +690,7 @@
679 # thread to include all content.690 # thread to include all content.
680 for rev_id in reversed(revisions):691 for rev_id in reversed(revisions):
681 if rev_id not in (EMPTY_REVISION,692 if rev_id not in (EMPTY_REVISION,
682 bzrlib.revision.NULL_REVISION):693 _mod_revision.NULL_REVISION):
683 # fetch the loom content for this revision694 # fetch the loom content for this revision
684 self.target.repository.fetch(self.source.repository,695 self.target.repository.fetch(self.source.repository,
685 revision_id=rev_id)696 revision_id=rev_id)
@@ -697,7 +708,7 @@
697 # and position the branch on the top loom708 # and position the branch on the top loom
698 new_rev = threads[-1][1]709 new_rev = threads[-1][1]
699 if new_rev == EMPTY_REVISION:710 if new_rev == EMPTY_REVISION:
700 new_rev = bzrlib.revision.NULL_REVISION711 new_rev = _mod_revision.NULL_REVISION
701 self.target.generate_revision_history(new_rev)712 self.target.generate_revision_history(new_rev)
702 self.do_hooks(result, run_hooks)713 self.do_hooks(result, run_hooks)
703 return result714 return result
@@ -712,14 +723,14 @@
712723
713 @staticmethod724 @staticmethod
714 def make_result():725 def make_result():
715 return bzrlib.branch.BranchPushResult()726 return _mod_branch.BranchPushResult()
716727
717 @staticmethod728 @staticmethod
718 def post_hooks():729 def post_hooks():
719 return bzrlib.branch.Branch.hooks['post_push']730 return _mod_branch.Branch.hooks['post_push']
720731
721732
722class LoomBranch(LoomSupport, bzrlib.branch.BzrBranch5):733class LoomBranch(LoomSupport, _mod_branch.BzrBranch5):
723 """The Loom branch.734 """The Loom branch.
724 735
725 A mixin is used as the easiest migration path to support branch6. A736 A mixin is used as the easiest migration path to support branch6. A
@@ -727,7 +738,7 @@
727 """738 """
728739
729740
730class LoomBranch6(LoomSupport, bzrlib.branch.BzrBranch6):741class LoomBranch6(LoomSupport, _mod_branch.BzrBranch6):
731 """Branch6 Loom branch.742 """Branch6 Loom branch.
732743
733 A mixin is used as the easiest migration path to support branch6. A744 A mixin is used as the easiest migration path to support branch6. A
@@ -735,7 +746,7 @@
735 """746 """
736747
737748
738class LoomBranch7(LoomSupport, bzrlib.branch.BzrBranch7):749class LoomBranch7(LoomSupport, _mod_branch.BzrBranch7):
739 """Branch6 Loom branch.750 """Branch6 Loom branch.
740751
741 A mixin is used as the easiest migration path to support branch7.752 A mixin is used as the easiest migration path to support branch7.
@@ -752,7 +763,7 @@
752 def initialize(self, a_bzrdir, name=None):763 def initialize(self, a_bzrdir, name=None):
753 """Create a branch of this format in a_bzrdir."""764 """Create a branch of this format in a_bzrdir."""
754 if name is not None:765 if name is not None:
755 raise bzrlib.errors.NoColocatedBranchSupport(self)766 raise errors.NoColocatedBranchSupport(self)
756 super(LoomFormatMixin, self).initialize(a_bzrdir, name=None)767 super(LoomFormatMixin, self).initialize(a_bzrdir, name=None)
757 branch_transport = a_bzrdir.get_branch_transport(self)768 branch_transport = a_bzrdir.get_branch_transport(self)
758 files = []769 files = []
@@ -762,8 +773,8 @@
762 writer.write(state_stream)773 writer.write(state_stream)
763 state_stream.seek(0)774 state_stream.seek(0)
764 files.append(('last-loom', state_stream))775 files.append(('last-loom', state_stream))
765 control_files = bzrlib.lockable_files.LockableFiles(776 control_files = lockable_files.LockableFiles(
766 branch_transport, 'lock', bzrlib.lockdir.LockDir)777 branch_transport, 'lock', lockdir.LockDir)
767 control_files.lock_write()778 control_files.lock_write()
768 try:779 try:
769 for name, stream in files:780 for name, stream in files:
@@ -783,13 +794,13 @@
783 it is unused.794 it is unused.
784 """795 """
785 if not _found:796 if not _found:
786 format = BranchFormat.find_format(a_bzrdir)797 format = _mod_branch.BranchFormat.find_format(a_bzrdir)
787 assert format.__class__ == self.__class__798 assert format.__class__ == self.__class__
788 if name is not None:799 if name is not None:
789 raise bzrlib.errors.NoColocatedBranchSupport(self)800 raise errors.NoColocatedBranchSupport(self)
790 transport = a_bzrdir.get_branch_transport(None)801 transport = a_bzrdir.get_branch_transport(None)
791 control_files = bzrlib.lockable_files.LockableFiles(802 control_files = lockable_files.LockableFiles(
792 transport, 'lock', bzrlib.lockdir.LockDir)803 transport, 'lock', lockdir.LockDir)
793 return self._branch_class(_format=self,804 return self._branch_class(_format=self,
794 _control_files=control_files,805 _control_files=control_files,
795 a_bzrdir=a_bzrdir,806 a_bzrdir=a_bzrdir,
@@ -815,7 +826,7 @@
815826
816827
817828
818class BzrBranchLoomFormat1(LoomFormatMixin, bzrlib.branch.BzrBranchFormat5):829class BzrBranchLoomFormat1(LoomFormatMixin, _mod_branch.BzrBranchFormat5):
819 """Loom's first format.830 """Loom's first format.
820831
821 This format is an extension to BzrBranchFormat5 with the following changes:832 This format is an extension to BzrBranchFormat5 with the following changes:
@@ -828,7 +839,7 @@
828 """839 """
829840
830 _branch_class = LoomBranch841 _branch_class = LoomBranch
831 _parent_classs = bzrlib.branch.BzrBranchFormat5842 _parent_classs = _mod_branch.BzrBranchFormat5
832843
833 def get_format_string(self):844 def get_format_string(self):
834 """See BranchFormat.get_format_string()."""845 """See BranchFormat.get_format_string()."""
@@ -842,7 +853,7 @@
842 return "Bazaar-NG Loom format 1"853 return "Bazaar-NG Loom format 1"
843854
844855
845class BzrBranchLoomFormat6(LoomFormatMixin, bzrlib.branch.BzrBranchFormat6):856class BzrBranchLoomFormat6(LoomFormatMixin, _mod_branch.BzrBranchFormat6):
846 """Loom's second edition - based on bzr's Branch6.857 """Loom's second edition - based on bzr's Branch6.
847858
848 This format is an extension to BzrBranchFormat6 with the following changes:859 This format is an extension to BzrBranchFormat6 with the following changes:
@@ -855,7 +866,7 @@
855 """866 """
856867
857 _branch_class = LoomBranch6868 _branch_class = LoomBranch6
858 _parent_classs = bzrlib.branch.BzrBranchFormat6869 _parent_classs = _mod_branch.BzrBranchFormat6
859870
860 def get_format_string(self):871 def get_format_string(self):
861 """See BranchFormat.get_format_string()."""872 """See BranchFormat.get_format_string()."""
@@ -869,7 +880,7 @@
869 return "bzr loom format 6 (based on bzr branch format 6)\n"880 return "bzr loom format 6 (based on bzr branch format 6)\n"
870881
871882
872class BzrBranchLoomFormat7(LoomFormatMixin, bzrlib.branch.BzrBranchFormat7):883class BzrBranchLoomFormat7(LoomFormatMixin, _mod_branch.BzrBranchFormat7):
873 """Loom's second edition - based on bzr's Branch7.884 """Loom's second edition - based on bzr's Branch7.
874885
875 This format is an extension to BzrBranchFormat7 with the following changes:886 This format is an extension to BzrBranchFormat7 with the following changes:
@@ -882,7 +893,7 @@
882 """893 """
883894
884 _branch_class = LoomBranch7895 _branch_class = LoomBranch7
885 _parent_classs = bzrlib.branch.BzrBranchFormat7896 _parent_classs = _mod_branch.BzrBranchFormat7
886897
887 def get_format_string(self):898 def get_format_string(self):
888 """See BranchFormat.get_format_string()."""899 """See BranchFormat.get_format_string()."""
@@ -896,136 +907,4 @@
896 return "bzr loom format 7 (based on bzr branch format 7)\n"907 return "bzr loom format 7 (based on bzr branch format 7)\n"
897908
898909
899# Handle the smart server:910
900
901class InterLoomBranch(bzrlib.branch.GenericInterBranch):
902
903 @classmethod
904 def _get_branch_formats_to_test(klass):
905 return [
906 (bzrlib.branch.BranchFormat._default_format,
907 BzrBranchLoomFormat7()),
908 (BzrBranchLoomFormat7(),
909 bzrlib.branch.BranchFormat._default_format),
910 (BzrBranchLoomFormat7(), BzrBranchLoomFormat7()),
911 ]
912
913 def unwrap_branch(self, branch):
914 if isinstance(branch, remote.RemoteBranch):
915 branch._ensure_real()
916 return branch._real_branch
917 return branch
918
919 @classmethod
920 def is_compatible(klass, source, target):
921 # 1st cut: special case and handle all *->Loom and Loom->*
922 return klass.branch_is_loom(source) or klass.branch_is_loom(target)
923
924 def get_loom_state(self, branch):
925 branch = self.unwrap_branch(branch)
926 return branch.get_loom_state()
927
928 def get_threads(self, branch, revision_id):
929 branch = self.unwrap_branch(branch)
930 return branch.get_threads(revision_id)
931
932 @classmethod
933 def branch_is_loom(klass, branch):
934 format = klass.unwrap_format(branch._format)
935 return isinstance(format, LoomFormatMixin)
936
937 @needs_write_lock
938 def copy_content_into(self, revision_id=None):
939 if not self.__class__.branch_is_loom(self.source):
940 # target is loom, but the generic code path works Just Fine for
941 # regular to loom copy_content_into.
942 return super(InterLoomBranch, self).copy_content_into(
943 revision_id=revision_id)
944 # XXX: hint for bzrlib - break this into two routines, one for
945 # copying the last-rev pointer, one for copying parent etc.
946 source_nick = self.source.nick
947 state = self.get_loom_state(self.source)
948 parents = state.get_parents()
949 if parents:
950 loom_tip = parents[0]
951 else:
952 loom_tip = None
953 threads = self.get_threads(self.source, state.get_basis_revision_id())
954 if revision_id not in (None, NULL_REVISION):
955 if threads:
956 # revision_id should be in the loom, or its an error
957 found_threads = [thread for thread, rev in threads
958 if rev == revision_id]
959 if not found_threads:
960 # the thread we have been asked to set in the remote
961 # side has not been recorded yet, so its data is not
962 # present at this point.
963 raise UnrecordedRevision(self.source, revision_id)
964
965 # pull in the warp, which was skipped during the initial pull
966 # because the front end does not know what to pull.
967 # nb: this is mega huge hacky. THINK. RBC 2006062
968 nested = bzrlib.ui.ui_factory.nested_progress_bar()
969 try:
970 if parents:
971 self.target.repository.fetch(self.source.repository,
972 revision_id=parents[0])
973 if threads:
974 for thread, rev_id in reversed(threads):
975 # fetch the loom content for this revision
976 self.target.repository.fetch(self.source.repository,
977 revision_id=rev_id)
978 finally:
979 nested.finished()
980 state = loom_state.LoomState()
981 try:
982 require_loom_branch(self.target)
983 if threads:
984 last_rev = threads[-1][1]
985 if last_rev == EMPTY_REVISION:
986 last_rev = bzrlib.revision.NULL_REVISION
987 self.target.generate_revision_history(last_rev)
988 state.set_parents([loom_tip])
989 state.set_threads(
990 (thread + ([thread[1]],) for thread in threads)
991 )
992 else:
993 # no threads yet, be a normal branch.
994 self.source._synchronize_history(self.target, revision_id)
995 target_loom = self.unwrap_branch(self.target)
996 target_loom._set_last_loom(state)
997 except NotALoom:
998 self.source._synchronize_history(self.target, revision_id)
999 try:
1000 parent = self.source.get_parent()
1001 except bzrlib.errors.InaccessibleParent, e:
1002 bzrlib.trace.mutter('parent was not accessible to copy: %s', e)
1003 else:
1004 if parent:
1005 self.target.set_parent(parent)
1006 if threads:
1007 self.target._set_nick(threads[-1][0])
1008
1009 @needs_write_lock
1010 def pull(self, overwrite=False, stop_revision=None,
1011 run_hooks=True, possible_transports=None, _override_hook_target=None,
1012 local=False):
1013 """Perform a pull, reading from self.source and writing to self.target.
1014
1015 If the source branch is a non-loom branch, the pull is done against the
1016 current warp. If it is a loom branch, then the pull is done against the
1017 entire loom and the current thread set to the top thread.
1018 """
1019 # Special code only needed when both source and targets are looms:
1020 if (self.__class__.branch_is_loom(self.target) and
1021 self.__class__.branch_is_loom(self.source)):
1022 return _Puller(self.source, self.target).transfer(overwrite, stop_revision,
1023 run_hooks, possible_transports, _override_hook_target, local)
1024 return super(InterLoomBranch, self).pull(
1025 overwrite=overwrite, stop_revision=stop_revision,
1026 possible_transports=possible_transports,
1027 _override_hook_target=_override_hook_target, local=local,
1028 run_hooks=run_hooks)
1029
1030
1031bzrlib.branch.InterBranch.register_optimiser(InterLoomBranch)
1032911
=== modified file 'formats.py'
--- formats.py 2010-06-18 04:44:52 +0000
+++ formats.py 2010-08-13 07:13:40 +0000
@@ -27,12 +27,21 @@
27 'require_loom_branch',27 'require_loom_branch',
28 ]28 ]
2929
30from bzrlib import errors
31
30from bzrlib.lazy_import import lazy_import32from bzrlib.lazy_import import lazy_import
31import bzrlib.errors
32
33lazy_import(globals(), """33lazy_import(globals(), """
34from bzrlib import (
35 remote,
36 revision as _mod_revision,
37 trace,
38 ui,
39 )
40import branch as _loom_branch
41import loom_state
42""")
34from bzrlib import branch as _mod_branch43from bzrlib import branch as _mod_branch
35""")44from bzrlib.decorators import needs_write_lock
3645
3746
38_LOOM_FORMATS = {47_LOOM_FORMATS = {
@@ -44,15 +53,14 @@
44def register_formats():53def register_formats():
45 if getattr(_mod_branch, 'MetaDirBranchFormatFactory', None):54 if getattr(_mod_branch, 'MetaDirBranchFormatFactory', None):
46 branch_formats = [_mod_branch.MetaDirBranchFormatFactory(format_string,55 branch_formats = [_mod_branch.MetaDirBranchFormatFactory(format_string,
47 "bzrlib.plugins.loom.branch", format_class) for 56 "bzrlib.plugins.loom.branch", format_class) for
48 (format_string, format_class) in _LOOM_FORMATS.iteritems()]57 (format_string, format_class) in _LOOM_FORMATS.iteritems()]
49 else:58 else:
50 # Compat for folk not running bleeding edge. Like me as I commit this.59 # Compat for folk not running bleeding edge. Like me as I commit this.
51 import branch
52 branch_formats = [60 branch_formats = [
53 branch.BzrBranchLoomFormat1(),61 _loom_branch.BzrBranchLoomFormat1(),
54 branch.BzrBranchLoomFormat6(),62 _loom_branch.BzrBranchLoomFormat6(),
55 branch.BzrBranchLoomFormat7(),63 _loom_branch.BzrBranchLoomFormat7(),
56 ]64 ]
57 map(_mod_branch.BranchFormat.register_format, branch_formats)65 map(_mod_branch.BranchFormat.register_format, branch_formats)
5866
@@ -64,11 +72,148 @@
6472
6573
66# TODO: define errors without importing all errors.74# TODO: define errors without importing all errors.
67class NotALoom(bzrlib.errors.BzrError):75class NotALoom(errors.BzrError):
6876
69 _fmt = ("The branch %(branch)s is not a loom. "77 _fmt = ("The branch %(branch)s is not a loom. "
70 "You can use 'bzr loomify' to make it into a loom.")78 "You can use 'bzr loomify' to make it into a loom.")
7179
72 def __init__(self, branch):80 def __init__(self, branch):
73 bzrlib.errors.BzrError.__init__(self)81 errors.BzrError.__init__(self)
74 self.branch = branch82 self.branch = branch
83
84
85class InterLoomBranch(_mod_branch.GenericInterBranch):
86 """Handle the smart server."""
87
88 @classmethod
89 def _get_branch_formats_to_test(klass):
90 return [
91 (_mod_branch.BranchFormat._default_format,
92 _loom_branch.BzrBranchLoomFormat7()),
93 (_loom_branch.BzrBranchLoomFormat7(),
94 _mod_branch.BranchFormat._default_format),
95 (_loom_branch.BzrBranchLoomFormat7(),
96 _loom_branch.BzrBranchLoomFormat7()),
97 ]
98
99 def unwrap_branch(self, branch):
100 if isinstance(branch, remote.RemoteBranch):
101 branch._ensure_real()
102 return branch._real_branch
103 return branch
104
105 @classmethod
106 def is_compatible(klass, source, target):
107 # 1st cut: special case and handle all *->Loom and Loom->*
108 return klass.branch_is_loom(source) or klass.branch_is_loom(target)
109
110 def get_loom_state(self, branch):
111 branch = self.unwrap_branch(branch)
112 return branch.get_loom_state()
113
114 def get_threads(self, branch, revision_id):
115 branch = self.unwrap_branch(branch)
116 return branch.get_threads(revision_id)
117
118 @classmethod
119 def branch_is_loom(klass, branch):
120 format = klass.unwrap_format(branch._format)
121 return isinstance(format, _loom_branch.LoomFormatMixin)
122
123 @needs_write_lock
124 def copy_content_into(self, revision_id=None):
125 if not self.__class__.branch_is_loom(self.source):
126 # target is loom, but the generic code path works Just Fine for
127 # regular to loom copy_content_into.
128 return super(InterLoomBranch, self).copy_content_into(
129 revision_id=revision_id)
130 # XXX: hint for bzrlib - break this into two routines, one for
131 # copying the last-rev pointer, one for copying parent etc.
132 source_nick = self.source.nick
133 state = self.get_loom_state(self.source)
134 parents = state.get_parents()
135 if parents:
136 loom_tip = parents[0]
137 else:
138 loom_tip = None
139 threads = self.get_threads(self.source, state.get_basis_revision_id())
140 if revision_id not in (None, _mod_revision.NULL_REVISION):
141 if threads:
142 # revision_id should be in the loom, or its an error
143 found_threads = [thread for thread, rev in threads
144 if rev == revision_id]
145 if not found_threads:
146 # the thread we have been asked to set in the remote
147 # side has not been recorded yet, so its data is not
148 # present at this point.
149 raise _loom_branch.UnrecordedRevision(
150 self.source, revision_id)
151
152 # pull in the warp, which was skipped during the initial pull
153 # because the front end does not know what to pull.
154 # nb: this is mega huge hacky. THINK. RBC 2006062
155 nested = ui.ui_factory.nested_progress_bar()
156 try:
157 if parents:
158 self.target.repository.fetch(self.source.repository,
159 revision_id=parents[0])
160 if threads:
161 for thread, rev_id in reversed(threads):
162 # fetch the loom content for this revision
163 self.target.repository.fetch(self.source.repository,
164 revision_id=rev_id)
165 finally:
166 nested.finished()
167 state = loom_state.LoomState()
168 try:
169 require_loom_branch(self.target)
170 if threads:
171 last_rev = threads[-1][1]
172 if last_rev == _loom_branch.EMPTY_REVISION:
173 last_rev = _mod_revision.NULL_REVISION
174 self.target.generate_revision_history(last_rev)
175 state.set_parents([loom_tip])
176 state.set_threads(
177 (thread + ([thread[1]],) for thread in threads)
178 )
179 else:
180 # no threads yet, be a normal branch.
181 self.source._synchronize_history(self.target, revision_id)
182 target_loom = self.unwrap_branch(self.target)
183 target_loom._set_last_loom(state)
184 except NotALoom:
185 self.source._synchronize_history(self.target, revision_id)
186 try:
187 parent = self.source.get_parent()
188 except errors.InaccessibleParent, e:
189 trace.mutter('parent was not accessible to copy: %s', e)
190 else:
191 if parent:
192 self.target.set_parent(parent)
193 if threads:
194 self.target._set_nick(threads[-1][0])
195
196 @needs_write_lock
197 def pull(self, overwrite=False, stop_revision=None,
198 run_hooks=True, possible_transports=None, _override_hook_target=None,
199 local=False):
200 """Perform a pull, reading from self.source and writing to self.target.
201
202 If the source branch is a non-loom branch, the pull is done against the
203 current warp. If it is a loom branch, then the pull is done against the
204 entire loom and the current thread set to the top thread.
205 """
206 # Special code only needed when both source and targets are looms:
207 if (self.__class__.branch_is_loom(self.target) and
208 self.__class__.branch_is_loom(self.source)):
209 puller = _loom_branch._Puller(self.source, self.target)
210 return puller.transfer(overwrite, stop_revision,
211 run_hooks, possible_transports, _override_hook_target, local)
212 return super(InterLoomBranch, self).pull(
213 overwrite=overwrite, stop_revision=stop_revision,
214 possible_transports=possible_transports,
215 _override_hook_target=_override_hook_target, local=local,
216 run_hooks=run_hooks)
217
218
219_mod_branch.InterBranch.register_optimiser(InterLoomBranch)

Subscribers

People subscribed via source and target branches