1
# Copyright (C) 2007-2010 Canonical Ltd
1
# Copyright (C) 2007-2011 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
56
53
mine.merge_from_branch(other.branch)
57
54
mine.commit('merge my change', rev_id='P2')
58
55
result = mine.branch.push(other.branch)
59
self.assertEqual(['P1', 'P2'], other.branch.revision_history())
56
self.assertEqual('P2', other.branch.last_revision())
60
57
# result object contains some structured data
61
58
self.assertEqual(result.old_revid, 'M1')
62
59
self.assertEqual(result.new_revid, 'P2')
63
# and it can be treated as an integer for compatibility
64
self.assertEqual(int(result), 0)
66
61
def test_push_merged_indirect(self):
67
62
# it should be possible to do a push from one branch into another
78
73
mine.merge_from_branch(other.branch)
79
74
mine.commit('merge other', rev_id='P2')
80
75
mine.branch.push(target.branch)
81
self.assertEqual(['P1', 'P2'], target.branch.revision_history())
76
self.assertEqual('P2', target.branch.last_revision())
83
78
def test_push_to_checkout_updates_master(self):
84
79
"""Pushing into a checkout updates the checkout and the master branch"""
95
90
rev2 = other.commit('other commit')
96
91
# now push, which should update both checkout and master.
97
92
other.branch.push(checkout.branch)
98
self.assertEqual([rev1, rev2], checkout.branch.revision_history())
99
self.assertEqual([rev1, rev2], master_tree.branch.revision_history())
93
self.assertEqual(rev2, checkout.branch.last_revision())
94
self.assertEqual(rev2, master_tree.branch.last_revision())
101
96
def test_push_raises_specific_error_on_master_connection_error(self):
102
97
master_tree = self.make_branch_and_tree('master')
114
109
self.assertRaises(errors.BoundBranchConnectionFailure,
115
110
other.branch.push, checkout.branch)
112
def test_push_new_tag_to_bound_branch(self):
113
master = self.make_branch('master')
114
bound = self.make_branch('bound')
117
except errors.UpgradeRequired:
118
raise tests.TestNotApplicable(
119
'Format does not support bound branches')
120
other = bound.bzrdir.sprout('other').open_branch()
122
other.tags.set_tag('new-tag', 'some-rev')
123
except errors.TagsNotSupported:
124
raise tests.TestNotApplicable('Format does not support tags')
126
self.assertEqual({'new-tag': 'some-rev'}, bound.tags.get_tag_dict())
127
self.assertEqual({'new-tag': 'some-rev'}, master.tags.get_tag_dict())
117
129
def test_push_uses_read_lock(self):
118
130
"""Push should only need a read lock on the source side."""
119
131
source = self.make_branch_and_tree('source')
140
152
except (errors.IncompatibleFormat, errors.UninitializableFormat):
141
153
# This Branch format cannot create shared repositories
155
if not repo._format.supports_nesting_repositories:
143
157
# This is a little bit trickier because make_branch_and_tree will not
144
158
# re-use a shared repository.
145
159
a_bzrdir = self.make_bzrdir('repo/tree')
154
168
if self.vfs_transport_factory is test_server.LocalURLServer:
155
169
# the branch is colocated on disk, we cannot create a checkout.
156
170
# hopefully callers will expect this.
157
local_controldir= bzrdir.BzrDir.open(
171
local_controldir = controldir.ControlDir.open(
158
172
self.get_vfs_only_url('repo/tree'))
159
173
tree = local_controldir.create_workingtree()
170
184
self.assertEqual(tree.branch.last_revision(),
171
185
to_branch.last_revision())
187
def test_push_overwrite_with_older_mainline_rev(self):
188
"""Pushing an older mainline revision with overwrite.
190
This was <https://bugs.launchpad.net/bzr/+bug/386576>.
192
source = self.make_branch_and_tree('source')
193
target = self.make_branch('target')
195
source.commit('1st commit')
196
source.commit('2nd commit', rev_id='rev-2')
197
source.commit('3rd commit')
198
source.branch.push(target)
199
source.branch.push(target, stop_revision='rev-2', overwrite=True)
200
self.assertEqual('rev-2', target.last_revision())
173
202
def test_push_overwrite_of_non_tip_with_stop_revision(self):
174
203
"""Combining the stop_revision and overwrite options works.
186
215
source.branch.push(target, stop_revision='rev-2', overwrite=True)
187
216
self.assertEqual('rev-2', target.last_revision())
218
def test_push_repository_no_branch_doesnt_fetch_all_revs(self):
219
# See https://bugs.launchpad.net/bzr/+bug/465517
220
t = self.get_transport('target')
222
bzrdir = self.bzrdir_format.initialize_on_transport(t)
225
except errors.NotBranchError:
228
raise tests.TestNotApplicable('older formats can\'t have a repo'
231
source = self.make_branch_builder('source',
232
format=self.bzrdir_format)
233
except errors.UninitializableFormat:
234
raise tests.TestNotApplicable('cannot initialize this format')
235
source.start_series()
236
source.build_snapshot('A', None, [
237
('add', ('', 'root-id', 'directory', None))])
238
source.build_snapshot('B', ['A'], [])
239
source.build_snapshot('C', ['A'], [])
240
source.finish_series()
241
b = source.get_branch()
242
# Note: We can't read lock the source branch. Some formats take a write
243
# lock to 'set_push_location', which breaks
244
self.addCleanup(b.lock_write().unlock)
245
repo = bzrdir.create_repository()
246
# This means 'push the source branch into this dir'
247
bzrdir.push_branch(b)
248
self.addCleanup(repo.lock_read().unlock)
249
# We should have pushed 'C', but not 'B', since it isn't in the
251
self.assertEqual(['A', 'C'], sorted(repo.all_revision_ids()))
189
253
def test_push_with_default_stacking_does_not_create_broken_branch(self):
190
254
"""Pushing a new standalone branch works even when there's a default
191
255
stacking policy at the destination.
194
258
default for the branch), and will be stacked when the repo format
195
259
allows (which means that the branch format isn't necessarly preserved).
197
if isinstance(self.branch_format, branch.BzrBranchFormat4):
261
if self.bzrdir_format.fixed_components:
198
262
raise tests.TestNotApplicable('Not a metadir format.')
199
263
if isinstance(self.branch_format, branch.BranchReferenceFormat):
200
264
# This test could in principle apply to BranchReferenceFormat, but
286
350
# remotebranches can't be bound. Let's instead make a new local
287
351
# branch of the default type, which does allow binding.
288
352
# See https://bugs.launchpad.net/bzr/+bug/112020
289
local = bzrdir.BzrDir.create_branch_convenience('local2')
353
local = controldir.ControlDir.create_branch_convenience('local2')
290
354
local.bind(target)
291
355
source = self.make_branch('source')
292
356
branch.Branch.hooks.install_named_hook(
335
399
raise tests.TestNotApplicable(
336
400
'Does not apply when remote backing branch is also '
337
401
'a smart branch')
338
if isinstance(self.branch_format, branch.BzrBranchFormat4):
402
if not self.branch_format.supports_leaving_lock():
339
403
raise tests.TestNotApplicable(
340
'Branch format 4 is not usable via HPSS.')
404
'Branch format is not usable via HPSS.')
341
405
super(EmptyPushSmartEffortTests, self).setUp()
342
406
# Create a smart server that publishes whatever the backing VFS server
357
421
def test_empty_branch_api(self):
358
422
"""The branch_obj.push API should make a limited number of HPSS calls.
360
t = transport.get_transport(self.smart_server.get_url()).clone('target')
424
t = transport.get_transport_from_url(self.smart_server.get_url()).clone('target')
361
425
target = branch.Branch.open_from_transport(t)
362
426
self.empty_branch.push(target)
363
427
self.assertEqual(
394
458
def test_lossy_push_raises_same_vcs(self):
395
459
target = self.make_branch('target')
396
460
source = self.make_branch('source')
397
self.assertRaises(errors.LossyPushToSameVCS, source.lossy_push, target)
461
self.assertRaises(errors.LossyPushToSameVCS, source.push, target, lossy=True)