~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Aaron Bentley
  • Date: 2007-03-09 21:46:40 UTC
  • mto: (2323.6.9 0.15-integration)
  • mto: This revision was merged to the branch mainline in revision 2330.
  • Revision ID: abentley@panoramicfeedback.com-20070309214640-nnxk7g37bygoz50c
Add (set|get)_public_branch

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2008, 2009 Canonical Ltd
 
1
# Copyright (C) 2005, 2006 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 (branch, bzrdir, errors, repository)
 
22
from bzrlib import branch, bzrdir
23
23
from bzrlib.repofmt.knitrepo import RepositoryFormatKnit1
24
24
from bzrlib.tests.blackbox import ExternalBase
25
 
from bzrlib.tests import (
26
 
    KnownFailure,
27
 
    HardlinkFeature,
28
 
    )
29
 
from bzrlib.tests.test_sftp_transport import TestCaseWithSFTPServer
30
 
from bzrlib.urlutils import local_path_to_url, strip_trailing_slash
31
25
from bzrlib.workingtree import WorkingTree
32
26
 
33
27
 
34
28
class TestBranch(ExternalBase):
35
29
 
36
 
    def example_branch(self, path='.'):
37
 
        tree = self.make_branch_and_tree(path)
38
 
        self.build_tree_contents([(path + '/hello', 'foo')])
39
 
        tree.add('hello')
40
 
        tree.commit(message='setup')
41
 
        self.build_tree_contents([(path + '/goodbye', 'baz')])
42
 
        tree.add('goodbye')
43
 
        tree.commit(message='setup')
 
30
    def example_branch(test):
 
31
        test.runbzr('init')
 
32
        file('hello', 'wt').write('foo')
 
33
        test.runbzr('add hello')
 
34
        test.runbzr('commit -m setup hello')
 
35
        file('goodbye', 'wt').write('baz')
 
36
        test.runbzr('add goodbye')
 
37
        test.runbzr('commit -m setup goodbye')
44
38
 
45
39
    def test_branch(self):
46
40
        """Branch from one branch to another."""
47
 
        self.example_branch('a')
48
 
        self.run_bzr('branch a b')
 
41
        os.mkdir('a')
 
42
        os.chdir('a')
 
43
        self.example_branch()
 
44
        os.chdir('..')
 
45
        self.runbzr('branch a b')
49
46
        b = branch.Branch.open('b')
50
 
        self.run_bzr('branch a c -r 1')
51
 
        # previously was erroneously created by branching
52
 
        self.assertFalse(b._transport.has('branch-name'))
53
 
        b.bzrdir.open_workingtree().commit(message='foo', allow_pointless=True)
 
47
        self.assertEqual('b\n', b.control_files.get_utf8('branch-name').read())
 
48
        self.runbzr('branch a c -r 1')
 
49
        os.chdir('b')
 
50
        self.runbzr('commit -m foo --unchanged')
 
51
        os.chdir('..')
 
52
 
 
53
    def test_branch_basis(self):
 
54
        # ensure that basis really does grab from the basis by having incomplete source
 
55
        tree = self.make_branch_and_tree('commit_tree')
 
56
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
57
        tree.add('foo')
 
58
        tree.commit('revision 1', rev_id='1')
 
59
        source = self.make_branch_and_tree('source')
 
60
        # this gives us an incomplete repository
 
61
        tree.bzrdir.open_repository().copy_content_into(source.branch.repository)
 
62
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
 
63
        tree.bzrdir.open_branch().copy_content_into(source.branch)
 
64
        tree.copy_content_into(source)
 
65
        self.assertFalse(source.branch.repository.has_revision('2'))
 
66
        dir = source.bzrdir
 
67
        self.runbzr('branch source target --basis commit_tree')
 
68
        target = bzrdir.BzrDir.open('target')
 
69
        self.assertEqual('2', target.open_branch().last_revision())
 
70
        self.assertEqual(['2'], target.open_workingtree().get_parent_ids())
 
71
        self.assertTrue(target.open_branch().repository.has_revision('2'))
54
72
 
55
73
    def test_branch_only_copies_history(self):
56
74
        # Knit branches should only push the history for the current revision.
83
101
 
84
102
        # Now that we have a repository with shared files, make sure
85
103
        # that things aren't copied out by a 'branch'
86
 
        self.run_bzr('branch repo/b branch-b')
 
104
        self.run_bzr('branch', 'repo/b', 'branch-b')
87
105
        pushed_tree = WorkingTree.open('branch-b')
88
106
        pushed_repo = pushed_tree.branch.repository
89
107
        self.assertFalse(pushed_repo.has_revision('a-1'))
