27
26
from bzrlib import (
38
36
from bzrlib.branch import Branch
39
from bzrlib.bzrdir import BzrDir
37
from bzrlib.controldir import ControlDir
40
38
from bzrlib.memorytree import MemoryTree
41
39
from bzrlib.revision import NULL_REVISION
42
from bzrlib.smart import client, server
43
40
from bzrlib.smart.repository import SmartServerRepositoryGetParentMap
44
41
from bzrlib.tests.per_interbranch import (
45
42
TestCaseWithInterBranch,
63
60
mine.merge_from_branch(other.branch)
64
61
mine.commit('merge my change', rev_id='P2')
65
62
result = mine.branch.push(other.branch)
66
self.assertEqual(['P1', 'P2'], other.branch.revision_history())
63
self.assertEqual('P2', other.branch.last_revision())
67
64
# result object contains some structured data
68
65
self.assertEqual(result.old_revid, 'M1')
69
66
self.assertEqual(result.new_revid, 'P2')
70
# and it can be treated as an integer for compatibility
71
self.assertEqual(int(result), 0)
73
68
def test_push_merged_indirect(self):
74
69
# it should be possible to do a push from one branch into another
85
80
mine.merge_from_branch(other.branch)
86
81
mine.commit('merge other', rev_id='P2')
87
82
mine.branch.push(target.branch)
88
self.assertEqual(['P1', 'P2'], target.branch.revision_history())
83
self.assertEqual('P2', target.branch.last_revision())
90
85
def test_push_to_checkout_updates_master(self):
91
86
"""Pushing into a checkout updates the checkout and the master branch"""
103
98
rev2 = other.commit('other commit')
104
99
# now push, which should update both checkout and master.
105
100
other.branch.push(checkout.branch)
106
self.assertEqual([rev1, rev2], checkout.branch.revision_history())
107
self.assertEqual([rev1, rev2], master_tree.branch.revision_history())
101
self.assertEqual(rev2, checkout.branch.last_revision())
102
self.assertEqual(rev2, master_tree.branch.last_revision())
109
104
def test_push_raises_specific_error_on_master_connection_error(self):
110
105
master_tree = self.make_to_branch_and_tree('master')
118
113
other = other_bzrdir.open_workingtree()
119
114
# move the branch out of the way on disk to cause a connection
121
os.rename('master', 'master_gone')
116
master_tree.bzrdir.destroy_branch()
122
117
# try to push, which should raise a BoundBranchConnectionFailure.
123
118
self.assertRaises(errors.BoundBranchConnectionFailure,
124
119
other.branch.push, checkout.branch)
160
155
tree = a_branch.bzrdir.create_workingtree()
156
except errors.UnsupportedOperation:
157
self.assertFalse(a_branch.bzrdir._format.supports_workingtrees)
158
tree = a_branch.create_checkout('repo/tree', lightweight=True)
161
159
except errors.NotLocalUrl:
162
160
if self.vfs_transport_factory is test_server.LocalURLServer:
163
161
# the branch is colocated on disk, we cannot create a checkout.
164
162
# hopefully callers will expect this.
165
local_controldir = bzrdir.BzrDir.open(self.get_vfs_only_url('repo/tree'))
163
local_controldir = controldir.ControlDir.open(self.get_vfs_only_url('repo/tree'))
166
164
tree = local_controldir.create_workingtree()
168
166
tree = a_branch.create_checkout('repo/tree', lightweight=True)
200
198
default for the branch), and will be stacked when the repo format
201
199
allows (which means that the branch format isn't necessarly preserved).
203
if isinstance(self.branch_format_from, branch.BzrBranchFormat4):
204
raise tests.TestNotApplicable('Not a metadir format.')
205
201
if isinstance(self.branch_format_from, branch.BranchReferenceFormat):
206
202
# This test could in principle apply to BranchReferenceFormat, but
207
203
# make_branch_builder doesn't support it.
278
274
# remote graph any further.
279
275
bzr_core_trace = Equals(
280
276
['Repository.insert_stream_1.19', 'Repository.insert_stream_1.19',
281
'get', 'Branch.set_last_revision_info', 'Branch.unlock'])
277
'Branch.set_last_revision_info', 'Branch.unlock'])
282
278
bzr_loom_trace = Equals(
283
279
['Repository.insert_stream_1.19', 'Repository.insert_stream_1.19',
284
'get', 'Branch.set_last_revision_info', 'get', 'Branch.unlock'])
280
'Branch.set_last_revision_info', 'get', 'Branch.unlock'])
285
281
self.assertThat(calls_after_insert_stream,
286
282
MatchesAny(bzr_core_trace, bzr_loom_trace))
288
284
def disableOptimisticGetParentMap(self):
289
285
# Tweak some class variables to stop remote get_parent_map calls asking
290
286
# for or receiving more data than the caller asked for.
291
self.overrideAttr(repository.InterRepository,
287
self.overrideAttr(vf_repository.InterVersionedFileRepository,
292
288
'_walk_to_common_revisions_batch_size', 1)
293
289
self.overrideAttr(SmartServerRepositoryGetParentMap,
294
290
'no_extra_results', True)
300
296
self.hook_calls = []
301
TestCaseWithInterBranch.setUp(self)
297
super(TestPushHook, self).setUp()
303
299
def capture_post_push_hook(self, result):
304
300
"""Capture post push hook calls to self.hook_calls.
348
344
# remotebranches can't be bound. Let's instead make a new local
349
345
# branch of the default type, which does allow binding.
350
346
# See https://bugs.launchpad.net/bzr/+bug/112020
351
local = BzrDir.create_branch_convenience('local2')
347
local = ControlDir.create_branch_convenience('local2')
352
348
local.bind(target)
353
349
source = self.make_from_branch('source')
354
350
Branch.hooks.install_named_hook('post_push',
369
365
rev1 = target.commit('rev 1')
371
sourcedir = target.bzrdir.clone(self.get_url('source'))
367
sourcedir = target.branch.bzrdir.clone(self.get_url('source'))
372
368
source = MemoryTree.create_on_branch(sourcedir.open_branch())
373
369
rev2 = source.commit('rev 2')
374
370
Branch.hooks.install_named_hook('post_push',