~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2008-09-03 22:30:56 UTC
  • mfrom: (3644.2.13 index_builder_cleanup)
  • Revision ID: pqm@pqm.ubuntu.com-20080903223056-b108iytb38xkznci
(jam) Streamline BTreeBuilder.add_node et al to make btree creation
        faster.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2012, 2016 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2008 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
12
12
#
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
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
 
18
18
"""Black-box tests for bzr branch."""
19
19
 
20
20
import os
21
21
 
22
 
from bzrlib import (
23
 
    branch,
24
 
    bzrdir,
25
 
    controldir,
26
 
    errors,
27
 
    revision as _mod_revision,
28
 
    tests,
29
 
    )
 
22
from bzrlib import (branch, bzrdir, errors, repository)
30
23
from bzrlib.repofmt.knitrepo import RepositoryFormatKnit1
31
 
from bzrlib.tests import (
32
 
    fixtures,
33
 
    test_server,
34
 
    )
35
 
from bzrlib.tests.features import (
36
 
    HardlinkFeature,
37
 
    )
38
 
from bzrlib.tests.blackbox import test_switch
39
 
from bzrlib.tests.matchers import ContainsNoVfsCalls
 
24
from bzrlib.tests.blackbox import ExternalBase
 
25
from bzrlib.tests import HardlinkFeature
40
26
from bzrlib.tests.test_sftp_transport import TestCaseWithSFTPServer
41
 
from bzrlib.tests.script import run_script
42
 
from bzrlib.urlutils import local_path_to_url, strip_trailing_slash
43
27
from bzrlib.workingtree import WorkingTree
44
28
 
45
29
 
46
 
class TestBranch(tests.TestCaseWithTransport):
 
30
class TestBranch(ExternalBase):
47
31
 
48
 
    def example_branch(self, path='.', format=None):
49
 
        tree = self.make_branch_and_tree(path, format=format)
 
32
    def example_branch(self, path='.'):
 
33
        tree = self.make_branch_and_tree(path)
50
34
        self.build_tree_contents([(path + '/hello', 'foo')])
51
35
        tree.add('hello')
52
36
        tree.commit(message='setup')
53
37
        self.build_tree_contents([(path + '/goodbye', 'baz')])
54
38
        tree.add('goodbye')
55
39
        tree.commit(message='setup')
56
 
        return tree
57
40
 
58
41
    def test_branch(self):
59
42
        """Branch from one branch to another."""
65
48
        self.assertFalse(b._transport.has('branch-name'))
66
49
        b.bzrdir.open_workingtree().commit(message='foo', allow_pointless=True)
67
50
 
68
 
    def test_branch_no_to_location(self):
69
 
        """The to_location is derived from the source branch name."""
70
 
        os.mkdir("something")
71
 
        a = self.example_branch('something/a').branch
72
 
        self.run_bzr('branch something/a')
73
 
        b = branch.Branch.open('a')
74
 
        self.assertEqual(b.last_revision_info(), a.last_revision_info())
75
 
 
76
 
    def test_into_colocated(self):
77
 
        """Branch from a branch into a colocated branch."""
78
 
        self.example_branch('a')
79
 
        out, err = self.run_bzr(
80
 
            'init --format=development-colo file:b,branch=orig')
81
 
        self.assertEqual(
82
 
            """Created a lightweight checkout (format: development-colo)\n""",
83
 
            out)
84
 
        self.assertEqual('', err)
85
 
        out, err = self.run_bzr(
86
 
            'branch a file:b,branch=thiswasa')
87
 
        self.assertEqual('', out)
88
 
        self.assertEqual('Branched 2 revisions.\n', err)
89
 
        out, err = self.run_bzr('branches b')
90
 
        self.assertEqual("  orig\n  thiswasa\n", out)
91
 
        self.assertEqual('', err)
92
 
        out,err = self.run_bzr('branch a file:b,branch=orig', retcode=3)
93
 
        self.assertEqual('', out)
94
 
        self.assertEqual(
95
 
            'bzr: ERROR: Already a branch: "file:b,branch=orig".\n', err)
96
 
 
97
 
    def test_from_colocated(self):
98
 
        """Branch from a colocated branch into a regular branch."""
99
 
        tree = self.example_branch('a', format='development-colo')
