~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: John Arbash Meinel
  • Date: 2010-05-11 10:45:26 UTC
  • mto: This revision was merged to the branch mainline in revision 5225.
  • Revision ID: john@arbash-meinel.com-20100511104526-zxnstcxta22hzw2n
Implement a compiled extension for parsing the text key out of a CHKInventory value.

Related to bug #562666. This seems to shave 5-10% out of the time spent doing a complete
branch of bzr.dev/launchpad/etc.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2008, 2009 Canonical Ltd
 
1
# Copyright (C) 2006-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
19
19
 
20
20
import os
21
21
 
22
 
from bzrlib import (branch, bzrdir, errors, repository)
 
22
from bzrlib import (
 
23
    branch,
 
24
    bzrdir,
 
25
    errors,
 
26
    repository,
 
27
    revision as _mod_revision,
 
28
    )
23
29
from bzrlib.repofmt.knitrepo import RepositoryFormatKnit1
24
30
from bzrlib.tests.blackbox import ExternalBase
25
 
from bzrlib.tests import HardlinkFeature
 
31
from bzrlib.tests import (
 
32
    KnownFailure,
 
33
    HardlinkFeature,
 
34
    test_server,
 
35
    )
26
36
from bzrlib.tests.test_sftp_transport import TestCaseWithSFTPServer
27
37
from bzrlib.urlutils import local_path_to_url, strip_trailing_slash
28
38
from bzrlib.workingtree import WorkingTree
49
59
        self.assertFalse(b._transport.has('branch-name'))
50
60
        b.bzrdir.open_workingtree().commit(message='foo', allow_pointless=True)
51
61
 
 
62
    def test_branch_switch_no_branch(self):
 
63
        # No branch in the current directory:
 
64
        #  => new branch will be created, but switch fails
 
65
        self.example_branch('a')
 
66
        self.make_repository('current')
 
67
        self.run_bzr_error(['No WorkingTree exists for'],
 
68
            'branch --switch ../a ../b', working_dir='current')
 
69
        a = branch.Branch.open('a')
 
70
        b = branch.Branch.open('b')
 
71
        self.assertEqual(a.last_revision(), b.last_revision())
 
72
 
 
73
    def test_branch_switch_no_wt(self):
 
74
        # No working tree in the current directory:
 
75
        #  => new branch will be created, but switch fails and the current
 
76
        #     branch is unmodified
 
77
        self.example_branch('a')
 
78
        self.make_branch('current')
 
79
        self.run_bzr_error(['No WorkingTree exists for'],
 
80
            'branch --switch ../a ../b', working_dir='current')
 
81
        a = branch.Branch.open('a')
 
82
        b = branch.Branch.open('b')
 
83
        self.assertEqual(a.last_revision(), b.last_revision())
 
84
        work = branch.Branch.open('current')
 
85
        self.assertEqual(work.last_revision(), _mod_revision.NULL_REVISION)
 
86
 
 
87
    def test_branch_switch_no_checkout(self):
 
88
        # Standalone branch in the current directory:
 
89
        #  => new branch will be created, but switch fails and the current
 
90
        #     branch is unmodified
 
91
        self.example_branch('a')
 
92
        self.make_branch_and_tree('current')
 
93
        self.run_bzr_error(['Cannot switch a branch, only a checkout'],
 
94
            'branch --switch ../a ../b', working_dir='current')
 
95
        a = branch.Branch.open('a')
 
96
        b = branch.Branch.open('b')
 
97
        self.assertEqual(a.last_revision(), b.last_revision())
 
98
        work = branch.Branch.open('current')
 
99
        self.assertEqual(work.last_revision(), _mod_revision.NULL_REVISION)
 
100
 
 
101
    def test_branch_switch_checkout(self):
 
102
        # Checkout in the current directory:
 
103
        #  => new branch will be created and checkout bound to the new branch
 
104
        self.example_branch('a')
 
105
        self.run_bzr('checkout a current')
 
106
        out, err = self.run_bzr('branch --switch ../a ../b', working_dir='current')
 
107
        a = branch.Branch.open('a')
 
108
        b = branch.Branch.open('b')
 
109
        self.assertEqual(a.last_revision(), b.last_revision())
 
110
        work = WorkingTree.open('current')
 
111
        self.assertEndsWith(work.branch.get_bound_location(), '/b/')
 
112
        self.assertContainsRe(err, "Switched to branch: .*/b/")
 
113
 
 
114
    def test_branch_switch_lightweight_checkout(self):
 
115
        # Lightweight checkout in the current directory:
 
116
        #  => new branch will be created and lightweight checkout pointed to
 
117
        #     the new branch
 
118
        self.example_branch('a')
 
119
        self.run_bzr('checkout --lightweight a current')
 
120
        out, err = self.run_bzr('branch --switch ../a ../b', working_dir='current')
 