90
108
        self.assertFalse(pushed_repo.has_revision('a-2'))
91
109
        self.assertTrue(pushed_repo.has_revision('b-1'))
92
110
 
93
 
    def test_branch_hardlink(self):
94
 
        self.requireFeature(HardlinkFeature)
95
 
        source = self.make_branch_and_tree('source')
96
 
        self.build_tree(['source/file1'])
97
 
        source.add('file1')
98
 
        source.commit('added file')
99
 
        out, err = self.run_bzr(['branch', 'source', 'target', '--hardlink'])
100
 
        source_stat = os.stat('source/file1')
101
 
        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)")
111
 
 
112
 
    def test_branch_standalone(self):
113
 
        shared_repo = self.make_repository('repo', shared=True)
114
 
        self.example_branch('source')
115
 
        self.run_bzr('branch --standalone source repo/target')
116
 
        b = branch.Branch.open('repo/target')
117
 
        expected_repo_path = os.path.abspath('repo/target/.bzr/repository')
118
 
        self.assertEqual(strip_trailing_slash(b.repository.base),
119
 
            strip_trailing_slash(local_path_to_url(expected_repo_path)))
120
 
 
121
 
    def test_branch_no_tree(self):
122
 
        self.example_branch('source')
123
 
        self.run_bzr('branch --no-tree source target')
124
 
        self.failIfExists('target/hello')
125
 
        self.failIfExists('target/goodbye')
126
 
 
127
 
    def test_branch_into_existing_dir(self):
128
 
        self.example_branch('a')
129
 
        # existing dir with similar files but no .bzr dir
130
 
        self.build_tree_contents([('b/',)])
131
 
        self.build_tree_contents([('b/hello', 'bar')])  # different content
132
 
        self.build_tree_contents([('b/goodbye', 'baz')])# same content
133
 
        # fails without --use-existing-dir
134
 
        out,err = self.run_bzr('branch a b', retcode=3)
135
 
        self.assertEqual('', out)
136
 
        self.assertEqual('bzr: ERROR: Target directory "b" already exists.\n',
137
 
            err)
138
 
        # force operation
139
 
        self.run_bzr('branch a b --use-existing-dir')
140
 
        # check conflicts
141
 
        self.failUnlessExists('b/hello.moved')
142
 
        self.failIfExists('b/godbye.moved')
143
 
        # we can't branch into branch
144
 
        out,err = self.run_bzr('branch a b --use-existing-dir', retcode=3)
145
 
        self.assertEqual('', out)
146
 
        self.assertEqual('bzr: ERROR: Already a branch: "b".\n', err)
147
 
 
148
 
 
149
 
class TestBranchStacked(ExternalBase):
150
 
    """Tests for branch --stacked"""
151
 
 
152
 
    def assertRevisionInRepository(self, repo_path, revid):
153
 
        """Check that a revision is in a repository, disregarding stacking."""
154
 
        repo = bzrdir.BzrDir.open(repo_path).open_repository()
155
 
        self.assertTrue(repo.has_revision(revid))
156
 
 
157
 
    def assertRevisionNotInRepository(self, repo_path, revid):
158
 
        """Check that a revision is not in a repository, disregarding stacking."""
159
 
        repo = bzrdir.BzrDir.open(repo_path).open_repository()
160
 
        self.assertFalse(repo.has_revision(revid))
161
 
 
162
 
    def assertRevisionsInBranchRepository(self, revid_list, branch_path):
163
 
        repo = branch.Branch.open(branch_path).repository
164
 
        self.assertEqual(set(revid_list),
165
 
            repo.has_revisions(revid_list))
166
 
 
167
 
    def test_branch_stacked_branch_not_stacked(self):
168
 
        """Branching a stacked branch is not stacked by default"""
169
 
        # We have a mainline
170
 
        trunk_tree = self.make_branch_and_tree('target',
171
 
            format='1.9')
172
 
        trunk_tree.commit('mainline')
173
 
        # and a branch from it which is stacked
174
 
        branch_tree = self.make_branch_and_tree('branch',
175
 
            format='1.9')
176
 
        branch_tree.branch.set_stacked_on_url(trunk_tree.branch.base)
177
 
        # with some work on it
178
 
        work_tree = trunk_tree.branch.bzrdir.sprout('local').open_workingtree()
179
 
        work_tree.commit('moar work plz')
180
 
        work_tree.branch.push(branch_tree.branch)
181
 
        # branching our local branch gives us a new stacked branch pointing at
182
 
        # mainline.
183
 
        out, err = self.run_bzr(['branch', 'branch', 'newbranch'])
