~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/blackbox/test_bound_branches.py

  • Committer: Andrew Bennetts
  • Date: 2010-10-08 08:15:14 UTC
  • mto: This revision was merged to the branch mainline in revision 5498.
  • Revision ID: andrew.bennetts@canonical.com-20101008081514-dviqzrdfwyzsqbz2
Split NEWS into per-release doc/en/release-notes/bzr-*.txt

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2012, 2016 Canonical Ltd
 
1
# Copyright (C) 2005-2010 Canonical Ltd
2
2
#
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
17
17
 
18
18
"""Tests of bound branches (binding, unbinding, commit, etc) command."""
19
19
 
 
20
import os
 
21
from cStringIO import StringIO
 
22
 
20
23
from bzrlib import (
21
 
    branch,
22
 
    controldir,
 
24
    bzrdir,
23
25
    errors,
24
26
    tests,
25
27
    )
 
28
from bzrlib.branch import Branch
 
29
from bzrlib.bzrdir import (BzrDir, BzrDirFormat, BzrDirMetaFormat1)
 
30
from bzrlib.osutils import getcwd
26
31
from bzrlib.tests import script
 
32
import bzrlib.urlutils as urlutils
 
33
from bzrlib.workingtree import WorkingTree
 
34
 
 
35
 
 
36
class TestLegacyFormats(tests.TestCaseWithTransport):
 
37
 
 
38
    def setUp(self):
 
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'))
 
44
        os.chdir('child')
 
45
 
 
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)
 
55
 
 
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)
27
63
 
28
64
 
29
65
class TestBoundBranches(tests.TestCaseWithTransport):
35
71
        base_tree.add(['a', 'b'])
36
72
        base_tree.commit('init')
37
73
        base_tree.unlock()
 
74
        branch = base_tree.branch
38
75
 
39
 
        child_tree = base_tree.branch.create_checkout('child')
 
76
        child_tree = branch.create_checkout('child')
40
77
 
41
78
        self.check_revno(1, 'child')
42
 
        d = controldir.ControlDir.open('child')
 
79
        d = BzrDir.open('child')
43
80
        self.assertNotEqual(None, d.open_branch().get_master_branch())
44
81
 
45
82
        return base_tree, child_tree
46
83
 
47
84
    def check_revno(self, val, loc='.'):
48
85
        self.assertEqual(
49
 
            val, controldir.ControlDir.open(loc).open_branch().last_revision_info()[0])
 
86
            val, len(BzrDir.open(loc).open_branch().revision_history()))
50
87
 
51
88
    def test_simple_binding(self):
52
89
        tree = self.make_branch_and_tree('base')
53
90
        self.build_tree(['base/a', 'base/b'])
54
91
        tree.add('a', 'b')
55
92
        tree.commit(message='init')
 
93
        branch = tree.branch
56
94
 
57
95
        tree.bzrdir.sprout('child')
58
96
 
59
 
        self.run_bzr('bind ../base', working_dir='child')
 
97
        os.chdir('child')
 
98
        self.run_bzr('bind ../base')
60
99
 
61
 
        d = controldir.ControlDir.open('child')
 
100
        d = BzrDir.open('')
62
101
        self.assertNotEqual(None, d.open_branch().get_master_branch())
63
102
 
64
 
        self.run_bzr('unbind', working_dir='child')
 
103
        self.run_bzr('unbind')
65
104
        self.assertEqual(None, d.open_branch().get_master_branch())
66
105
 
67
 
        self.run_bzr('unbind', retcode=3, working_dir='child')
 
106
        self.run_bzr('unbind', retcode=3)
68
107
 
69
108
    def test_bind_branch6(self):
70
109
        branch1 = self.make_branch('branch1', format='dirstate-tags')
71
 
        error = self.run_bzr('bind', retcode=3, working_dir='branch1')[1]
72
 
        self.assertEndsWith(
73
 
            error, 'No location supplied and no previous location known\n')
 
110
        os.chdir('branch1')
 
111
        error = self.run_bzr('bind', retcode=3)[1]
 
112
        self.assertContainsRe(error, 'no previous location known')
74
113
 
75
114
    def setup_rebind(self, format):
76
115
        branch1 = self.make_branch('branch1')
80
119
 
81
120
    def test_rebind_branch6(self):
82
121
        self.setup_rebind('dirstate-tags')
83
 
        self.run_bzr('bind', working_dir='branch2')
84
 
        b = branch.Branch.open('branch2')