100
 
        tree.bzrdir.create_branch(name='somecolo')
101
 
        out, err = self.run_bzr('branch %s,branch=somecolo' %
102
 
            local_path_to_url('a'))
103
 
        self.assertEqual('', out)
104
 
        self.assertEqual('Branched 0 revisions.\n', err)
105
 
        self.assertPathExists("somecolo")
106
 
 
107
 
    def test_branch_broken_pack(self):
108
 
        """branching with a corrupted pack file."""
109
 
        self.example_branch('a')
110
 
        # add some corruption
111
 
        packs_dir = 'a/.bzr/repository/packs/'
112
 
        fname = packs_dir + os.listdir(packs_dir)[0]
113
 
        with open(fname, 'rb+') as f:
114
 
            # Start from the end of the file to avoid choosing a place bigger
115
 
            # than the file itself.
116
 
            f.seek(-5, os.SEEK_END)
117
 
            c = f.read(1)
118
 
            f.seek(-5, os.SEEK_END)
119
 
            # Make sure we inject a value different than the one we just read
120
 
            if c == '\xFF':
121
 
                corrupt = '\x00'
122
 
            else:
123
 
                corrupt = '\xFF'
124
 
            f.write(corrupt) # make sure we corrupt something
125
 
        self.run_bzr_error(['Corruption while decompressing repository file'],
126
 
                            'branch a b', retcode=3)
127
 
 
128
 
    def test_branch_switch_no_branch(self):
129
 
        # No branch in the current directory:
130
 
        #  => new branch will be created, but switch fails
131
 
        self.example_branch('a')
132
 
        self.make_repository('current')
133
 
        self.run_bzr_error(['No WorkingTree exists for'],
134
 
            'branch --switch ../a ../b', working_dir='current')
135
 
        a = branch.Branch.open('a')
136
 
        b = branch.Branch.open('b')
137
 
        self.assertEqual(a.last_revision(), b.last_revision())
138
 
 
139
 
    def test_branch_switch_no_wt(self):
140
 
        # No working tree in the current directory:
141
 
        #  => new branch will be created, but switch fails and the current
142
 
        #     branch is unmodified
143
 
        self.example_branch('a')
144
 
        self.make_branch('current')
145
 
        self.run_bzr_error(['No WorkingTree exists for'],
146
 
            'branch --switch ../a ../b', working_dir='current')
147
 
        a = branch.Branch.open('a')
148
 
        b = branch.Branch.open('b')
149
 
        self.assertEqual(a.last_revision(), b.last_revision())
150
 
        work = branch.Branch.open('current')
151
 
        self.assertEqual(work.last_revision(), _mod_revision.NULL_REVISION)
152
 
 
153
 
    def test_branch_switch_no_checkout(self):
154
 
        # Standalone branch in the current directory:
155
 
        #  => new branch will be created, but switch fails and the current
156
 
        #     branch is unmodified
157
 
        self.example_branch('a')
158
 
        tree = self.make_branch_and_tree('current')
159
 
        c1 = tree.commit('some diverged change')
160
 
        self.run_bzr_error(['Cannot switch a branch, only a checkout'],
161
 
            'branch --switch ../a ../b', working_dir='current')
162
 
        a = branch.Branch.open('a')
163
 
        b = branch.Branch.open('b')
164
 
        self.assertEqual(a.last_revision(), b.last_revision())
165
 
        work = branch.Branch.open('current')
166
 
        self.assertEqual(work.last_revision(), c1)
167
 
 
168
 
    def test_branch_into_empty_dir(self):
169
 
        t = self.example_branch('source')
170
 
        self.make_bzrdir('target')
171
 
        self.run_bzr("branch source target")
172
 
        self.assertEqual(2, len(t.branch.repository.all_revision_ids()))
173
 
 
174
 
    def test_branch_switch_checkout(self):
175
 
        # Checkout in the current directory:
176
 
        #  => new branch will be created and checkout bound to the new branch
177
 
        self.example_branch('a')
178
 
        self.run_bzr('checkout a current')
179
 
        out, err = self.run_bzr('branch --switch ../a ../b',
180
 
                                working_dir='current')
181
 
        a = branch.Branch.open('a')
182
 
        b = branch.Branch.open('b')
183
 
        self.assertEqual(a.last_revision(), b.last_revision())