184
 
        self.assertEqual('', out)
185
 
        self.assertEqual('Branched 2 revision(s).\n',
186
 
            err)
187
 
        # it should have preserved the branch format, and so it should be
188
 
        # capable of supporting stacking, but not actually have a stacked_on
189
 
        # branch configured
190
 
        self.assertRaises(errors.NotStacked,
191
 
            bzrdir.BzrDir.open('newbranch').open_branch().get_stacked_on_url)
192
 
 
193
 
    def test_branch_stacked_branch_stacked(self):
194
 
        """Asking to stack on a stacked branch does work"""
195
 
        # We have a mainline
196
 
        trunk_tree = self.make_branch_and_tree('target',
197
 
            format='1.9')
198
 
        trunk_revid = trunk_tree.commit('mainline')
199
 
        # and a branch from it which is stacked
200
 
        branch_tree = self.make_branch_and_tree('branch',
201
 
            format='1.9')
202
 
        branch_tree.branch.set_stacked_on_url(trunk_tree.branch.base)
203
 
        # with some work on it
204
 
        work_tree = trunk_tree.branch.bzrdir.sprout('local').open_workingtree()
205
 
        branch_revid = work_tree.commit('moar work plz')
206
 
        work_tree.branch.push(branch_tree.branch)
207
 
        # you can chain branches on from there
208
 
        out, err = self.run_bzr(['branch', 'branch', '--stacked', 'branch2'])
209
 
        self.assertEqual('', out)
210
 
        self.assertEqual('Created new stacked branch referring to %s.\n' %
211
 
            branch_tree.branch.base, err)
212
 
        self.assertEqual(branch_tree.branch.base,
213
 
            branch.Branch.open('branch2').get_stacked_on_url())
214
 
        branch2_tree = WorkingTree.open('branch2')
215
 
        branch2_revid = work_tree.commit('work on second stacked branch')
216
 
        work_tree.branch.push(branch2_tree.branch)
217
 
        self.assertRevisionInRepository('branch2', branch2_revid)
218
 
        self.assertRevisionsInBranchRepository(
219
 
            [trunk_revid, branch_revid, branch2_revid],
220
 
            'branch2')
221
 
 
222
 
    def test_branch_stacked(self):
223
 
        # We have a mainline
224
 
        trunk_tree = self.make_branch_and_tree('mainline',
225
 
            format='1.9')
226
 
        original_revid = trunk_tree.commit('mainline')
227
 
        self.assertRevisionInRepository('mainline', original_revid)
228
 
        # and a branch from it which is stacked
229
 
        out, err = self.run_bzr(['branch', '--stacked', 'mainline',
230
 
            'newbranch'])
231
 
        self.assertEqual('', out)
232
 
        self.assertEqual('Created new stacked branch referring to %s.\n' %
233
 
            trunk_tree.branch.base, err)
234
 
        self.assertRevisionNotInRepository('newbranch', original_revid)
235
 
        new_branch = branch.Branch.open('newbranch')
236
 
        self.assertEqual(trunk_tree.branch.base, new_branch.get_stacked_on_url())
237
 
 
238
 
    def test_branch_stacked_from_smart_server(self):
239
 
        # We can branch stacking on a smart server
240
 
        from bzrlib.smart.server import SmartTCPServer_for_testing
241
 
        self.transport_server = SmartTCPServer_for_testing
242
 
        trunk = self.make_branch('mainline', format='1.9')
243
 
        out, err = self.run_bzr(
244
 
            ['branch', '--stacked', self.get_url('mainline'), 'shallow'])
245
 
 
246
 
    def test_branch_stacked_from_non_stacked_format(self):
247
 
        """The origin format doesn't support stacking"""
248
 
        trunk = self.make_branch('trunk', format='pack-0.92')
249
 
        out, err = self.run_bzr(
250
 
            ['branch', '--stacked', 'trunk', 'shallow'])
251
 
        # We should notify the user that we upgraded their format
252
 
        self.assertEqualDiff(
253
 
            'Source repository format does not support stacking, using format:\n'
254
 
            '  Packs 5 (adds stacking support, requires bzr 1.6)\n'
255
 
            'Source branch format does not support stacking, using format:\n'
256
 
            '  Branch format 7\n'
257
 
            'Created new stacked branch referring to %s.\n' % (trunk.base,),
258
 
            err)
259
 
 
260
 
    def test_branch_stacked_from_rich_root_non_stackable(self):
261
 
        trunk = self.make_branch('trunk', format='rich-root-pack')
262
 
        out, err = self.run_bzr(
263
 
            ['branch', '--stacked', 'trunk', 'shallow'])