85
 
        self.assertEndsWith(b.get_bound_location(), '/branch1/')
 
122
        os.chdir('branch2')
 
123
        self.run_bzr('bind')
 
124
        b = Branch.open('.')
 
125
        self.assertContainsRe(b.get_bound_location(), '\/branch1\/$')
86
126
 
87
127
    def test_rebind_branch5(self):
88
128
        self.setup_rebind('knit')
89
 
        error = self.run_bzr('bind', retcode=3, working_dir='branch2')[1]
90
 
        self.assertEndsWith(
91
 
            error, 'No location supplied.  This format does not remember'
92
 
            ' old locations.\n')
 
129
        os.chdir('branch2')
 
130
        error = self.run_bzr('bind', retcode=3)[1]
 
131
        self.assertContainsRe(error, 'old locations')
93
132
 
94
133
    def test_bound_commit(self):
95
134
        child_tree = self.create_branches()[1]
126
165
 
127
166
    def test_double_binding(self):
128
167
        child_tree = self.create_branches()[1]
129
 
        child_tree.bzrdir.sprout('child2')
130
 
 
 
168
 
 
169
        child2_tree = child_tree.bzrdir.sprout('child2').open_workingtree()
 
170
 
 
171
        os.chdir('child2')
131
172
        # Double binding succeeds, but committing to child2 should fail
132
 
        self.run_bzr('bind ../child', working_dir='child2')
 
173
        self.run_bzr('bind ../child')
133
174
 
134
 
        # Refresh the child tree object as 'unbind' modified it
135
 
        child2_tree = controldir.ControlDir.open('child2').open_workingtree()
136
175
        self.assertRaises(errors.CommitToDoubleBoundBranch,
137
176
                child2_tree.commit, message='child2', allow_pointless=True)
138
177
 
147
186
        self.check_revno(2, 'base')
148
187
 
149
188
        self.check_revno(1, 'child')
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()
 
189
        os.chdir('child')
 
190
        self.run_bzr("commit -m child", retcode=3)
 
191
        self.check_revno(1)
 
192
        self.run_bzr('unbind')
155
193
        child_tree.commit(message='child')
156
 
        self.check_revno(2, 'child')
 
194
        self.check_revno(2)
157
195
 
158
196
    def test_commit_remote_bound(self):
159
197
        # It is not possible to commit to a branch
161
199
        base_tree, child_tree = self.create_branches()
162
200
        base_tree.bzrdir.sprout('newbase')
163
201
 
 
202
        os.chdir('base')
164
203
        # There is no way to know that B has already
165
204
        # been bound by someone else, otherwise it
166
205
        # might be nice if this would fail
167
 
        self.run_bzr('bind ../newbase', working_dir='base')
 
206
        self.run_bzr('bind ../newbase')
168
207
 
169
 
        self.run_bzr('commit -m failure --unchanged', retcode=3,
170
 
                     working_dir='child')
 
208
        os.chdir('../child')
 
209
        self.run_bzr('commit -m failure --unchanged', retcode=3)
171
210
 
172
211
    def test_pull_updates_both(self):
173
212
        base_tree = self.create_branches()[0]
176
215
        newchild_tree.commit(message='newchild')
177
216
        self.check_revno(2, 'newchild')
178
217
 
 
218
        os.chdir('child')
179
219
        # The pull should succeed, and update
180
220
        # the bound parent branch
181
 
        self.run_bzr('pull ../newchild', working_dir='child')
182
 
        self.check_revno(2, 'child')
183
 
        self.check_revno(2, 'base')
 
221
        self.run_bzr('pull ../newchild')
 
222
        self.check_revno(2)
 
223
 
 
224
        self.check_revno(2, '../base')
184
225
 
185
226
    def test_pull_local_updates_local(self):
186
227
        base_tree = self.create_branches()[0]
189
230
        newchild_tree.commit(message='newchild')
190
231
        self.check_revno(2, 'newchild')
191
232
 
 
233
        os.chdir('child')
192
234
        # The pull should succeed, and update
193
235
        # the bound parent branch
194
 
        self.run_bzr('pull ../newchild --local', working_dir='child')
195
 
        self.check_revno(2, 'child')
196
 
        self.check_revno(1, 'base')
 
236
        self.run_bzr('pull ../newchild --local')
 
237
        self.check_revno(2)
 
238
 
 
239
        self.check_revno(1, '../base')
197
240
 
198
241
    def test_bind_diverged(self):
199
242
        base_tree, child_tree = self.create_branches()