121
        a = branch.Branch.open('a')
 
122
        b = branch.Branch.open('b')
 
123
        self.assertEqual(a.last_revision(), b.last_revision())
 
124
        work = WorkingTree.open('current')
 
125
        self.assertEndsWith(work.branch.base, '/b/')
 
126
        self.assertContainsRe(err, "Switched to branch: .*/b/")
 
127
 
52
128
    def test_branch_only_copies_history(self):
53
129
        # Knit branches should only push the history for the current revision.
54
130
        format = bzrdir.BzrDirMetaFormat1()
93
169
        self.build_tree(['source/file1'])
94
170
        source.add('file1')
95
171
        source.commit('added file')
96
 
        self.run_bzr(['branch', 'source', 'target', '--hardlink'])
 
172
        out, err = self.run_bzr(['branch', 'source', 'target', '--hardlink'])
97
173
        source_stat = os.stat('source/file1')
98
174
        target_stat = os.stat('target/file1')
99
175
        self.assertEqual(source_stat, target_stat)
134
210
        self.assertEqual('', out)
135
211
        self.assertEqual('bzr: ERROR: Already a branch: "b".\n', err)
136
212
 
 
213
    def test_branch_bind(self):
 
214
        self.example_branch('a')
 
215
        out, err = self.run_bzr('branch a b --bind')
 
216
        self.assertEndsWith(err, "New branch bound to a\n")
 
217
        b = branch.Branch.open('b')
 
218
        self.assertEndsWith(b.get_bound_location(), '/a/')
 
219
 
 
220
    def test_branch_with_post_branch_init_hook(self):
 
221
        calls = []
 
222
        branch.Branch.hooks.install_named_hook('post_branch_init',
 
223
            calls.append, None)
 
224
        self.assertLength(0, calls)
 
225
        self.example_branch('a')
 
226
        self.assertLength(1, calls)
 
227
        self.run_bzr('branch a b')
 
228
        self.assertLength(2, calls)
 
229
 
 
230
    def test_checkout_with_post_branch_init_hook(self):
 
231
        calls = []
 
232
        branch.Branch.hooks.install_named_hook('post_branch_init',
 
233
            calls.append, None)
 
234
        self.assertLength(0, calls)
 
235
        self.example_branch('a')
 
236
        self.assertLength(1, calls)
 
237
        self.run_bzr('checkout a b')
 
238
        self.assertLength(2, calls)
 
239
 
 
240
    def test_lightweight_checkout_with_post_branch_init_hook(self):
 
241
        calls = []
 
242
        branch.Branch.hooks.install_named_hook('post_branch_init',
 
243
            calls.append, None)
 
244
        self.assertLength(0, calls)
 
245
        self.example_branch('a')
 
246
        self.assertLength(1, calls)
 
247
        self.run_bzr('checkout --lightweight a b')
 
248
        self.assertLength(2, calls)
 
249
 
137
250
 
138
251
class TestBranchStacked(ExternalBase):
139
252
    """Tests for branch --stacked"""
140
253
 
141
 
    def check_shallow_branch(self, branch_revid, stacked_on):
142
 
        """Assert that the branch 'newbranch' has been published correctly.
143
 
 
144
 
        :param stacked_on: url of a branch this one is stacked upon.
145
 
        :param branch_revid: a revision id that should be the only
146
 
            revision present in the stacked branch, and it should not be in
147
 
            the reference branch.
148
 
        """
149
 
        new_branch = branch.Branch.open('newbranch')
150
 
        # The branch refers to the mainline
151
 
        self.assertEqual(stacked_on, new_branch.get_stacked_on_url())
152
 
        # and the branch's work was pushed
153
 
        self.assertTrue(new_branch.repository.has_revision(branch_revid))
154
 
        # The newly committed revision shoud be present in the stacked branch,
155
 
        # but not in the stacked-on branch.  Because stacking is set up by the
156
 
        # branch object, if we open the stacked branch's repository directly,
157
 
        # bypassing the branch, we see only what's in the stacked repository.
158
 
        stacked_repo = bzrdir.BzrDir.open('newbranch').open_repository()
159
 
        stacked_repo_revisions = set(stacked_repo.all_revision_ids())
160
 
        if len(stacked_repo_revisions) != 1:
161
 
            self.fail("wrong revisions in stacked repository: %r"
162
 
                % (stacked_repo_revisions,))
163
 
 
164
254
    def assertRevisionInRepository(self, repo_path, revid):
165
255
        """Check that a revision is in a repository, disregarding stacking."""
166
256
        repo = bzrdir.BzrDir.open(repo_path).open_repository()
187
277
            format='1.9')
188
278
        branch_tree.branch.set_stacked_on_url(trunk_tree.branch.base)
189
279
        # with some work on it