184
 
        work = WorkingTree.open('current')
185
 
        self.assertEndsWith(work.branch.get_bound_location(), '/b/')
186
 
        self.assertContainsRe(err, "Switched to branch: .*/b/")
187
 
 
188
 
    def test_branch_switch_lightweight_checkout(self):
189
 
        # Lightweight checkout in the current directory:
190
 
        #  => new branch will be created and lightweight checkout pointed to
191
 
        #     the new branch
192
 
        self.example_branch('a')
193
 
        self.run_bzr('checkout --lightweight a current')
194
 
        out, err = self.run_bzr('branch --switch ../a ../b',
195
 
                                working_dir='current')
196
 
        a = branch.Branch.open('a')
197
 
        b = branch.Branch.open('b')
198
 
        self.assertEqual(a.last_revision(), b.last_revision())
199
 
        work = WorkingTree.open('current')
200
 
        self.assertEndsWith(work.branch.base, '/b/')
201
 
        self.assertContainsRe(err, "Switched to branch: .*/b/")
202
 
 
203
51
    def test_branch_only_copies_history(self):
204
52
        # Knit branches should only push the history for the current revision.
205
53
        format = bzrdir.BzrDirMetaFormat1()
209
57
 
210
58
        def make_shared_tree(path):
211
59
            shared_repo.bzrdir.root_transport.mkdir(path)
212
 
            controldir.ControlDir.create_branch_convenience('repo/' + path)
 
60
            shared_repo.bzrdir.create_branch_convenience('repo/' + path)
213
61
            return WorkingTree.open('repo/' + path)
214
62
        tree_a = make_shared_tree('a')
215
63
        self.build_tree(['repo/a/file'])
244
92
        self.build_tree(['source/file1'])
245
93
        source.add('file1')
246
94
        source.commit('added file')
247
 
        out, err = self.run_bzr(['branch', 'source', 'target', '--hardlink'])
 
95
        self.run_bzr(['branch', 'source', 'target', '--hardlink'])
248
96
        source_stat = os.stat('source/file1')
249
97
        target_stat = os.stat('target/file1')
250
98
        self.assertEqual(source_stat, target_stat)
251
99
 
252
 
    def test_branch_files_from(self):
253
 
        source = self.make_branch_and_tree('source')
254
 
        self.build_tree(['source/file1'])
255
 
        source.add('file1')
256
 
        source.commit('added file')
257
 
        out, err = self.run_bzr('branch source target --files-from source')
258
 
        self.assertPathExists('target/file1')
259
 
 
260
 
    def test_branch_files_from_hardlink(self):
261
 
        self.requireFeature(HardlinkFeature)
262
 
        source = self.make_branch_and_tree('source')
263
 
        self.build_tree(['source/file1'])
264
 
        source.add('file1')
265
 
        source.commit('added file')
266
 
        source.bzrdir.sprout('second')
267
 
        out, err = self.run_bzr('branch source target --files-from second'
268
 
                                ' --hardlink')
269
 
        source_stat = os.stat('source/file1')
270
 
        second_stat = os.stat('second/file1')
271
 
        target_stat = os.stat('target/file1')
272
 
        self.assertNotEqual(source_stat, target_stat)
273
 
        self.assertEqual(second_stat, target_stat)
274
 
 
275
 
    def test_branch_standalone(self):
276
 
        shared_repo = self.make_repository('repo', shared=True)
277
 
        self.example_branch('source')
278
 
        self.run_bzr('branch --standalone source repo/target')
279
 
        b = branch.Branch.open('repo/target')
280
 
        expected_repo_path = os.path.abspath('repo/target/.bzr/repository')
281
 
        self.assertEqual(strip_trailing_slash(b.repository.base),
282
 
            strip_trailing_slash(local_path_to_url(expected_repo_path)))
283
 
 
284
 
    def test_branch_no_tree(self):
285
 
        self.example_branch('source')
286
 
        self.run_bzr('branch --no-tree source target')
287
 
        self.assertPathDoesNotExist('target/hello')
288
 
        self.assertPathDoesNotExist('target/goodbye')
289
 
 
290
 
    def test_branch_into_existing_dir(self):
291
 
        self.example_branch('a')
292
 
        # existing dir with similar files but no .bzr dir
