Merge lp:~lifeless/bzr/loomsupport into lp:bzr

Proposed by Robert Collins
Status: Merged
Approved by: Robert Collins
Approved revision: no longer in the source branch.
Merged at revision: 5293
Proposed branch: lp:~lifeless/bzr/loomsupport
Merge into: lp:bzr
Diff against target: 567 lines (+267/-154)
7 files modified
NEWS (+16/-10)
bzrlib/branch.py (+138/-131)
bzrlib/tests/per_branch/test_pull.py (+0/-11)
bzrlib/tests/per_interbranch/__init__.py (+30/-0)
bzrlib/tests/per_interbranch/test_copy_content_into.py (+47/-0)
bzrlib/tests/per_interbranch/test_get.py (+34/-0)
bzrlib/tests/per_interbranch/test_pull.py (+2/-2)
To merge this branch: bzr merge lp:~lifeless/bzr/loomsupport
Reviewer Review Type Date Requested Status
Vincent Ladeuil Approve
Review via email: mp+27473@code.launchpad.net

Commit message

InterBranch improvements needed for bzr-loom support.

Description of the change

Essentially, move Branch.copy_content_into to a InterBranch method.

Opportunistically:
 - cleanup a crazy InterBranch structural issue that had me confused while
   doing this.
 - add tests to ensure that that issue can't resurrect itself

To post a comment you must log in.
Revision history for this message
Vincent Ladeuil (vila) wrote :

Tests failing:
ERROR: bzrlib.tests.blackbox.test_push.TestPush.test_push_smart_tags_streaming_acceptance
ERROR: bzrlib.tests.blackbox.test_switch.TestSwitch.test_switch_lightweight_directory
ERROR: bzrlib.tests.blackbox.test_tags.TestTagging.test_branch_push_pull_merge_copies_tags
ERROR: bzrlib.tests.blackbox.test_tags.TestTagging.test_list_tags

I haven't reviewed yet.

review: Needs Fixing
Revision history for this message
Robert Collins (lifeless) wrote :

They work for me. Perhaps you have a non-core plugin interfering?

Revision history for this message
Vincent Ladeuil (vila) wrote :

Sounds fine, please land.

review: Approve
Revision history for this message
Robert Collins (lifeless) wrote :

sent to pqm by email

Revision history for this message
Robert Collins (lifeless) wrote :