264
 
        # We should notify the user that we upgraded their format
265
 
        self.assertEqualDiff(
266
 
            'Source repository format does not support stacking, using format:\n'
267
 
            '  Packs 5 rich-root (adds stacking support, requires bzr 1.6.1)\n'
268
 
            'Source branch format does not support stacking, using format:\n'
269
 
            '  Branch format 7\n'
270
 
            'Created new stacked branch referring to %s.\n' % (trunk.base,),
271
 
            err)
272
 
 
273
 
 
274
 
class TestSmartServerBranching(ExternalBase):
275
 
 
276
 
    def test_branch_from_trivial_branch_to_same_server_branch_acceptance(self):
277
 
        self.setup_smart_server_with_call_log()
278
 
        t = self.make_branch_and_tree('from')
279
 
        for count in range(9):
280
 
            t.commit(message='commit %d' % count)
281
 
        self.reset_smart_call_log()
282
 
        out, err = self.run_bzr(['branch', self.get_url('from'),
283
 
            self.get_url('target')])
284
 
        # This figure represent the amount of work to perform this use case. It
285
 
        # is entirely ok to reduce this number if a test fails due to rpc_count
286
 
        # being too low. If rpc_count increases, more network roundtrips have
287
 
        # become necessary for this use case. Please do not adjust this number
288
 
        # upwards without agreement from bzr's network support maintainers.
289
 
        self.assertLength(38, self.hpss_calls)
290
 
 
291
 
    def test_branch_from_trivial_branch_streaming_acceptance(self):
292
 
        self.setup_smart_server_with_call_log()
293
 
        t = self.make_branch_and_tree('from')
294
 
        for count in range(9):
295
 
            t.commit(message='commit %d' % count)
296
 
        self.reset_smart_call_log()
297
 
        out, err = self.run_bzr(['branch', self.get_url('from'),
298
 
            'local-target'])
299
 
        # This figure represent the amount of work to perform this use case. It
300
 
        # is entirely ok to reduce this number if a test fails due to rpc_count
301
 
        # being too low. If rpc_count increases, more network roundtrips have
302
 
        # become necessary for this use case. Please do not adjust this number
303
 
        # upwards without agreement from bzr's network support maintainers.
304
 
        self.assertLength(10, self.hpss_calls)
305
 
 
306
 
    def test_branch_from_trivial_stacked_branch_streaming_acceptance(self):
307
 
        self.setup_smart_server_with_call_log()
308
 
        t = self.make_branch_and_tree('trunk')
309
 
        for count in range(8):
310
 
            t.commit(message='commit %d' % count)
311
 
        tree2 = t.branch.bzrdir.sprout('feature', stacked=True
312
 
            ).open_workingtree()
313
 
        local_tree = t.branch.bzrdir.sprout('local-working').open_workingtree()
314
 
        local_tree.commit('feature change')
315
 
        local_tree.branch.push(tree2.branch)
316
 
        self.reset_smart_call_log()
317
 
        out, err = self.run_bzr(['branch', self.get_url('feature'),
318
 
            'local-target'])
319
 
        # This figure represent the amount of work to perform this use case. It
320
 
        # is entirely ok to reduce this number if a test fails due to rpc_count
321
 
        # being too low. If rpc_count increases, more network roundtrips have
322
 
        # become necessary for this use case. Please do not adjust this number
323
 
        # upwards without agreement from bzr's network support maintainers.
324
 
        self.assertLength(15, self.hpss_calls)
325
 
 
326
 
 
327
 
class TestRemoteBranch(TestCaseWithSFTPServer):
328
 
 
329
 
    def setUp(self):
330
 
        super(TestRemoteBranch, self).setUp()
331
 
        tree = self.make_branch_and_tree('branch')
332
 
        self.build_tree_contents([('branch/file', 'file content\n')])
333
 
        tree.add('file')
334
 
        tree.commit('file created')
335
 
 
336
 
    def test_branch_local_remote(self):
337
 
        self.run_bzr(['branch', 'branch', self.get_url('remote')])
338
 
        t = self.get_transport()
339
 
        # Ensure that no working tree what created remotely
340
 
        self.assertFalse(t.has('remote/file'))
341
 
 
342
 
    def test_branch_remote_remote(self):
343
 
        # Light cheat: we access the branch remotely
344
 
        self.run_bzr(['branch', self.get_url('branch'),
345
 
                      self.get_url('remote')])
346
 
        t = self.get_transport()
347
 
        # Ensure that no working tree what created remotely
348
 
        self.assertFalse(t.has('remote/file'))
349
111