293
 
        self.build_tree_contents([('b/',)])
294
 
        self.build_tree_contents([('b/hello', 'bar')])  # different content
295
 
        self.build_tree_contents([('b/goodbye', 'baz')])# same content
296
 
        # fails without --use-existing-dir
297
 
        out,err = self.run_bzr('branch a b', retcode=3)
298
 
        self.assertEqual('', out)
299
 
        self.assertEqual('bzr: ERROR: Target directory "b" already exists.\n',
300
 
            err)
301
 
        # force operation
302
 
        self.run_bzr('branch a b --use-existing-dir')
303
 
        # check conflicts
304
 
        self.assertPathExists('b/hello.moved')
305
 
        self.assertPathDoesNotExist('b/godbye.moved')
306
 
        # we can't branch into branch
307
 
        out,err = self.run_bzr('branch a b --use-existing-dir', retcode=3)
308
 
        self.assertEqual('', out)
309
 
        self.assertEqual('bzr: ERROR: Already a branch: "b".\n', err)
310
 
 
311
 
    def test_branch_bind(self):
312
 
        self.example_branch('a')
313
 
        out, err = self.run_bzr('branch a b --bind')
314
 
        self.assertEndsWith(err, "New branch bound to a\n")
315
 
        b = branch.Branch.open('b')
316
 
        self.assertEndsWith(b.get_bound_location(), '/a/')
317
 
 
318
 
    def test_branch_with_post_branch_init_hook(self):
319
 
        calls = []
320
 
        branch.Branch.hooks.install_named_hook('post_branch_init',
321
 
            calls.append, None)
322
 
        self.assertLength(0, calls)
323
 
        self.example_branch('a')
324
 
        self.assertLength(1, calls)
325
 
        self.run_bzr('branch a b')
326
 
        self.assertLength(2, calls)
327
 
 
328
 
    def test_checkout_with_post_branch_init_hook(self):
329
 
        calls = []
330
 
        branch.Branch.hooks.install_named_hook('post_branch_init',
331
 
            calls.append, None)
332
 
        self.assertLength(0, calls)
333
 
        self.example_branch('a')
334
 
        self.assertLength(1, calls)
335
 
        self.run_bzr('checkout a b')
336
 
        self.assertLength(2, calls)
337
 
 
338
 
    def test_lightweight_checkout_with_post_branch_init_hook(self):
339
 
        calls = []
340
 
        branch.Branch.hooks.install_named_hook('post_branch_init',
341
 
            calls.append, None)
342
 
        self.assertLength(0, calls)
343
 
        self.example_branch('a')
344
 
        self.assertLength(1, calls)
345
 
        self.run_bzr('checkout --lightweight a b')
346
 
        self.assertLength(2, calls)
347
 
 
348
 
    def test_branch_fetches_all_tags(self):
349
 
        builder = self.make_branch_builder('source')
350
 
        source = fixtures.build_branch_with_non_ancestral_rev(builder)
351
 
        source.tags.set_tag('tag-a', 'rev-2')
352
 
        source.get_config_stack().set('branch.fetch_tags', True)
353
 
        # Now source has a tag not in its ancestry.  Make a branch from it.
354
 
        self.run_bzr('branch source new-branch')
355
 
        new_branch = branch.Branch.open('new-branch')
356
 
        # The tag is present, and so is its revision.
357
 
        self.assertEqual('rev-2', new_branch.tags.lookup_tag('tag-a'))
358
 
        new_branch.repository.get_revision('rev-2')
359
 
 
360
 
 
361
 
class TestBranchStacked(tests.TestCaseWithTransport):
 
100
 
 
101
class TestBranchStacked(ExternalBase):
362
102
    """Tests for branch --stacked"""
363
103
 
 
104
    def check_shallow_branch(self, branch_revid, stacked_on):
 
105
        """Assert that the branch 'newbranch' has been published correctly.
 
106
 
 
107
        :param stacked_on: url of a branch this one is stacked upon.
 
108
        :param branch_revid: a revision id that should be the only
 
109
            revision present in the stacked branch, and it should not be in
 
110
            the reference branch.
 
111
        """
 
112
        new_branch = branch.Branch.open('newbranch')
 
113
        # The branch refers to the mainline
 
114
        self.assertEqual(stacked_on, new_branch.get_stacked_on_url())
 