190
 
        branch_tree.commit('moar work plz')
 
280
        work_tree = trunk_tree.branch.bzrdir.sprout('local').open_workingtree()
 
281
        work_tree.commit('moar work plz')
 
282
        work_tree.branch.push(branch_tree.branch)
191
283
        # branching our local branch gives us a new stacked branch pointing at
192
284
        # mainline.
193
285
        out, err = self.run_bzr(['branch', 'branch', 'newbranch'])
194
286
        self.assertEqual('', out)
195
 
        self.assertEqual('Branched 1 revision(s).\n',
 
287
        self.assertEqual('Branched 2 revision(s).\n',
196
288
            err)
197
289
        # it should have preserved the branch format, and so it should be
198
290
        # capable of supporting stacking, but not actually have a stacked_on
211
303
            format='1.9')
212
304
        branch_tree.branch.set_stacked_on_url(trunk_tree.branch.base)
213
305
        # with some work on it
214
 
        branch_revid = branch_tree.commit('moar work plz')
 
306
        work_tree = trunk_tree.branch.bzrdir.sprout('local').open_workingtree()
 
307
        branch_revid = work_tree.commit('moar work plz')
 
308
        work_tree.branch.push(branch_tree.branch)
215
309
        # you can chain branches on from there
216
310
        out, err = self.run_bzr(['branch', 'branch', '--stacked', 'branch2'])
217
311
        self.assertEqual('', out)
220
314
        self.assertEqual(branch_tree.branch.base,
221
315
            branch.Branch.open('branch2').get_stacked_on_url())
222
316
        branch2_tree = WorkingTree.open('branch2')
223
 
        branch2_revid = branch2_tree.commit('work on second stacked branch')
 
317
        branch2_revid = work_tree.commit('work on second stacked branch')
 
318
        work_tree.branch.push(branch2_tree.branch)
224
319
        self.assertRevisionInRepository('branch2', branch2_revid)
225
320
        self.assertRevisionsInBranchRepository(
226
321
            [trunk_revid, branch_revid, branch2_revid],
239
334
        self.assertEqual('Created new stacked branch referring to %s.\n' %
240
335
            trunk_tree.branch.base, err)
241
336
        self.assertRevisionNotInRepository('newbranch', original_revid)
242
 
        new_tree = WorkingTree.open('newbranch')
243
 
        new_revid = new_tree.commit('new work')
244
 
        self.check_shallow_branch(new_revid, trunk_tree.branch.base)
 
337
        new_branch = branch.Branch.open('newbranch')
 
338
        self.assertEqual(trunk_tree.branch.base, new_branch.get_stacked_on_url())
245
339
 
246
340
    def test_branch_stacked_from_smart_server(self):
247
341
        # We can branch stacking on a smart server
248
 
        from bzrlib.smart.server import SmartTCPServer_for_testing
249
 
        self.transport_server = SmartTCPServer_for_testing
 
342
        self.transport_server = test_server.SmartTCPServer_for_testing
250
343
        trunk = self.make_branch('mainline', format='1.9')
251
344
        out, err = self.run_bzr(
252
345
            ['branch', '--stacked', self.get_url('mainline'), 'shallow'])
262
355
            '  Packs 5 (adds stacking support, requires bzr 1.6)\n'
263
356
            'Source branch format does not support stacking, using format:\n'
264
357
            '  Branch format 7\n'
 
358
            'Doing on-the-fly conversion from RepositoryFormatKnitPack1() to RepositoryFormatKnitPack5().\n'
 
359
            'This may take some time. Upgrade the repositories to the same format for better performance.\n'
265
360
            'Created new stacked branch referring to %s.\n' % (trunk.base,),
266
361
            err)
267
362
 
275
370
            '  Packs 5 rich-root (adds stacking support, requires bzr 1.6.1)\n'
276
371
            'Source branch format does not support stacking, using format:\n'
277
372
            '  Branch format 7\n'
 
373
            'Doing on-the-fly conversion from RepositoryFormatKnitPack4() to RepositoryFormatKnitPack5RichRoot().\n'
 
374
            'This may take some time. Upgrade the repositories to the same format for better performance.\n'
278
375
            'Created new stacked branch referring to %s.\n' % (trunk.base,),
279
376
            err)
280
377
 
318
415
            t.commit(message='commit %d' % count)
319
416
        tree2 = t.branch.bzrdir.sprout('feature', stacked=True
320
417
            ).open_workingtree()
321
 
        tree2.commit('feature change')
 
418
        local_tree = t.branch.bzrdir.sprout('local-working').open_workingtree()
 
419
        local_tree.commit('feature change')
 
420
        local_tree.branch.push(tree2.branch)
322
421
        self.reset_smart_call_log()
323
422
        out, err = self.run_bzr(['branch', self.get_url('feature'),
324
423
            'local-target'])