200
243
        base_branch = base_tree.branch
201
244
        child_branch = child_tree.branch
202
245
 
203
 
        self.run_bzr('unbind', working_dir='child')
 
246
        os.chdir('child')
 
247
        self.run_bzr('unbind')
204
248
 
205
 
        # Refresh the child tree/branch objects as 'unbind' modified them
206
 
        child_tree = child_tree.bzrdir.open_workingtree()
207
249
        child_tree.commit(message='child', allow_pointless=True)
208
 
        self.check_revno(2, 'child')
 
250
        self.check_revno(2)
209
251
 
 
252
        os.chdir('..')
210
253
        self.check_revno(1, 'base')
211
254
        base_tree.commit(message='base', allow_pointless=True)
212
255
        self.check_revno(2, 'base')
213
256
 
 
257
        os.chdir('child')
214
258
        # These branches have diverged, but bind should succeed anyway
215
 
        self.run_bzr('bind ../base', working_dir='child')
 
259
        self.run_bzr('bind ../base')
216
260
 
217
 
        # Refresh the child tree/branch objects as 'bind' modified them
218
 
        child_tree = child_tree.bzrdir.open_workingtree()
219
261
        # This should turn the local commit into a merge
220
262
        child_tree.update()
221
263
        child_tree.commit(message='merged')
222
 
        self.check_revno(3, 'child')
223
 
        self.assertEqual(child_tree.branch.last_revision(),
224
 
                          base_tree.branch.last_revision())
 
264
        self.check_revno(3)
 
265
 
 
266
        # After binding, the revision history should be unaltered
 
267
        # take a copy before
 
268
        base_history = base_branch.revision_history()
 
269
        child_history = child_branch.revision_history()
225
270
 
226
271
    def test_bind_parent_ahead(self):
227
272
        base_tree = self.create_branches()[0]
228
273
 
229
 
        self.run_bzr('unbind', working_dir='child')
 
274
        os.chdir('child')
 
275
        self.run_bzr('unbind')
230
276
 
231
277
        base_tree.commit(message='base', allow_pointless=True)
232
278
 
233
 
        self.check_revno(1, 'child')
234
 
        self.run_bzr('bind ../base', working_dir='child')
 
279
        self.check_revno(1)
 
280
        self.run_bzr('bind ../base')
235
281
 
236
282
        # binding does not pull data:
237
 
        self.check_revno(1, 'child')
238
 
        self.run_bzr('unbind', working_dir='child')
 
283
        self.check_revno(1)
 
284
        self.run_bzr('unbind')
239
285
 
240
286
        # Check and make sure it also works if parent is ahead multiple
241
287
        base_tree.commit(message='base 3', allow_pointless=True)
242
288
        base_tree.commit(message='base 4', allow_pointless=True)
243
289
        base_tree.commit(message='base 5', allow_pointless=True)
244
 
        self.check_revno(5, 'base')
 
290
        self.check_revno(5, '../base')
245
291
 
246
 
        self.check_revno(1, 'child')
247
 
        self.run_bzr('bind ../base', working_dir='child')
248
 
        self.check_revno(1, 'child')
 
292
        self.check_revno(1)
 
293
        self.run_bzr('bind ../base')
 
294
        self.check_revno(1)
249
295
 
250
296
    def test_bind_child_ahead(self):
251
297
        # test binding when the master branches history is a prefix of the
253
299
        # be altered
254
300
        child_tree = self.create_branches()[1]
255
301
 
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()
 
302
        os.chdir('child')
 
303
        self.run_bzr('unbind')
259
304
        child_tree.commit(message='child', allow_pointless=True)
260
 
        self.check_revno(2, 'child')
261
 
        self.check_revno(1, 'base')
 
305
        self.check_revno(2)
 
306
        self.check_revno(1, '../base')
262
307
 
263
 
        self.run_bzr('bind ../base', working_dir='child')
264
 
        self.check_revno(1, 'base')
 
308
        self.run_bzr('bind ../base')
 
309
        self.check_revno(1, '../base')
265
310
 
266
311
        # Check and make sure it also works if child is ahead multiple
267
 
        self.run_bzr('unbind', working_dir='child')
 
312
        self.run_bzr('unbind')
268
313
        child_tree.commit(message='child 3', allow_pointless=True)
269
314
        child_tree.commit(message='child 4', allow_pointless=True)
270
315
        child_tree.commit(message='child 5', allow_pointless=True)
271
 
        self.check_revno(5, 'child')
 
316
        self.check_revno(5)