115
        # and the branch's work was pushed
 
116
        self.assertTrue(new_branch.repository.has_revision(branch_revid))
 
117
        # The newly committed revision shoud be present in the stacked branch,
 
118
        # but not in the stacked-on branch.  Because stacking is set up by the
 
119
        # branch object, if we open the stacked branch's repository directly,
 
120
        # bypassing the branch, we see only what's in the stacked repository.
 
121
        stacked_repo = bzrdir.BzrDir.open('newbranch').open_repository()
 
122
        stacked_repo_revisions = set(stacked_repo.all_revision_ids())
 
123
        if len(stacked_repo_revisions) != 1:
 
124
            self.fail("wrong revisions in stacked repository: %r"
 
125
                % (stacked_repo_revisions,))
 
126
 
364
127
    def assertRevisionInRepository(self, repo_path, revid):
365
 
        """Check that a revision is in a repo, disregarding stacking."""
366
 
        repo = controldir.ControlDir.open(repo_path).open_repository()
 
128
        """Check that a revision is in a repository, disregarding stacking."""
 
129
        repo = bzrdir.BzrDir.open(repo_path).open_repository()
367
130
        self.assertTrue(repo.has_revision(revid))
368
131
 
369
132
    def assertRevisionNotInRepository(self, repo_path, revid):
370
 
        """Check that a revision is not in a repo, disregarding stacking."""
371
 
        repo = controldir.ControlDir.open(repo_path).open_repository()
 
133
        """Check that a revision is not in a repository, disregarding stacking."""
 
134
        repo = bzrdir.BzrDir.open(repo_path).open_repository()
372
135
        self.assertFalse(repo.has_revision(revid))
373
136
 
374
137
    def assertRevisionsInBranchRepository(self, revid_list, branch_path):
380
143
        """Branching a stacked branch is not stacked by default"""
381
144
        # We have a mainline
382
145
        trunk_tree = self.make_branch_and_tree('target',
383
 
            format='1.9')
 
146
            format='development')
384
147
        trunk_tree.commit('mainline')
385
148
        # and a branch from it which is stacked
386
149
        branch_tree = self.make_branch_and_tree('branch',
387
 
            format='1.9')
 
150
            format='development')
388
151
        branch_tree.branch.set_stacked_on_url(trunk_tree.branch.base)
389
152
        # with some work on it
390
 
        work_tree = trunk_tree.branch.bzrdir.sprout('local').open_workingtree()
391
 
        work_tree.commit('moar work plz')
392
 
        work_tree.branch.push(branch_tree.branch)
 
153
        branch_tree.commit('moar work plz')
393
154
        # branching our local branch gives us a new stacked branch pointing at
394
155
        # mainline.
395
156
        out, err = self.run_bzr(['branch', 'branch', 'newbranch'])
396
157
        self.assertEqual('', out)
397
 
        self.assertEqual('Branched 2 revisions.\n',
 
158
        self.assertEqual('Branched 1 revision(s).\n',
398
159
            err)
399
160
        # it should have preserved the branch format, and so it should be
400
161
        # capable of supporting stacking, but not actually have a stacked_on
401
162
        # branch configured
402
163
        self.assertRaises(errors.NotStacked,
403
 
            controldir.ControlDir.open('newbranch').open_branch().get_stacked_on_url)
 
164
            bzrdir.BzrDir.open('newbranch').open_branch().get_stacked_on_url)
404
165
 
405
166
    def test_branch_stacked_branch_stacked(self):
406
167
        """Asking to stack on a stacked branch does work"""
407
168
        # We have a mainline
408
169
        trunk_tree = self.make_branch_and_tree('target',
409
 
            format='1.9')
 
170
            format='development')
410
171
        trunk_revid = trunk_tree.commit('mainline')
411
172
        # and a branch from it which is stacked
412
173
        branch_tree = self.make_branch_and_tree('branch',
413
 
            format='1.9')
 
174
            format='development')
414
175
        branch_tree.branch.set_stacked_on_url(trunk_tree.branch.base)
415
176
        # with some work on it
416
 
        work_tree = trunk_tree.branch.bzrdir.sprout('local').open_workingtree()
417
 
        branch_revid = work_tree.commit('moar work plz')
