132
136
return BzrDir.create_branch_convenience(path, format=format)
134
138
def test_bound_commit(self):
136
self.create_branches()
139
open('a', 'wb').write('new contents\n')
140
bzr('commit -m child')
139
child_tree = self.create_branches()[1]
141
self.build_tree_contents([('child/a', 'new contents')])
142
child_tree.commit(message='child')
144
self.check_revno(2, 'child')
144
146
# Make sure it committed on the parent
145
self.check_revno(2, '../base')
147
self.check_revno(2, 'base')
147
149
def test_bound_fail(self):
148
150
# Make sure commit fails if out of date.
150
self.create_branches()
153
open('a', 'wb').write('new base contents\n')
154
bzr('commit -m base')
159
open('b', 'wb').write('new b child contents\n')
160
bzr('commit -m child', retcode=3)
166
bzr('commit -m child')
168
self.check_revno(3, '../base')
151
base_tree, child_tree = self.create_branches()
153
self.build_tree_contents([
154
('base/a', 'new base contents\n' ),
155
('child/b', 'new b child contents\n')])
156
base_tree.commit(message='base')
157
self.check_revno(2, 'base')
159
self.check_revno(1, 'child')
160
self.assertRaises(errors.BoundBranchOutOfDate, child_tree.commit,
162
self.check_revno(1, 'child')
165
self.check_revno(2, 'child')
167
child_tree.commit(message='child')
168
self.check_revno(3, 'child')
169
self.check_revno(3, 'base')
170
171
def test_double_binding(self):
172
self.create_branches()
174
bzr('branch child child2')
172
child_tree = self.create_branches()[1]
174
child2_tree = child_tree.bzrdir.sprout('child2').open_workingtree()
175
176
os.chdir('child2')
177
177
# Double binding succeeds, but committing to child2 should fail
178
self.run_bzr('bind ../child')
180
bzr('commit -m child2 --unchanged', retcode=3)
180
self.assertRaises(errors.CommitToDoubleBoundBranch,
181
child2_tree.commit, message='child2', allow_pointless=True)
182
183
def test_unbinding(self):
184
self.create_branches()
187
open('a', 'wb').write('new base contents\n')
188
bzr('commit -m base')
192
open('b', 'wb').write('new b child contents\n')
194
bzr('commit -m child', retcode=3)
197
bzr('commit -m child')
200
bzr('bind', retcode=3)
184
base_tree, child_tree = self.create_branches()
186
self.build_tree_contents([
187
('base/a', 'new base contents\n' ),
188
('child/b', 'new b child contents\n')])
190
base_tree.commit(message='base')
191
self.check_revno(2, 'base')
193
self.check_revno(1, 'child')
195
self.run_bzr("commit -m child", retcode=3)
197
self.run_bzr('unbind')
198
child_tree.commit(message='child')
201
self.run_bzr('bind', retcode=3)
202
203
def test_commit_remote_bound(self):
203
204
# It is not possible to commit to a branch
204
205
# which is bound to a branch which is bound
206
self.create_branches()
207
bzr('branch base newbase')
206
base_tree, child_tree = self.create_branches()
207
base_tree.bzrdir.sprout('newbase')
210
210
# There is no way to know that B has already
211
211
# been bound by someone else, otherwise it
212
212
# might be nice if this would fail
213
bzr('bind ../newbase')
213
self.run_bzr('bind ../newbase')
215
215
os.chdir('../child')
216
bzr('commit -m failure --unchanged', retcode=3)
216
self.run_bzr('commit -m failure --unchanged', retcode=3)
218
218
def test_pull_updates_both(self):
220
self.create_branches()
221
bzr('branch base newchild')
223
open('b', 'wb').write('newchild b contents\n')
224
bzr('commit -m newchild')
219
base_tree = self.create_branches()[0]
220
newchild_tree = base_tree.bzrdir.sprout('newchild').open_workingtree()
221
self.build_tree_contents([('newchild/b', 'newchild b contents\n')])
222
newchild_tree.commit(message='newchild')
223
self.check_revno(2, 'newchild')
228
226
# The pull should succeed, and update
229
227
# the bound parent branch
230
bzr('pull ../newchild')
228
self.run_bzr('pull ../newchild')
231
229
self.check_revno(2)
233
231
self.check_revno(2, '../base')
235
233
def test_bind_diverged(self):
237
self.create_branches()
242
bzr('commit -m child --unchanged')
247
bzr('commit -m base --unchanged')
234
base_tree, child_tree = self.create_branches()
235
base_branch = base_tree.branch
236
child_branch = child_tree.branch
239
self.run_bzr('unbind')
241
child_tree.commit(message='child', allow_pointless=True)
245
self.check_revno(1, 'base')
246
base_tree.commit(message='base', allow_pointless=True)
247
self.check_revno(2, 'base')
251
250
# These branches have diverged
252
bzr('bind ../base', retcode=3)
251
self.run_bzr('bind ../base', retcode=3)
254
253
# TODO: In the future, this might require actual changes
255
254
# to have occurred, rather than just a new revision entry
257
bzr('commit -m merged')
255
child_tree.merge_from_branch(base_branch)
256
child_tree.commit(message='merged')
258
257
self.check_revno(3)
260
259
# After binding, the revision history should be unaltered
261
base_branch = Branch.open('../base')
262
child_branch = Branch.open('.')
263
260
# take a copy before
264
261
base_history = base_branch.revision_history()
265
262
child_history = child_branch.revision_history()
267
264
# After a merge, trying to bind again should succeed
268
265
# keeping the new change as a local commit.
266
self.run_bzr('bind ../base')
270
267
self.check_revno(3)
271
268
self.check_revno(2, '../base')
275
272
self.assertEqual(child_history, child_branch.revision_history())
277
274
def test_bind_parent_ahead(self):
279
self.create_branches()
275
base_tree = self.create_branches()[0]
281
277
os.chdir('child')
285
bzr('commit -m base --unchanged')
278
self.run_bzr('unbind')
280
base_tree.commit(message='base', allow_pointless=True)
288
282
self.check_revno(1)
283
self.run_bzr('bind ../base')
291
285
# binding does not pull data:
292
286
self.check_revno(1)
287
self.run_bzr('unbind')
295
289
# Check and make sure it also works if parent is ahead multiple
297
bzr(['commit', '-m', 'base 3', '--unchanged'])
298
bzr(['commit', '-m', 'base 4', '--unchanged'])
299
bzr(['commit', '-m', 'base 5', '--unchanged'])
290
base_tree.commit(message='base 3', allow_pointless=True)
291
base_tree.commit(message='base 4', allow_pointless=True)
292
base_tree.commit(message='base 5', allow_pointless=True)
293
self.check_revno(5, '../base')
303
295
self.check_revno(1)
296
self.run_bzr('bind ../base')
305
297
self.check_revno(1)
307
299
def test_bind_child_ahead(self):
308
300
# test binding when the master branches history is a prefix of the
309
301
# childs - it should bind ok but the revision histories should not
312
self.create_branches()
303
child_tree = self.create_branches()[1]
314
305
os.chdir('child')
316
bzr('commit -m child --unchanged')
306
self.run_bzr('unbind')
307
child_tree.commit(message='child', allow_pointless=True)
317
308
self.check_revno(2)
318
309
self.check_revno(1, '../base')
311
self.run_bzr('bind ../base')
321
312
self.check_revno(1, '../base')
323
314
# Check and make sure it also works if child is ahead multiple
325
bzr(['commit', '-m', 'child 3', '--unchanged'])
326
bzr(['commit', '-m', 'child 4', '--unchanged'])
327
bzr(['commit', '-m', 'child 5', '--unchanged'])
315
self.run_bzr('unbind')
316
child_tree.commit(message='child 3', allow_pointless=True)
317
child_tree.commit(message='child 4', allow_pointless=True)
318
child_tree.commit(message='child 5', allow_pointless=True)
328
319
self.check_revno(5)
330
321
self.check_revno(1, '../base')
322
self.run_bzr('bind ../base')
332
323
self.check_revno(1, '../base')
334
325
def test_commit_after_merge(self):
336
self.create_branches()
326
base_tree, child_tree = self.create_branches()
338
328
# We want merge to be able to be a local only
339
329
# operation, because it can be without violating
340
330
# the binding invariants.
341
331
# But we can't fail afterwards
343
bzr('branch child other')
346
open('c', 'wb').write('file c\n')
348
bzr(['commit', '-m', 'adding c'])
349
new_rev_id = bzr('revision-history')[0].strip().split('\n')[-1]
352
bzr('merge ../other')
354
self.failUnlessExists('c')
355
tree = WorkingTree.open('.') # opens child
356
self.assertEqual([new_rev_id], tree.get_parent_ids()[1:])
332
other_tree = child_tree.bzrdir.sprout('other').open_workingtree()
333
other_branch = other_tree.branch
335
self.build_tree_contents([('other/c', 'file c\n')])
337
other_tree.commit(message='adding c')
338
new_rev_id = other_branch.revision_history()[-1]
340
child_tree.merge_from_branch(other_branch)
342
self.failUnlessExists('child/c')
343
self.assertEqual([new_rev_id], child_tree.get_parent_ids()[1:])
358
345
# Make sure the local branch has the installed revision
359
bzr(['cat-revision', new_rev_id])
346
self.assertTrue(child_tree.branch.repository.has_revision(new_rev_id))
361
348
# And make sure that the base tree does not
363
bzr(['cat-revision', new_rev_id], retcode=3)
349
self.assertFalse(base_tree.branch.repository.has_revision(new_rev_id))
365
351
# Commit should succeed, and cause merged revisions to
366
352
# be pulled into base
368
bzr(['commit', '-m', 'merge other'])
375
bzr(['cat-revision', new_rev_id])
354
self.run_bzr(['commit', '-m', 'merge other'])
358
self.check_revno(2, '../base')
360
self.assertTrue(base_tree.branch.repository.has_revision(new_rev_id))
377
362
def test_pull_overwrite(self):
378
363
# XXX: This test should be moved to branch-implemenations/test_pull
380
self.create_branches()
382
bzr('branch child other')
385
open('a', 'wb').write('new contents\n')
386
bzr(['commit', '-m', 'changed a'])
388
open('a', 'ab').write('and then some\n')
389
bzr(['commit', '-m', 'another a'])
391
open('a', 'ab').write('and some more\n')
392
bzr(['commit', '-m', 'yet another a'])
396
open('a', 'wb').write('also changed a\n')
397
bzr(['commit', '-m', 'child modified a'])
400
self.check_revno(2, '../base')
402
bzr('pull --overwrite ../other')
364
child_tree = self.create_branches()[1]
366
other_tree = child_tree.bzrdir.sprout('other').open_workingtree()
368
self.build_tree_contents([('other/a', 'new contents\n')])
369
other_tree.commit(message='changed a')
370
self.check_revno(2, 'other')
371
self.build_tree_contents([
372
('other/a', 'new contents\nand then some\n')])
373
other_tree.commit(message='another a')
374
self.check_revno(3, 'other')
375
self.build_tree_contents([
376
('other/a', 'new contents\nand then some\nand some more\n')])
377
other_tree.commit('yet another a')
378
self.check_revno(4, 'other')
380
self.build_tree_contents([('child/a', 'also changed a\n')])
381
child_tree.commit(message='child modified a')
383
self.check_revno(2, 'child')
384
self.check_revno(2, 'base')
387
self.run_bzr('pull --overwrite ../other')
404
389
# both the local and master should have been updated.
405
390
self.check_revno(4)