272
317
 
273
 
        self.check_revno(1, 'base')
274
 
        self.run_bzr('bind ../base', working_dir='child')
275
 
        self.check_revno(1, 'base')
 
318
        self.check_revno(1, '../base')
 
319
        self.run_bzr('bind ../base')
 
320
        self.check_revno(1, '../base')
276
321
 
277
322
    def test_bind_fail_if_missing(self):
278
323
        """We should not be able to bind to a missing branch."""
279
324
        tree = self.make_branch_and_tree('tree_1')
280
325
        tree.commit('dummy commit')
281
 
        self.run_bzr_error(['Not a branch.*no-such-branch/'],
282
 
                           ['bind', '../no-such-branch'],
283
 
                           working_dir='tree_1')
 
326
        self.run_bzr_error(['Not a branch.*no-such-branch/'], ['bind', '../no-such-branch'],
 
327
                            working_dir='tree_1')
284
328
        self.assertIs(None, tree.branch.get_bound_location())
285
329
 
 
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')
 
334
        os.chdir('child')
 
335
        self.assertEqual(child.branch.nick, 'child')
 
336
        self.assertEqual(child.branch.get_config().has_explicit_nickname(),
 
337
            False)
 
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(),
 
341
            False)
 
342
 
 
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')
 
347
        os.chdir('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(),
 
351
            "explicit_nick")
 
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(),
 
355
            base.branch.nick)
 
356
 
286
357
    def test_commit_after_merge(self):
287
358
        base_tree, child_tree = self.create_branches()
288
359
 
296
367
        self.build_tree_contents([('other/c', 'file c\n')])
297
368
        other_tree.add('c')
298
369
        other_tree.commit(message='adding c')
299
 
        new_rev_id = other_branch.last_revision()
 
370
        new_rev_id = other_branch.revision_history()[-1]
300
371
 
301
372
        child_tree.merge_from_branch(other_branch)
302
373
 
303
 
        self.assertPathExists('child/c')
 
374
        self.failUnlessExists('child/c')
304
375
        self.assertEqual([new_rev_id], child_tree.get_parent_ids()[1:])
305
376
 
306
377
        # Make sure the local branch has the installed revision
311
382
 
312
383
        # Commit should succeed, and cause merged revisions to
313
384
        # be pulled into base
314
 
        self.run_bzr(['commit', '-m', 'merge other'], working_dir='child')
315
 
        self.check_revno(2, 'child')
316
 
        self.check_revno(2, 'base')
 
385
        os.chdir('child')
 
386
        self.run_bzr(['commit', '-m', 'merge other'])
 
387
 
 
388
        self.check_revno(2)
 
389
 
 
390
        self.check_revno(2, '../base')
 
391
 
317
392
        self.assertTrue(base_tree.branch.repository.has_revision(new_rev_id))
318
393
 
319
394
    def test_pull_overwrite(self):
340
415
        self.check_revno(2, 'child')
341
416
        self.check_revno(2, 'base')
342
417
 
343
 
        self.run_bzr('pull --overwrite ../other', working_dir='child')
 
418
        os.chdir('child')
 
419
        self.run_bzr('pull --overwrite ../other')
344
420
 
345
421
        # both the local and master should have been updated.
346
 
        self.check_revno(4, 'child')
347
 
        self.check_revno(4, 'base')
 
422
        self.check_revno(4)
 
423
        self.check_revno(4, '../base')
348
424
 
349
425
    def test_bind_directory(self):
350
426
        """Test --directory option"""
355
431
        branch = tree.branch
356
432
        tree.bzrdir.sprout('child')
357
433
        self.run_bzr('bind --directory=child base')
358
 
        d = controldir.ControlDir.open('child')
 
434
        d = BzrDir.open('child')
359
435
        self.assertNotEqual(None, d.open_branch().get_master_branch())
360
436
        self.run_bzr('unbind -d child')
361
437
        self.assertEqual(None, d.open_branch().get_master_branch())
367
443
    def test_bind_when_bound(self):
368
444
        self.run_script("""
369
445
$ bzr init trunk
370
 
...
371
446
$ bzr init copy
372
 
...
373
447
$ cd copy
374
448
$ bzr bind ../trunk
375
449
$ bzr bind
379
453
    def test_bind_before_bound(self):
380
454
        self.run_script("""
381
455
$ bzr init trunk
382
 
...
383
456
$ cd trunk
384
457
$ bzr bind
385
458
2>bzr: ERROR: No location supplied and no previous location known