418
 
        work_tree.branch.push(branch_tree.branch)
 
177
        branch_revid = branch_tree.commit('moar work plz')
419
178
        # you can chain branches on from there
420
179
        out, err = self.run_bzr(['branch', 'branch', '--stacked', 'branch2'])
421
180
        self.assertEqual('', out)
424
183
        self.assertEqual(branch_tree.branch.base,
425
184
            branch.Branch.open('branch2').get_stacked_on_url())
426
185
        branch2_tree = WorkingTree.open('branch2')
427
 
        branch2_revid = work_tree.commit('work on second stacked branch')
428
 
        work_tree.branch.push(branch2_tree.branch)
 
186
        branch2_revid = branch2_tree.commit('work on second stacked branch')
429
187
        self.assertRevisionInRepository('branch2', branch2_revid)
430
188
        self.assertRevisionsInBranchRepository(
431
189
            [trunk_revid, branch_revid, branch2_revid],
434
192
    def test_branch_stacked(self):
435
193
        # We have a mainline
436
194
        trunk_tree = self.make_branch_and_tree('mainline',
437
 
            format='1.9')
 
195
            format='development')
438
196
        original_revid = trunk_tree.commit('mainline')
439
197
        self.assertRevisionInRepository('mainline', original_revid)
440
198
        # and a branch from it which is stacked
444
202
        self.assertEqual('Created new stacked branch referring to %s.\n' %
445
203
            trunk_tree.branch.base, err)
446
204
        self.assertRevisionNotInRepository('newbranch', original_revid)
447
 
        new_branch = branch.Branch.open('newbranch')
448
 
        self.assertEqual(trunk_tree.branch.base,
449
 
                         new_branch.get_stacked_on_url())
 
205
        new_tree = WorkingTree.open('newbranch')
 
206
        new_revid = new_tree.commit('new work')
 
207
        self.check_shallow_branch(new_revid, trunk_tree.branch.base)
450
208
 
451
209
    def test_branch_stacked_from_smart_server(self):
452
210
        # We can branch stacking on a smart server
453
 
        self.transport_server = test_server.SmartTCPServer_for_testing
454
 
        trunk = self.make_branch('mainline', format='1.9')
 
211
        from bzrlib.smart.server import SmartTCPServer_for_testing
 
212
        self.transport_server = SmartTCPServer_for_testing
 
213
        trunk = self.make_branch('mainline', format='development')
455
214
        out, err = self.run_bzr(
456
215
            ['branch', '--stacked', self.get_url('mainline'), 'shallow'])
457
216
 
462
221
            ['branch', '--stacked', 'trunk', 'shallow'])
463
222
        # We should notify the user that we upgraded their format
464
223
        self.assertEqualDiff(
465
 
            'Source repository format does not support stacking, using format:\n'
 
224
            'Source format does not support stacking, using format: \'1.6\'\n'
466
225
            '  Packs 5 (adds stacking support, requires bzr 1.6)\n'
467
 
            'Source branch format does not support stacking, using format:\n'
468
 
            '  Branch format 7\n'
469
 
            'Doing on-the-fly conversion from RepositoryFormatKnitPack1() to RepositoryFormatKnitPack5().\n'
470
 
            'This may take some time. Upgrade the repositories to the same format for better performance.\n'
 
226
            '\n'
471
227
            'Created new stacked branch referring to %s.\n' % (trunk.base,),
472
228
            err)
473
229
 
477
233
            ['branch', '--stacked', 'trunk', 'shallow'])
478
234
        # We should notify the user that we upgraded their format
479
235
        self.assertEqualDiff(
480
 
            'Source repository format does not support stacking, using format:\n'
 
236
            'Source format does not support stacking, using format:'
 
237
            ' \'1.6.1-rich-root\'\n'
481
238
            '  Packs 5 rich-root (adds stacking support, requires bzr 1.6.1)\n'
482
 
            'Source branch format does not support stacking, using format:\n'
483
 
            '  Branch format 7\n'
484
 
            'Doing on-the-fly conversion from RepositoryFormatKnitPack4() to RepositoryFormatKnitPack5RichRoot().\n'
485
 
            'This may take some time. Upgrade the repositories to the same format for better performance.\n'
 
239
            '\n'
486
240
            'Created new stacked branch referring to %s.\n' % (trunk.base,),
487
241
            err)
