18
18
"""Tests of bound branches (binding, unbinding, commit, etc) command."""
21
from cStringIO import StringIO
23
20
from bzrlib import (
28
from bzrlib.branch import Branch
29
from bzrlib.bzrdir import (BzrDir, BzrDirFormat, BzrDirMetaFormat1)
30
from bzrlib.osutils import getcwd
31
26
from bzrlib.tests import script
32
import bzrlib.urlutils as urlutils
33
from bzrlib.workingtree import WorkingTree
36
class TestLegacyFormats(tests.TestCaseWithTransport):
39
super(TestLegacyFormats, self).setUp()
40
self.build_tree(['master/', 'child/'])
41
self.make_branch_and_tree('master')
42
self.make_branch_and_tree('child',
43
format=bzrdir.format_registry.make_bzrdir('weave'))
46
def test_bind_format_6_bzrdir(self):
47
# bind on a format 6 bzrdir should error
48
out,err = self.run_bzr('bind ../master', retcode=3)
49
self.assertEqual('', out)
50
# TODO: jam 20060427 Probably something like this really should
51
# print out the actual path, rather than the URL
52
cwd = urlutils.local_path_to_url(getcwd())
53
self.assertEqual('bzr: ERROR: To use this feature you must '
54
'upgrade your branch at %s/.\n' % cwd, err)
56
def test_unbind_format_6_bzrdir(self):
57
# bind on a format 6 bzrdir should error
58
out,err = self.run_bzr('unbind', retcode=3)
59
self.assertEqual('', out)
60
cwd = urlutils.local_path_to_url(getcwd())
61
self.assertEqual('bzr: ERROR: To use this feature you must '
62
'upgrade your branch at %s/.\n' % cwd, err)
65
29
class TestBoundBranches(tests.TestCaseWithTransport):
71
35
base_tree.add(['a', 'b'])
72
36
base_tree.commit('init')
74
branch = base_tree.branch
76
child_tree = branch.create_checkout('child')
39
child_tree = base_tree.branch.create_checkout('child')
78
41
self.check_revno(1, 'child')
79
d = BzrDir.open('child')
42
d = controldir.ControlDir.open('child')
80
43
self.assertNotEqual(None, d.open_branch().get_master_branch())
82
45
return base_tree, child_tree
84
47
def check_revno(self, val, loc='.'):
86
val, len(BzrDir.open(loc).open_branch().revision_history()))
49
val, controldir.ControlDir.open(loc).open_branch().last_revision_info()[0])
88
51
def test_simple_binding(self):
89
52
tree = self.make_branch_and_tree('base')
90
53
self.build_tree(['base/a', 'base/b'])
92
55
tree.commit(message='init')
95
57
tree.bzrdir.sprout('child')
98
self.run_bzr('bind ../base')
59
self.run_bzr('bind ../base', working_dir='child')
61
d = controldir.ControlDir.open('child')
101
62
self.assertNotEqual(None, d.open_branch().get_master_branch())
103
self.run_bzr('unbind')
64
self.run_bzr('unbind', working_dir='child')
104
65
self.assertEqual(None, d.open_branch().get_master_branch())
106
self.run_bzr('unbind', retcode=3)
67
self.run_bzr('unbind', retcode=3, working_dir='child')
108
69
def test_bind_branch6(self):
109
70
branch1 = self.make_branch('branch1', format='dirstate-tags')
111
error = self.run_bzr('bind', retcode=3)[1]
112
self.assertContainsRe(error, 'no previous location known')
71
error = self.run_bzr('bind', retcode=3, working_dir='branch1')[1]
73
error, 'No location supplied and no previous location known\n')
114
75
def setup_rebind(self, format):
115
76
branch1 = self.make_branch('branch1')
120
81
def test_rebind_branch6(self):
121
82
self.setup_rebind('dirstate-tags')
125
self.assertContainsRe(b.get_bound_location(), '\/branch1\/$')
83
self.run_bzr('bind', working_dir='branch2')
84
b = branch.Branch.open('branch2')
85
self.assertEndsWith(b.get_bound_location(), '/branch1/')
127
87
def test_rebind_branch5(self):
128
88
self.setup_rebind('knit')
130
error = self.run_bzr('bind', retcode=3)[1]
131
self.assertContainsRe(error, 'old locations')
89
error = self.run_bzr('bind', retcode=3, working_dir='branch2')[1]
91
error, 'No location supplied. This format does not remember'
133
94
def test_bound_commit(self):
134
95
child_tree = self.create_branches()[1]
166
127
def test_double_binding(self):
167
128
child_tree = self.create_branches()[1]
169
child2_tree = child_tree.bzrdir.sprout('child2').open_workingtree()
129
child_tree.bzrdir.sprout('child2')
172
131
# Double binding succeeds, but committing to child2 should fail
173
self.run_bzr('bind ../child')
132
self.run_bzr('bind ../child', working_dir='child2')
134
# Refresh the child tree object as 'unbind' modified it
135
child2_tree = controldir.ControlDir.open('child2').open_workingtree()
175
136
self.assertRaises(errors.CommitToDoubleBoundBranch,
176
137
child2_tree.commit, message='child2', allow_pointless=True)
186
147
self.check_revno(2, 'base')
188
149
self.check_revno(1, 'child')
190
self.run_bzr("commit -m child", retcode=3)
192
self.run_bzr('unbind')
150
self.run_bzr("commit -m child", retcode=3, working_dir='child')
151
self.check_revno(1, 'child')
152
self.run_bzr('unbind', working_dir='child')
153
# Refresh the child tree/branch objects as 'unbind' modified them
154
child_tree = child_tree.bzrdir.open_workingtree()
193
155
child_tree.commit(message='child')
156
self.check_revno(2, 'child')
196
158
def test_commit_remote_bound(self):
197
159
# It is not possible to commit to a branch
199
161
base_tree, child_tree = self.create_branches()
200
162
base_tree.bzrdir.sprout('newbase')
203
164
# There is no way to know that B has already
204
165
# been bound by someone else, otherwise it
205
166
# might be nice if this would fail
206
self.run_bzr('bind ../newbase')
167
self.run_bzr('bind ../newbase', working_dir='base')
209
self.run_bzr('commit -m failure --unchanged', retcode=3)
169
self.run_bzr('commit -m failure --unchanged', retcode=3,
211
172
def test_pull_updates_both(self):
212
173
base_tree = self.create_branches()[0]
215
176
newchild_tree.commit(message='newchild')
216
177
self.check_revno(2, 'newchild')
219
179
# The pull should succeed, and update
220
180
# the bound parent branch
221
self.run_bzr('pull ../newchild')
224
self.check_revno(2, '../base')
181
self.run_bzr('pull ../newchild', working_dir='child')
182
self.check_revno(2, 'child')
183
self.check_revno(2, 'base')
226
185
def test_pull_local_updates_local(self):
227
186
base_tree = self.create_branches()[0]
230
189
newchild_tree.commit(message='newchild')
231
190
self.check_revno(2, 'newchild')
234
192
# The pull should succeed, and update
235
193
# the bound parent branch
236
self.run_bzr('pull ../newchild --local')
239
self.check_revno(1, '../base')
194
self.run_bzr('pull ../newchild --local', working_dir='child')
195
self.check_revno(2, 'child')
196
self.check_revno(1, 'base')
241
198
def test_bind_diverged(self):
242
199
base_tree, child_tree = self.create_branches()
243
200
base_branch = base_tree.branch
244
201
child_branch = child_tree.branch
247
self.run_bzr('unbind')
203
self.run_bzr('unbind', working_dir='child')
205
# Refresh the child tree/branch objects as 'unbind' modified them
206
child_tree = child_tree.bzrdir.open_workingtree()
249
207
child_tree.commit(message='child', allow_pointless=True)
208
self.check_revno(2, 'child')
253
210
self.check_revno(1, 'base')
254
211
base_tree.commit(message='base', allow_pointless=True)
255
212
self.check_revno(2, 'base')
258
214
# These branches have diverged, but bind should succeed anyway
259
self.run_bzr('bind ../base')
215
self.run_bzr('bind ../base', working_dir='child')
217
# Refresh the child tree/branch objects as 'bind' modified them
218
child_tree = child_tree.bzrdir.open_workingtree()
261
219
# This should turn the local commit into a merge
262
220
child_tree.update()
263
221
child_tree.commit(message='merged')
266
# After binding, the revision history should be unaltered
268
base_history = base_branch.revision_history()
269
child_history = child_branch.revision_history()
222
self.check_revno(3, 'child')
223
self.assertEquals(child_tree.branch.last_revision(),
224
base_tree.branch.last_revision())
271
226
def test_bind_parent_ahead(self):
272
227
base_tree = self.create_branches()[0]
275
self.run_bzr('unbind')
229
self.run_bzr('unbind', working_dir='child')
277
231
base_tree.commit(message='base', allow_pointless=True)
280
self.run_bzr('bind ../base')
233
self.check_revno(1, 'child')
234
self.run_bzr('bind ../base', working_dir='child')
282
236
# binding does not pull data:
284
self.run_bzr('unbind')
237
self.check_revno(1, 'child')
238
self.run_bzr('unbind', working_dir='child')
286
240
# Check and make sure it also works if parent is ahead multiple
287
241
base_tree.commit(message='base 3', allow_pointless=True)
288
242
base_tree.commit(message='base 4', allow_pointless=True)
289
243
base_tree.commit(message='base 5', allow_pointless=True)
290
self.check_revno(5, '../base')
244
self.check_revno(5, 'base')
293
self.run_bzr('bind ../base')
246
self.check_revno(1, 'child')
247
self.run_bzr('bind ../base', working_dir='child')
248
self.check_revno(1, 'child')
296
250
def test_bind_child_ahead(self):
297
251
# test binding when the master branches history is a prefix of the
300
254
child_tree = self.create_branches()[1]
303
self.run_bzr('unbind')
256
self.run_bzr('unbind', working_dir='child')
257
# Refresh the child tree/branch objects as 'bind' modified them
258
child_tree = child_tree.bzrdir.open_workingtree()
304
259
child_tree.commit(message='child', allow_pointless=True)
306
self.check_revno(1, '../base')
260
self.check_revno(2, 'child')
261
self.check_revno(1, 'base')
308
self.run_bzr('bind ../base')
309
self.check_revno(1, '../base')
263
self.run_bzr('bind ../base', working_dir='child')
264
self.check_revno(1, 'base')
311
266
# Check and make sure it also works if child is ahead multiple
312
self.run_bzr('unbind')
267
self.run_bzr('unbind', working_dir='child')
313
268
child_tree.commit(message='child 3', allow_pointless=True)
314
269
child_tree.commit(message='child 4', allow_pointless=True)
315
270
child_tree.commit(message='child 5', allow_pointless=True)
271
self.check_revno(5, 'child')
318
self.check_revno(1, '../base')
319
self.run_bzr('bind ../base')
320
self.check_revno(1, '../base')
273
self.check_revno(1, 'base')
274
self.run_bzr('bind ../base', working_dir='child')
275
self.check_revno(1, 'base')
322
277
def test_bind_fail_if_missing(self):
323
278
"""We should not be able to bind to a missing branch."""
324
279
tree = self.make_branch_and_tree('tree_1')
325
280
tree.commit('dummy commit')
326
self.run_bzr_error(['Not a branch.*no-such-branch/'], ['bind', '../no-such-branch'],
327
working_dir='tree_1')
281
self.run_bzr_error(['Not a branch.*no-such-branch/'],
282
['bind', '../no-such-branch'],
283
working_dir='tree_1')
328
284
self.assertIs(None, tree.branch.get_bound_location())
330
def test_bind_nick(self):
331
"""Bind should not update implicit nick."""
332
base = self.make_branch_and_tree('base')
333
child = self.make_branch_and_tree('child')
335
self.assertEqual(child.branch.nick, 'child')
336
self.assertEqual(child.branch.get_config().has_explicit_nickname(),
338
self.run_bzr('bind ../base')
339
self.assertEqual(child.branch.nick, base.branch.nick)
340
self.assertEqual(child.branch.get_config().has_explicit_nickname(),
343
def test_bind_explicit_nick(self):
344
"""Bind should update explicit nick."""
345
base = self.make_branch_and_tree('base')
346
child = self.make_branch_and_tree('child')
348
child.branch.nick = "explicit_nick"
349
self.assertEqual(child.branch.nick, "explicit_nick")
350
self.assertEqual(child.branch.get_config()._get_explicit_nickname(),
352
self.run_bzr('bind ../base')
353
self.assertEqual(child.branch.nick, base.branch.nick)
354
self.assertEqual(child.branch.get_config()._get_explicit_nickname(),
357
286
def test_commit_after_merge(self):
358
287
base_tree, child_tree = self.create_branches()
383
312
# Commit should succeed, and cause merged revisions to
384
313
# be pulled into base
386
self.run_bzr(['commit', '-m', 'merge other'])
390
self.check_revno(2, '../base')
314
self.run_bzr(['commit', '-m', 'merge other'], working_dir='child')
315
self.check_revno(2, 'child')
316
self.check_revno(2, 'base')
392
317
self.assertTrue(base_tree.branch.repository.has_revision(new_rev_id))
394
319
def test_pull_overwrite(self):
415
340
self.check_revno(2, 'child')
416
341
self.check_revno(2, 'base')
419
self.run_bzr('pull --overwrite ../other')
343
self.run_bzr('pull --overwrite ../other', working_dir='child')
421
345
# both the local and master should have been updated.
423
self.check_revno(4, '../base')
346
self.check_revno(4, 'child')
347
self.check_revno(4, 'base')
425
349
def test_bind_directory(self):
426
350
"""Test --directory option"""