sent to pqm by email

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'NEWS'
2--- NEWS 2010-06-14 17:58:24 +0000
3+++ NEWS 2010-06-14 21:46:28 +0000
4@@ -34,29 +34,35 @@
5 (Martin [gz], Parth Malwankar, #501307)
6
7 * ``bzr log --exclude-common-ancestry`` is now taken into account for
8- linear ancetries.
9- (Vincent Ladeuil, #575631)
10+ linear ancetries. (Vincent Ladeuil, #575631)
11
12 * Ensure that wrong path specifications in ``BZR_PLUGINS_AT`` display
13- proper error messages.
14- (Vincent Ladeuil, #591215)
15+ proper error messages. (Vincent Ladeuil, #591215)
16+
17+* Explicitly removing ``--profile-imports`` option from parsed command-line
18+ arguments on Windows, because bzr script does the same.
19+ (Alexander Belchenko, #588277)
20+
21+* Fetching was slightly confused about the best code to use and was
22+ using a new code path for all branches, resulting in more lookups than
23+ necessary on old branches. (Robert Collins, #593515)
24
25 * Final fix for 'no help for command' issue. We now show a clean message
26 when a command has no help, document how to set help more clearly, and
27 test that all commands available to the test suite have help.
28 (Robert Collins, #177500)
29
30-* Explicitly removing ``--profile-imports`` option from parsed command-line
31- arguments on Windows, because bzr script does the same.
32- (Alexander Belchenko, #588277)
33-
34 * Relative imports in plugins are now handled correctly when using
35- BZR_PLUGINS_AT.
36- (Vincent Ladeuil, #588959)
37+ BZR_PLUGINS_AT. (Vincent Ladeuil, #588959)
38
39 Improvements
40 ************
41
42+* ``Branch.copy_content_into`` is now a convenience method dispatching to
43+ a ``InterBranch`` multi-method. This permits ``bzr-loom`` and other
44+ plugins to intercept this even when a ``RemoteBranch`` proxy is in use.
45+ (Robert Collins, #201613)
46+
47 * Use lazy imports in ``bzrlib/merge.py`` so that plugins like ``news_merge``
48 do not cause modules to be loaded unnecessarily just because the plugin
49 registers a merge hook. This improves ``bzr rocks`` time by about 25%
50
51=== modified file 'bzrlib/branch.py'
52--- bzrlib/branch.py 2010-06-07 20:25:05 +0000
53+++ bzrlib/branch.py 2010-06-14 21:46:28 +0000
54@@ -29,6 +29,7 @@
55 errors,
56 lockdir,
57 lockable_files,
58+ remote,
59 repository,
60 revision as _mod_revision,
61 rio,
62@@ -968,7 +969,6 @@
63 raise errors.NoSuchRevision(self, stop_revision)
64 return other_history[self_len:stop_revision]
65
66- @needs_write_lock
67 def update_revisions(self, other, stop_revision=None, overwrite=False,
68 graph=None):
69 """Pull in new perfect-fit revisions.
70@@ -1272,24 +1272,14 @@
71 revno = 1
72 destination.set_last_revision_info(revno, revision_id)
73
74- @needs_read_lock
75 def copy_content_into(self, destination, revision_id=None):
76 """Copy the content of self into destination.
77
78 revision_id: if not None, the revision history in the new branch will
79 be truncated to end with revision_id.
80 """
81- self.update_references(destination)
82- self._synchronize_history(destination, revision_id)
83- try:
84- parent = self.get_parent()
85- except errors.InaccessibleParent, e:
86- mutter('parent was not accessible to copy: %s', e)
87- else:
88- if parent:
89- destination.set_parent(parent)
90- if self._push_should_merge_tags():
91- self.tags.merge_to(destination.tags)
92+ return InterBranch.get(self, destination).copy_content_into(
93+ revision_id=revision_id)
94
95 def update_references(self, target):
96 if not getattr(self._format, 'supports_reference_locations', False):
97@@ -3233,110 +3223,112 @@
98
99
100 class GenericInterBranch(InterBranch):
101- """InterBranch implementation that uses public Branch functions.
102- """
103+ """InterBranch implementation that uses public Branch functions."""
104+
105+ @classmethod
106+ def is_compatible(klass, source, target):
107+ # GenericBranch uses the public API, so always compatible
108+ return True
109
110 @staticmethod
111 def _get_branch_formats_to_test():
112 return BranchFormat._default_format, BranchFormat._default_format
113
114+ @classmethod
115+ def unwrap_format(klass, format):
116+ if isinstance(format, remote.RemoteBranchFormat):
117+ format._ensure_real()
118+ return format._custom_format
119+ return format
120+
121+ @needs_write_lock
122+ def copy_content_into(self, revision_id=None):
123+ """Copy the content of source into target
124+
125+ revision_id: if not None, the revision history in the new branch will
126+ be truncated to end with revision_id.
127+ """
128+ self.source.update_references(self.target)
129+ self.source._synchronize_history(self.target, revision_id)
130+ try:
131+ parent = self.source.get_parent()
132+ except errors.InaccessibleParent, e:
133+ mutter('parent was not accessible to copy: %s', e)
134+ else:
135+ if parent:
136+ self.target.set_parent(parent)
137+ if self.source._push_should_merge_tags():
138+ self.source.tags.merge_to(self.target.tags)
139+
140+ @needs_write_lock
141 def update_revisions(self, stop_revision=None, overwrite=False,
142 graph=None):
143 """See InterBranch.update_revisions()."""
144- self.source.lock_read()
145- try:
146- other_revno, other_last_revision = self.source.last_revision_info()
147- stop_revno = None # unknown
148- if stop_revision is None:
149- stop_revision = other_last_revision
150- if _mod_revision.is_null(stop_revision):
151- # if there are no commits, we're done.
152- return
153- stop_revno = other_revno
154+ other_revno, other_last_revision = self.source.last_revision_info()
155+ stop_revno = None # unknown
156+ if stop_revision is None:
157+ stop_revision = other_last_revision
158+ if _mod_revision.is_null(stop_revision):
159+ # if there are no commits, we're done.
160+ return
161+ stop_revno = other_revno
162
163- # what's the current last revision, before we fetch [and change it
164- # possibly]
165- last_rev = _mod_revision.ensure_null(self.target.last_revision())
166- # we fetch here so that we don't process data twice in the common
167- # case of having something to pull, and so that the check for
168- # already merged can operate on the just fetched graph, which will
169- # be cached in memory.
170- self.target.fetch(self.source, stop_revision)
171- # Check to see if one is an ancestor of the other
172- if not overwrite:
173- if graph is None:
174- graph = self.target.repository.get_graph()
175- if self.target._check_if_descendant_or_diverged(
176- stop_revision, last_rev, graph, self.source):
177- # stop_revision is a descendant of last_rev, but we aren't
178- # overwriting, so we're done.
179- return
180- if stop_revno is None:
181- if graph is None:
182- graph = self.target.repository.get_graph()
183- this_revno, this_last_revision = \
184- self.target.last_revision_info()
185- stop_revno = graph.find_distance_to_null(stop_revision,
186- [(other_last_revision, other_revno),
187- (this_last_revision, this_revno)])
188- self.target.set_last_revision_info(stop_revno, stop_revision)
189- finally:
190- self.source.unlock()
191+ # what's the current last revision, before we fetch [and change it
192+ # possibly]
193+ last_rev = _mod_revision.ensure_null(self.target.last_revision())
194+ # we fetch here so that we don't process data twice in the common
195+ # case of having something to pull, and so that the check for
196+ # already merged can operate on the just fetched graph, which will
197+ # be cached in memory.
198+ self.target.fetch(self.source, stop_revision)
199+ # Check to see if one is an ancestor of the other
200+ if not overwrite:
201+ if graph is None:
202+ graph = self.target.repository.get_graph()
203+ if self.target._check_if_descendant_or_diverged(
204+ stop_revision, last_rev, graph, self.source):
205+ # stop_revision is a descendant of last_rev, but we aren't
206+ # overwriting, so we're done.
207+ return
208+ if stop_revno is None:
209+ if graph is None:
210+ graph = self.target.repository.get_graph()
211+ this_revno, this_last_revision = \
212+ self.target.last_revision_info()
213+ stop_revno = graph.find_distance_to_null(stop_revision,
214+ [(other_last_revision, other_revno),
215+ (this_last_revision, this_revno)])
216+ self.target.set_last_revision_info(stop_revno, stop_revision)
217
218 def pull(self, overwrite=False, stop_revision=None,
219- possible_transports=None, _hook_master=None, run_hooks=True,
220+ possible_transports=None, run_hooks=True,
221 _override_hook_target=None, local=False):
222- """See Branch.pull.
223+ """Pull from source into self, updating my master if any.
224
225- :param _hook_master: Private parameter - set the branch to
226- be supplied as the master to pull hooks.
227 :param run_hooks: Private parameter - if false, this branch
228 is being called because it's the master of the primary branch,
229 so it should not run its hooks.
230- :param _override_hook_target: Private parameter - set the branch to be
231- supplied as the target_branch to pull hooks.
232- :param local: Only update the local branch, and not the bound branch.
233 """
234- # This type of branch can't be bound.
235- if local:
236+ bound_location = self.target.get_bound_location()
237+ if local and not bound_location:
238 raise errors.LocalRequiresBoundBranch()
239- result = PullResult()
240- result.source_branch = self.source
241- if _override_hook_target is None:
242- result.target_branch = self.target
243- else:
244- result.target_branch = _override_hook_target
245- self.source.lock_read()
246+ master_branch = None
247+ if not local and bound_location and self.source.user_url != bound_location:
248+ # not pulling from master, so we need to update master.
249+ master_branch = self.target.get_master_branch(possible_transports)
250+ master_branch.lock_write()
251 try:
252- # We assume that during 'pull' the target repository is closer than
253- # the source one.
254- self.source.update_references(self.target)
255- graph = self.target.repository.get_graph(self.source.repository)
256- # TODO: Branch formats should have a flag that indicates
257- # that revno's are expensive, and pull() should honor that flag.
258- # -- JRV20090506
259- result.old_revno, result.old_revid = \
260- self.target.last_revision_info()
261- self.target.update_revisions(self.source, stop_revision,
262- overwrite=overwrite, graph=graph)
263- # TODO: The old revid should be specified when merging tags,
264- # so a tags implementation that versions tags can only
265- # pull in the most recent changes. -- JRV20090506
266- result.tag_conflicts = self.source.tags.merge_to(self.target.tags,
267- overwrite)
268- result.new_revno, result.new_revid = self.target.last_revision_info()
269- if _hook_master:
270- result.master_branch = _hook_master
271- result.local_branch = result.target_branch
272- else:
273- result.master_branch = result.target_branch
274- result.local_branch = None
275- if run_hooks:
276- for hook in Branch.hooks['post_pull']:
277- hook(result)
278+ if master_branch:
279+ # pull from source into master.
280+ master_branch.pull(self.source, overwrite, stop_revision,
281+ run_hooks=False)
282+ return self._pull(overwrite,
283+ stop_revision, _hook_master=master_branch,
284+ run_hooks=run_hooks,
285+ _override_hook_target=_override_hook_target)
286 finally:
287- self.source.unlock()
288- return result
289+ if master_branch:
290+ master_branch.unlock()
291
292 def push(self, overwrite=False, stop_revision=None,
293 _override_hook_source_branch=None):
294@@ -3404,48 +3396,63 @@
295 _run_hooks()
296 return result
297
298- @classmethod
299- def is_compatible(self, source, target):
300- # GenericBranch uses the public API, so always compatible
301- return True
302-
303-
304-class InterToBranch5(GenericInterBranch):
305-
306- @staticmethod
307- def _get_branch_formats_to_test():
308- return BranchFormat._default_format, BzrBranchFormat5()
309-
310- def pull(self, overwrite=False, stop_revision=None,
311- possible_transports=None, run_hooks=True,
312+ def _pull(self, overwrite=False, stop_revision=None,
313+ possible_transports=None, _hook_master=None, run_hooks=True,
314 _override_hook_target=None, local=False):
315- """Pull from source into self, updating my master if any.
316-
317+ """See Branch.pull.
318+
319+ This function is the core worker, used by GenericInterBranch.pull to
320+ avoid duplication when pulling source->master and source->local.
321+
322+ :param _hook_master: Private parameter - set the branch to
323+ be supplied as the master to pull hooks.
324 :param run_hooks: Private parameter - if false, this branch
325 is being called because it's the master of the primary branch,
326 so it should not run its hooks.
327+ :param _override_hook_target: Private parameter - set the branch to be
328+ supplied as the target_branch to pull hooks.
329+ :param local: Only update the local branch, and not the bound branch.
330 """
331- bound_location = self.target.get_bound_location()
332- if local and not bound_location:
333+ # This type of branch can't be bound.
334+ if local:
335 raise errors.LocalRequiresBoundBranch()
336- master_branch = None
337- if not local and bound_location and self.source.user_url != bound_location:
338- # not pulling from master, so we need to update master.
339- master_branch = self.target.get_master_branch(possible_transports)
340- master_branch.lock_write()
341+ result = PullResult()
342+ result.source_branch = self.source
343+ if _override_hook_target is None:
344+ result.target_branch = self.target
345+ else:
346+ result.target_branch = _override_hook_target
347+ self.source.lock_read()
348 try:
349- if master_branch:
350- # pull from source into master.
351- master_branch.pull(self.source, overwrite, stop_revision,
352- run_hooks=False)
353- return super(InterToBranch5, self).pull(overwrite,
354- stop_revision, _hook_master=master_branch,
355- run_hooks=run_hooks,
356- _override_hook_target=_override_hook_target)
357+ # We assume that during 'pull' the target repository is closer than
358+ # the source one.
359+ self.source.update_references(self.target)
360+ graph = self.target.repository.get_graph(self.source.repository)
361+ # TODO: Branch formats should have a flag that indicates
362+ # that revno's are expensive, and pull() should honor that flag.
363+ # -- JRV20090506
364+ result.old_revno, result.old_revid = \
365+ self.target.last_revision_info()
366+ self.target.update_revisions(self.source, stop_revision,
367+ overwrite=overwrite, graph=graph)
368+ # TODO: The old revid should be specified when merging tags,
369+ # so a tags implementation that versions tags can only
370+ # pull in the most recent changes. -- JRV20090506
371+ result.tag_conflicts = self.source.tags.merge_to(self.target.tags,
372+ overwrite)
373+ result.new_revno, result.new_revid = self.target.last_revision_info()
374+ if _hook_master:
375+ result.master_branch = _hook_master
376+ result.local_branch = result.target_branch
377+ else:
378+ result.master_branch = result.target_branch
379+ result.local_branch = None
380+ if run_hooks:
381+ for hook in Branch.hooks['post_pull']:
382+ hook(result)
383 finally:
384- if master_branch:
385- master_branch.unlock()
386+ self.source.unlock()
387+ return result
388
389
390 InterBranch.register_optimiser(GenericInterBranch)
391-InterBranch.register_optimiser(InterToBranch5)
392
393=== modified file 'bzrlib/tests/per_branch/test_pull.py'
394--- bzrlib/tests/per_branch/test_pull.py 2010-02-10 17:52:08 +0000
395+++ bzrlib/tests/per_branch/test_pull.py 2010-06-14 21:46:28 +0000
396@@ -98,17 +98,6 @@
397 master_tree.branch.pull, other.branch, local = True)
398 self.assertEqual([rev1], master_tree.branch.revision_history())
399
400- def test_pull_raises_specific_error_on_master_connection_error(self):
401- master_tree = self.make_branch_and_tree('master')
402- checkout = master_tree.branch.create_checkout('checkout')
403- other = master_tree.branch.bzrdir.sprout('other').open_workingtree()
404- # move the branch out of the way on disk to cause a connection
405- # error.
406- os.rename('master', 'master_gone')
407- # try to pull, which should raise a BoundBranchConnectionFailure.
408- self.assertRaises(errors.BoundBranchConnectionFailure,
409- checkout.branch.pull, other.branch)
410-
411 def test_pull_returns_result(self):
412 parent = self.make_branch_and_tree('parent')
413 parent.commit('1st post', rev_id='P1')
414
415=== modified file 'bzrlib/tests/per_interbranch/__init__.py'
416--- bzrlib/tests/per_interbranch/__init__.py 2009-05-07 05:08:46 +0000
417+++ bzrlib/tests/per_interbranch/__init__.py 2010-06-14 21:46:28 +0000
418@@ -144,8 +144,38 @@
419 return newbranch.bzrdir
420
421
422+class StubWithFormat(object):
423+ """A stub object used to check that convenience methods call Inter's."""
424+
425+ _format = object()
426+
427+
428+class StubMatchingInter(object):
429+ """An inter for tests.
430+
431+ This is not a subclass of InterBranch so that missing methods are caught
432+ and added rather than actually trying to do something.
433+ """
434+
435+ _uses = []
436+
437+ def __init__(self, source, target):
438+ self.source = source
439+ self.target = target
440+
441+ @classmethod
442+ def is_compatible(klass, source, target):
443+ return StubWithFormat._format in (source._format, target._format)
444+
445+ def copy_content_into(self, *args, **kwargs):
446+ self.__class__._uses.append(
447+ (self, 'copy_content_into', args, kwargs))
448+
449+
450 def load_tests(standard_tests, module, loader):
451 submod_tests = loader.loadTestsFromModuleNames([
452+ 'bzrlib.tests.per_interbranch.test_get',
453+ 'bzrlib.tests.per_interbranch.test_copy_content_into',
454 'bzrlib.tests.per_interbranch.test_pull',
455 'bzrlib.tests.per_interbranch.test_push',
456 'bzrlib.tests.per_interbranch.test_update_revisions',
457
458=== added file 'bzrlib/tests/per_interbranch/test_copy_content_into.py'
459--- bzrlib/tests/per_interbranch/test_copy_content_into.py 1970-01-01 00:00:00 +0000
460+++ bzrlib/tests/per_interbranch/test_copy_content_into.py 2010-06-14 21:46:28 +0000
461@@ -0,0 +1,47 @@
462+# Copyright (C) 2010 Canonical Ltd
463+#
464+# This program is free software; you can redistribute it and/or modify
465+# it under the terms of the GNU General Public License as published by
466+# the Free Software Foundation; either version 2 of the License, or
467+# (at your option) any later version.
468+#
469+# This program is distributed in the hope that it will be useful,
470+# but WITHOUT ANY WARRANTY; without even the implied warranty of
471+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
472+# GNU General Public License for more details.
473+#
474+# You should have received a copy of the GNU General Public License
475+# along with this program; if not, write to the Free Software
476+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
477+
478+"""Tests for bzrlib.branch.InterBranch.copy_content_into."""
479+
480+from bzrlib import branch
481+from bzrlib.tests.per_interbranch import (
482+ StubMatchingInter,
483+ StubWithFormat,
484+ TestCaseWithInterBranch,
485+ )
486+
487+
488+class TestCopyContentInto(TestCaseWithInterBranch):
489+
490+ def test_contract_convenience_method(self):
491+ self.tree1 = self.make_branch_and_tree('tree1')
492+ rev1 = self.tree1.commit('one')
493+ branch2 = self.make_to_branch('tree2')
494+ branch2.repository.fetch(self.tree1.branch.repository)
495+ self.tree1.branch.copy_content_into(branch2, revision_id=rev1)
496+
497+ def test_inter_is_used(self):
498+ self.tree1 = self.make_branch_and_tree('tree1')
499+ self.addCleanup(branch.InterBranch.unregister_optimiser,
500+ StubMatchingInter)
501+ branch.InterBranch.register_optimiser(StubMatchingInter)
502+ del StubMatchingInter._uses[:]
503+ self.tree1.branch.copy_content_into(StubWithFormat(), revision_id='54')
504+ self.assertLength(1, StubMatchingInter._uses)
505+ use = StubMatchingInter._uses[0]
506+ self.assertEqual('copy_content_into', use[1])
507+ self.assertEqual('54', use[3]['revision_id'])
508+ del StubMatchingInter._uses[:]
509
510=== added file 'bzrlib/tests/per_interbranch/test_get.py'
511--- bzrlib/tests/per_interbranch/test_get.py 1970-01-01 00:00:00 +0000
512+++ bzrlib/tests/per_interbranch/test_get.py 2010-06-14 21:46:28 +0000
513@@ -0,0 +1,34 @@
514+# Copyright (C) 2010 Canonical Ltd
515+#
516+# This program is free software; you can redistribute it and/or modify
517+# it under the terms of the GNU General Public License as published by
518+# the Free Software Foundation; either version 2 of the License, or
519+# (at your option) any later version.
520+#
521+# This program is distributed in the hope that it will be useful,
522+# but WITHOUT ANY WARRANTY; without even the implied warranty of
523+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
524+# GNU General Public License for more details.
525+#
526+# You should have received a copy of the GNU General Public License
527+# along with this program; if not, write to the Free Software
528+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
529+
530+"""Tests for bzrlib.branch.InterBranch.get."""
531+
532+from bzrlib import (
533+ branch,
534+ )
535+from bzrlib.tests.per_interbranch import (
536+ TestCaseWithInterBranch,
537+ )
538+
539+
540+class TestCopyContentInto(TestCaseWithInterBranch):
541+
542+ def test_gets_right_inter(self):
543+ self.tree1 = self.make_branch_and_tree('tree1')
544+ branch2 = self.make_to_branch('tree2')
545+ self.assertIs(branch.InterBranch.get(
546+ self.tree1.branch, branch2).__class__,
547+ self.interbranch_class)
548
549=== modified file 'bzrlib/tests/per_interbranch/test_pull.py'
550--- bzrlib/tests/per_interbranch/test_pull.py 2009-07-10 05:49:34 +0000
551+++ bzrlib/tests/per_interbranch/test_pull.py 2010-06-14 21:46:28 +0000
552@@ -76,13 +76,13 @@
553 def test_pull_raises_specific_error_on_master_connection_error(self):
554 master_tree = self.make_from_branch_and_tree('master')
555 checkout = master_tree.branch.create_checkout('checkout')
556- other = self.sprout_to(master_tree.branch.bzrdir, 'other').open_workingtree()
557+ other = self.sprout_to(master_tree.branch.bzrdir, 'other').open_branch()
558 # move the branch out of the way on disk to cause a connection
559 # error.
560 os.rename('master', 'master_gone')
561 # try to pull, which should raise a BoundBranchConnectionFailure.
562 self.assertRaises(errors.BoundBranchConnectionFailure,
563- checkout.branch.pull, other.branch)
564+ checkout.branch.pull, other)
565
566 def test_pull_returns_result(self):
567 parent = self.make_from_branch_and_tree('parent')