~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Gary van der Merwe
  • Date: 2010-08-02 19:56:52 UTC
  • mfrom: (5050.3.18 2.2)
  • mto: (5050.3.19 2.2)
  • mto: This revision was merged to the branch mainline in revision 5371.
  • Revision ID: garyvdm@gmail.com-20100802195652-o1ppjemhwrr98i61
MergeĀ lp:bzr/2.2.

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
 
from bzrlib.tests.blackbox import ExternalBase
 
30
from bzrlib.tests import TestCaseWithTransport
25
31
from bzrlib.tests import (
26
32
    KnownFailure,
27
33
    HardlinkFeature,
 
34
    test_server,
28
35
    )
29
36
from bzrlib.tests.test_sftp_transport import TestCaseWithSFTPServer
30
37
from bzrlib.urlutils import local_path_to_url, strip_trailing_slash
31
38
from bzrlib.workingtree import WorkingTree
32
39
 
33
40
 
34
 
class TestBranch(ExternalBase):
 
41
class TestBranch(TestCaseWithTransport):
35
42
 
36
43
    def example_branch(self, path='.'):
37
44
        tree = self.make_branch_and_tree(path)
52
59
        self.assertFalse(b._transport.has('branch-name'))
53
60
        b.bzrdir.open_workingtree().commit(message='foo', allow_pointless=True)
54
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
 
55
128
    def test_branch_only_copies_history(self):
56
129
        # Knit branches should only push the history for the current revision.
57
130
        format = bzrdir.BzrDirMetaFormat1()
99
172
        out, err = self.run_bzr(['branch', 'source', 'target', '--hardlink'])
100
173
        source_stat = os.stat('source/file1')
101
174
        target_stat = os.stat('target/file1')
102
 
        same_file = (source_stat == target_stat)
103
 
        if same_file:
104
 
            pass
105
 
        else:
106
 
            # https://bugs.edge.launchpad.net/bzr/+bug/408193
107
 
            self.assertContainsRe(err, "hardlinking working copy files is "
108
 
                "not currently supported")
109
 
            raise KnownFailure("--hardlink doesn't work in formats "
110
 
                "that support content filtering (#408193)")
 
175
        self.assertEqual(source_stat, target_stat)
111
176
 
112
177
    def test_branch_standalone(self):
113
178
        shared_repo = self.make_repository('repo', shared=True)
145
210
        self.assertEqual('', out)
146
211
        self.assertEqual('bzr: ERROR: Already a branch: "b".\n', err)
147
212
 
148
 
 
149
 
class TestBranchStacked(ExternalBase):
 
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
 
 
250
 
 
251
class TestBranchStacked(TestCaseWithTransport):
150
252
    """Tests for branch --stacked"""
151
253
 
152
 
    def check_shallow_branch(self, branch_revid, stacked_on):
153
 
        """Assert that the branch 'newbranch' has been published correctly.
154
 
 
155
 
        :param stacked_on: url of a branch this one is stacked upon.
156
 
        :param branch_revid: a revision id that should be the only
157
 
            revision present in the stacked branch, and it should not be in
158
 
            the reference branch.
159
 
        """
160
 
        new_branch = branch.Branch.open('newbranch')
161
 
        # The branch refers to the mainline
162
 
        self.assertEqual(stacked_on, new_branch.get_stacked_on_url())
163
 
        # and the branch's work was pushed
164
 
        self.assertTrue(new_branch.repository.has_revision(branch_revid))
165
 
        # The newly committed revision shoud be present in the stacked branch,
166
 
        # but not in the stacked-on branch.  Because stacking is set up by the
167
 
        # branch object, if we open the stacked branch's repository directly,
168
 
        # bypassing the branch, we see only what's in the stacked repository.
169
 
        stacked_repo = bzrdir.BzrDir.open('newbranch').open_repository()
170
 
        stacked_repo_revisions = set(stacked_repo.all_revision_ids())
171
 
        if len(stacked_repo_revisions) != 1:
172
 
            self.fail("wrong revisions in stacked repository: %r"
173
 
                % (stacked_repo_revisions,))
174
 
 
175
254
    def assertRevisionInRepository(self, repo_path, revid):
176
255
        """Check that a revision is in a repository, disregarding stacking."""
177
256
        repo = bzrdir.BzrDir.open(repo_path).open_repository()
198
277
            format='1.9')
199
278
        branch_tree.branch.set_stacked_on_url(trunk_tree.branch.base)
200
279
        # with some work on it
201
 
        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)
202
283
        # branching our local branch gives us a new stacked branch pointing at
203
284
        # mainline.
204
285
        out, err = self.run_bzr(['branch', 'branch', 'newbranch'])
205
286
        self.assertEqual('', out)
206
 
        self.assertEqual('Branched 1 revision(s).\n',
 
287
        self.assertEqual('Branched 2 revision(s).\n',
207
288
            err)
208
289
        # it should have preserved the branch format, and so it should be
209
290
        # capable of supporting stacking, but not actually have a stacked_on
222
303
            format='1.9')
223
304
        branch_tree.branch.set_stacked_on_url(trunk_tree.branch.base)
224
305
        # with some work on it
225
 
        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)
226
309
        # you can chain branches on from there
227
310
        out, err = self.run_bzr(['branch', 'branch', '--stacked', 'branch2'])
228
311
        self.assertEqual('', out)
231
314
        self.assertEqual(branch_tree.branch.base,
232
315
            branch.Branch.open('branch2').get_stacked_on_url())
233
316
        branch2_tree = WorkingTree.open('branch2')
234
 
        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)
235
319
        self.assertRevisionInRepository('branch2', branch2_revid)
236
320
        self.assertRevisionsInBranchRepository(
237
321
            [trunk_revid, branch_revid, branch2_revid],
250
334
        self.assertEqual('Created new stacked branch referring to %s.\n' %
251
335
            trunk_tree.branch.base, err)
252
336
        self.assertRevisionNotInRepository('newbranch', original_revid)
253
 
        new_tree = WorkingTree.open('newbranch')
254
 
        new_revid = new_tree.commit('new work')
255
 
        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())
256
339
 
257
340
    def test_branch_stacked_from_smart_server(self):
258
341
        # We can branch stacking on a smart server
259
 
        from bzrlib.smart.server import SmartTCPServer_for_testing
260
 
        self.transport_server = SmartTCPServer_for_testing
 
342
        self.transport_server = test_server.SmartTCPServer_for_testing
261
343
        trunk = self.make_branch('mainline', format='1.9')
262
344
        out, err = self.run_bzr(
263
345
            ['branch', '--stacked', self.get_url('mainline'), 'shallow'])
273
355
            '  Packs 5 (adds stacking support, requires bzr 1.6)\n'
274
356
            'Source branch format does not support stacking, using format:\n'
275
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'
276
360
            'Created new stacked branch referring to %s.\n' % (trunk.base,),
277
361
            err)
278
362
 
286
370
            '  Packs 5 rich-root (adds stacking support, requires bzr 1.6.1)\n'
287
371
            'Source branch format does not support stacking, using format:\n'
288
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'
289
375
            'Created new stacked branch referring to %s.\n' % (trunk.base,),
290
376
            err)
291
377
 
292
378
 
293
 
class TestSmartServerBranching(ExternalBase):
 
379
class TestSmartServerBranching(TestCaseWithTransport):
294
380
 
295
381
    def test_branch_from_trivial_branch_to_same_server_branch_acceptance(self):
296
382
        self.setup_smart_server_with_call_log()
329
415
            t.commit(message='commit %d' % count)
330
416
        tree2 = t.branch.bzrdir.sprout('feature', stacked=True
331
417
            ).open_workingtree()
332
 
        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)
333
421
        self.reset_smart_call_log()
334
422
        out, err = self.run_bzr(['branch', self.get_url('feature'),
335
423
            'local-target'])