1
1
# Copyright (C) 2005 Robey Pointer <robey@lag.net>, 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
5
5
# the Free Software Foundation; either version 2 of the License, or
6
6
# (at your option) any later version.
8
8
# This program is distributed in the hope that it will be useful,
9
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
11
# GNU General Public License for more details.
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
35
38
def create_branches(self):
36
39
self.build_tree(['base/', 'base/a', 'base/b'])
37
old_format = BzrDirFormat.get_default_format()
38
BzrDirFormat.set_default_format(BzrDirMetaFormat1())
40
wt_base = BzrDir.create_standalone_workingtree('base')
42
BzrDirFormat.set_default_format(old_format)
40
format = bzrdir.format_registry.make_bzrdir('knit')
41
wt_base = BzrDir.create_standalone_workingtree('base',
44
44
b_base = wt_base.branch
50
50
wt_child = b_base.bzrdir.sprout('child').open_workingtree()
51
51
self.sftp_base = Branch.open(self.get_url('base'))
52
52
wt_child.branch.bind(self.sftp_base)
53
# check the branch histories are ready for using in tests.
54
54
self.assertEqual(['r@b-1'], b_base.revision_history())
55
55
self.assertEqual(['r@b-1'], wt_child.branch.revision_history())
57
56
return b_base, wt_child
59
58
def tearDown(self):
70
69
wt_base.commit('first', rev_id='r@b-1')
72
71
b_base = wt_base.branch
73
old_format = BzrDirFormat.get_default_format()
74
BzrDirFormat.set_default_format(BzrDirMetaFormat1())
76
b_child = BzrDir.create_branch_convenience('child')
78
BzrDirFormat.set_default_format(old_format)
72
# manually make a branch we can bind, because the default format
73
# may not be bindable-from, and we want to test the side effects etc
75
format = bzrdir.format_registry.make_bzrdir('knit')
76
b_child = BzrDir.create_branch_convenience('child', format=format)
79
77
self.assertEqual(None, b_child.get_bound_location())
80
78
self.assertEqual(None, b_child.get_master_branch())
82
80
sftp_b_base = Branch.open(self.get_url('base'))
83
81
b_child.bind(sftp_b_base)
84
82
self.assertEqual(sftp_b_base.base, b_child.get_bound_location())
85
# this line is more of a working tree test line, but - what the hey.
83
# the bind must not have given b_child history:
84
self.assertEqual([], b_child.revision_history())
85
# we should be able to update the branch at this point:
86
self.assertEqual(None, b_child.update())
87
# and now there must be history.
88
self.assertEqual(['r@b-1'], b_child.revision_history())
89
# this line is more of a working tree test line, but - what the hey,
86
91
b_child.bzrdir.open_workingtree().update()
87
92
self.failUnlessExists('child/a')
88
93
self.failUnlessExists('child/b')
99
104
self.assertEqual(['r@b-1', 'r@c-2'], wt_child.branch.revision_history())
100
105
self.assertEqual(['r@b-1', 'r@c-2'], b_base.revision_history())
102
def test_bound_fail(self):
107
def test_bound_commit_fails_when_out_of_date(self):
103
108
# Make sure commit fails if out of date.
104
109
b_base, wt_child = self.create_branches()
127
132
def test_double_binding(self):
128
133
b_base, wt_child = self.create_branches()
130
wt_child2 = wt_child.bzrdir.sprout('child2').open_workingtree()
132
wt_child2.branch.bind(wt_child.branch)
135
wt_child2 = wt_child.branch.create_checkout('child2')
134
137
open('child2/a', 'wb').write('new contents\n')
135
138
self.assertRaises(errors.CommitToDoubleBoundBranch,
162
165
wt_child.branch.bind, sftp_b_base)
164
167
def test_commit_remote_bound(self):
165
# Make sure it is detected if the current base
166
# suddenly is bound when child goes to commit
168
# Make sure it is detected if the current base is bound during the
169
# objects lifetime, when the child goes to commit.
167
170
b_base, wt_child = self.create_branches()
169
172
b_base.bzrdir.sprout('newbase')
181
184
self.assertEqual(['r@b-1'], wt_child.branch.revision_history())
182
185
self.assertEqual(['r@b-1'], sftp_b_newbase.revision_history())
184
def test_pull_updates_both(self):
185
b_base, wt_child = self.create_branches()
187
wt_newchild = b_base.bzrdir.sprout('newchild').open_workingtree()
188
open('newchild/b', 'wb').write('newchild b contents\n')
189
wt_newchild.commit('newchild', rev_id='r@d-2')
190
self.assertEqual(['r@b-1', 'r@d-2'], wt_newchild.branch.revision_history())
192
wt_child.pull(wt_newchild.branch)
193
self.assertEqual(['r@b-1', 'r@d-2'], wt_child.branch.revision_history())
194
self.assertEqual(['r@b-1', 'r@d-2'], b_base.revision_history())
196
187
def test_bind_diverged(self):
197
188
from bzrlib.builtins import merge
201
192
wt_child.branch.unbind()
202
193
open('child/a', 'ab').write('child contents\n')
203
wt_child.commit('child', rev_id='r@c-2')
194
wt_child_rev = wt_child.commit('child', rev_id='r@c-2')
205
196
self.assertEqual(['r@b-1', 'r@c-2'], wt_child.branch.revision_history())
206
197
self.assertEqual(['r@b-1'], b_base.revision_history())
214
205
self.assertRaises(errors.DivergedBranches,
215
206
wt_child.branch.bind, sftp_b_base)
217
# TODO: jam 20051230 merge_inner doesn't set pending merges
218
# Is this on purpose?
219
# merge_inner also doesn't fetch any missing revisions
220
#merge_inner(wt_child.branch, sftp_b_base.revision_tree('r@b-2'),
221
# wt_child.branch.revision_tree('r@b-1'))
222
# TODO: jam 20051230 merge(..., (None, None), ...) seems to
223
# cause an infinite loop of some sort. It definitely doesn't
224
# work, you have to use list notation
225
merge((sftp_b_base.base, 2), [None, None], this_dir=wt_child.branch.base)
227
self.assertEqual(['r@b-2'], wt_child.pending_merges())
208
wt_child.merge_from_branch(sftp_b_base)
209
self.assertEqual([wt_child_rev, 'r@b-2'], wt_child.get_parent_ids())
228
210
wt_child.commit('merged', rev_id='r@c-3')
230
# After a merge, trying to bind again should succeed
231
# by pushing the new change to base
212
# After a merge, trying to bind again should succeed but not push the
232
214
wt_child.branch.bind(sftp_b_base)
234
self.assertEqual(['r@b-1', 'r@c-2', 'r@c-3'],
235
b_base.revision_history())
236
self.assertEqual(['r@b-1', 'r@c-2', 'r@c-3'],
237
wt_child.branch.revision_history())
216
self.assertEqual(['r@b-1', 'r@b-2'], b_base.revision_history())
217
self.assertEqual(['r@b-1', 'r@c-2', 'r@c-3'],
218
wt_child.branch.revision_history())
239
def test_bind_parent_ahead(self):
220
def test_bind_parent_ahead_preserves_parent(self):
240
221
b_base, wt_child = self.create_branches()
242
223
wt_child.branch.unbind()
250
231
sftp_b_base = Branch.open(self.get_url('base'))
251
232
wt_child.branch.bind(sftp_b_base)
253
self.assertEqual(['r@b-1', 'r@b-2'], wt_child.branch.revision_history())
234
self.assertEqual(['r@b-1'], wt_child.branch.revision_history())
255
236
wt_child.branch.unbind()
262
243
self.assertEqual(['r@b-1', 'r@b-2', 'r@b-3', 'r@b-4', 'r@b-5'],
263
244
b_base.revision_history())
265
self.assertEqual(['r@b-1', 'r@b-2'], wt_child.branch.revision_history())
246
self.assertEqual(['r@b-1'], wt_child.branch.revision_history())
267
248
wt_child.branch.bind(sftp_b_base)
268
self.assertEqual(['r@b-1', 'r@b-2', 'r@b-3', 'r@b-4', 'r@b-5'],
269
wt_child.branch.revision_history())
249
self.assertEqual(['r@b-1'], wt_child.branch.revision_history())
271
def test_bind_child_ahead(self):
251
def test_bind_child_ahead_preserves_child(self):
272
252
b_base, wt_child = self.create_branches()
274
254
wt_child.branch.unbind()
280
260
sftp_b_base = Branch.open(self.get_url('base'))
281
261
wt_child.branch.bind(sftp_b_base)
283
self.assertEqual(['r@b-1', 'r@c-2'], b_base.revision_history())
263
self.assertEqual(['r@b-1'], b_base.revision_history())
285
265
# Check and make sure it also works if child is ahead multiple
286
266
wt_child.branch.unbind()
291
271
self.assertEqual(['r@b-1', 'r@c-2', 'r@c-3', 'r@c-4', 'r@c-5'],
292
272
wt_child.branch.revision_history())
293
self.assertEqual(['r@b-1', 'r@c-2'], b_base.revision_history())
273
self.assertEqual(['r@b-1'], b_base.revision_history())
295
275
wt_child.branch.bind(sftp_b_base)
296
self.assertEqual(['r@b-1', 'r@c-2', 'r@c-3', 'r@c-4', 'r@c-5'],
297
b_base.revision_history())
276
self.assertEqual(['r@b-1'], b_base.revision_history())
299
278
def test_commit_after_merge(self):
300
279
from bzrlib.builtins import merge
315
294
self.failIf(wt_child.branch.repository.has_revision('r@d-2'))
316
295
self.failIf(b_base.repository.has_revision('r@d-2'))
318
# TODO: jam 20051230 merge_inner doesn't set pending merges
319
# Is this on purpose?
320
# merge_inner also doesn't fetch any missing revisions
321
#merge_inner(wt_child.branch, b_other.revision_tree('r@d-2'),
322
# wt_child.branch.revision_tree('r@b-1'))
323
merge((wt_other.branch.base, 2), [None, None], this_dir=wt_child.branch.base)
297
wt_child.merge_from_branch(wt_other.branch)
325
299
self.failUnlessExists('child/c')
326
self.assertEqual(['r@d-2'], wt_child.pending_merges())
300
self.assertEqual(['r@d-2'], wt_child.get_parent_ids()[1:])
327
301
self.failUnless(wt_child.branch.repository.has_revision('r@d-2'))
328
302
self.failIf(b_base.repository.has_revision('r@d-2'))
330
304
# Commit should succeed, and cause merged revisions to
331
# be pulled into base
305
# be pushed into base
332
306
wt_child.commit('merge other', rev_id='r@c-2')
333
307
self.assertEqual(['r@b-1', 'r@c-2'], wt_child.branch.revision_history())
334
308
self.assertEqual(['r@b-1', 'r@c-2'], b_base.revision_history())
340
314
open('a', 'ab').write('child adds some text\n')
316
# this deletes the branch from memory
318
# and this moves it out of the way on disk
343
319
os.rename('base', 'hidden_base')
345
321
self.assertRaises(errors.BoundBranchConnectionFailure,
346
322
wt_child.commit, 'added text', rev_id='r@c-2')
348
def test_pull_fails(self):
349
b_base, wt_child = self.create_branches()
351
wt_other = wt_child.bzrdir.sprout('other').open_workingtree()
352
open('other/a', 'wb').write('new contents\n')
353
wt_other.commit('changed a', rev_id='r@d-2')
355
self.assertEqual(['r@b-1'], b_base.revision_history())
356
self.assertEqual(['r@b-1'], wt_child.branch.revision_history())
357
self.assertEqual(['r@b-1', 'r@d-2'], wt_other.branch.revision_history())
360
os.rename('base', 'hidden_base')
362
self.assertRaises(errors.BoundBranchConnectionFailure,
363
wt_child.pull, wt_other.branch)
365
324
# TODO: jam 20051231 We need invasive failure tests, so that we can show
366
325
# performance even when something fails.