488
242
 
489
243
 
490
 
class TestSmartServerBranching(tests.TestCaseWithTransport):
491
 
 
492
 
    def test_branch_from_trivial_branch_to_same_server_branch_acceptance(self):
493
 
        self.setup_smart_server_with_call_log()
494
 
        t = self.make_branch_and_tree('from')
495
 
        for count in range(9):
496
 
            t.commit(message='commit %d' % count)
497
 
        self.reset_smart_call_log()
498
 
        out, err = self.run_bzr(['branch', self.get_url('from'),
499
 
            self.get_url('target')])
500
 
        # This figure represent the amount of work to perform this use case. It
501
 
        # is entirely ok to reduce this number if a test fails due to rpc_count
502
 
        # being too low. If rpc_count increases, more network roundtrips have
503
 
        # become necessary for this use case. Please do not adjust this number
504
 
        # upwards without agreement from bzr's network support maintainers.
505
 
        self.assertLength(2, self.hpss_connections)
506
 
        self.assertLength(33, self.hpss_calls)
507
 
        self.expectFailure("branching to the same branch requires VFS access",
508
 
            self.assertThat, self.hpss_calls, ContainsNoVfsCalls)
509
 
 
510
 
    def test_branch_from_trivial_branch_streaming_acceptance(self):
511
 
        self.setup_smart_server_with_call_log()
512
 
        t = self.make_branch_and_tree('from')
513
 
        for count in range(9):
514
 
            t.commit(message='commit %d' % count)
515
 
        self.reset_smart_call_log()
516
 
        out, err = self.run_bzr(['branch', self.get_url('from'),
517
 
            'local-target'])
518
 
        # This figure represent the amount of work to perform this use case. It
519
 
        # is entirely ok to reduce this number if a test fails due to rpc_count
520
 
        # being too low. If rpc_count increases, more network roundtrips have
521
 
        # become necessary for this use case. Please do not adjust this number
522
 
        # upwards without agreement from bzr's network support maintainers.
523
 
        self.assertThat(self.hpss_calls, ContainsNoVfsCalls)
524
 
        self.assertLength(10, self.hpss_calls)
525
 
        self.assertLength(1, self.hpss_connections)
526
 
 
527
 
    def test_branch_from_trivial_stacked_branch_streaming_acceptance(self):
528
 
        self.setup_smart_server_with_call_log()
529
 
        t = self.make_branch_and_tree('trunk')
530
 
        for count in range(8):
531
 
            t.commit(message='commit %d' % count)
532
 
        tree2 = t.branch.bzrdir.sprout('feature', stacked=True
533
 
            ).open_workingtree()
534
 
        local_tree = t.branch.bzrdir.sprout('local-working').open_workingtree()
535
 
        local_tree.commit('feature change')
536
 
        local_tree.branch.push(tree2.branch)
537
 
        self.reset_smart_call_log()
538
 
        out, err = self.run_bzr(['branch', self.get_url('feature'),
539
 
            'local-target'])
540
 
        # This figure represent the amount of work to perform this use case. It
541
 
        # is entirely ok to reduce this number if a test fails due to rpc_count
542
 
        # being too low. If rpc_count increases, more network roundtrips have
543
 
        # become necessary for this use case. Please do not adjust this number
544
 
        # upwards without agreement from bzr's network support maintainers.
545
 
        self.assertLength(15, self.hpss_calls)
546
 
        self.assertLength(1, self.hpss_connections)
547
 
        self.assertThat(self.hpss_calls, ContainsNoVfsCalls)
548
 
 
549
 
    def test_branch_from_branch_with_tags(self):
550
 
        self.setup_smart_server_with_call_log()
551
 
        builder = self.make_branch_builder('source')
552
 
        source = fixtures.build_branch_with_non_ancestral_rev(builder)
553
 
        source.get_config_stack().set('branch.fetch_tags', True)
554
 
        source.tags.set_tag('tag-a', 'rev-2')
555
 
        source.tags.set_tag('tag-missing', 'missing-rev')
556
 
        # Now source has a tag not in its ancestry.  Make a branch from it.
557
 
        self.reset_smart_call_log()
558
 
        out, err = self.run_bzr(['branch', self.get_url('source'), 'target'])
559
 
        # This figure represent the amount of work to perform this use case. It
560
 
        # is entirely ok to reduce this number if a test fails due to rpc_count
561
 
        # being too low. If rpc_count increases, more network roundtrips have
562
 
        # become necessary for this use case. Please do not adjust this number
563
 
        # upwards without agreement from bzr's network support maintainers.
564
 
        self.assertLength(10, self.hpss_calls)
565
 
        self.assertThat(self.hpss_calls, ContainsNoVfsCalls)
566
 
        self.assertLength(1, self.hpss_connections)
567
 
 
568
 
    def test_branch_to_stacked_from_trivial_branch_streaming_acceptance(self):
569
 
        self.setup_smart_server_with_call_log()
570
 
        t = self.make_branch_and_tree('from')
571
 
        for count in range(9):
572
 
            t.commit(message='commit %d' % count)
573
 
        self.reset_smart_call_log()
574
 
        out, err = self.run_bzr(['branch', '--stacked', self.get_url('from'),
575
 
            'local-target'])
576
 
        # XXX: the number of hpss calls for this case isn't deterministic yet,
577
 
        # so we can't easily assert about the number of calls.
578
 
        #self.assertLength(XXX, self.hpss_calls)
579
 
        # We can assert that none of the calls were readv requests for rix
580
 
        # files, though (demonstrating that at least get_parent_map calls are
581
 
        # not using VFS RPCs).
582
 
        readvs_of_rix_files = [
583
 
            c for c in self.hpss_calls
584
 
            if c.call.method == 'readv' and c.call.args[-1].endswith('.rix')]
585
 
        self.assertLength(1, self.hpss_connections)
586
 
        self.assertLength(0, readvs_of_rix_files)
587
 
        self.expectFailure("branching to stacked requires VFS access",
588
 
            self.assertThat, self.hpss_calls, ContainsNoVfsCalls)
589
 
 
590
244
 
591
245
class TestRemoteBranch(TestCaseWithSFTPServer):
592
246
 
611
265
        # Ensure that no working tree what created remotely
612
266
        self.assertFalse(t.has('remote/file'))
613
267
 
614
 
 
615
 
class TestDeprecatedAliases(tests.TestCaseWithTransport):
616
 
 
617
 
    def test_deprecated_aliases(self):
618
 
        """bzr branch can be called clone or get, but those names are
619
 
        deprecated.
620
 
 
621
 
        See bug 506265.
622
 
        """
623
 
        for command in ['clone', 'get']:
624
 
            run_script(self, """
625
 
            $ bzr %(command)s A B
626
 
            2>The command 'bzr %(command)s' has been deprecated in bzr 2.4. Please use 'bzr branch' instead.
627
 
            2>bzr: ERROR: Not a branch...
628
 
            """ % locals())
629
 
 
630
 
 
631
 
class TestBranchParentLocation(test_switch.TestSwitchParentLocationBase):
632
 
 
633
 
    def _checkout_and_branch(self, option=''):
634
 
        self.script_runner.run_script(self, '''
635
 
                $ bzr checkout %(option)s repo/trunk checkout
636
 
                $ cd checkout
637
 
                $ bzr branch --switch ../repo/trunk ../repo/branched
638
 
                2>Branched 0 revisions.
639
 
                2>Tree is up to date at revision 0.
640
 
                2>Switched to branch:...branched...
641
 
                $ cd ..
642
 
                ''' % locals())
643
 
        bound_branch = branch.Branch.open_containing('checkout')[0]
644
 
        master_branch = branch.Branch.open_containing('repo/branched')[0]
645
 
        return (bound_branch, master_branch)
646
 
 
647
 
    def test_branch_switch_parent_lightweight(self):
648
 
        """Lightweight checkout using bzr branch --switch."""
649
 
        bb, mb = self._checkout_and_branch(option='--lightweight')
650
 
        self.assertParent('repo/trunk', bb)
651
 
        self.assertParent('repo/trunk', mb)
652
 
 
653
 
    def test_branch_switch_parent_heavyweight(self):
654
 
        """Heavyweight checkout using bzr branch --switch."""
655
 
        bb, mb = self._checkout_and_branch()
656
 
        self.assertParent('repo/trunk', bb)
657
 
        self.assertParent('repo/trunk', mb)