/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_branchbuilder.py

  • Committer: mernst at mit
  • Date: 2008-10-16 10:57:16 UTC
  • mto: This revision was merged to the branch mainline in revision 3799.
  • Revision ID: mernst@csail.mit.edu-20081016105716-v8x8n5t2pf7f6uds
Improved documentation of stacked and lightweight branches

These patches improve the User Guide's documentation of stacked and
lightweight branches.

Section "1.2.6 Putting the concepts together" should mention stacked
branches and the difference between them and lightweight branches.  It
should also contain links to further details of the common scenarios.

Section "5.3.4 Getting a lightweight checkout" should mention stacked
branches as an option, and should link to all the options, not just some of
them.  It should also clarify that lightweight only applies to checkouts,
not to arbitrary branches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2007 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
"""Tests for the BranchBuilder class."""
 
18
 
 
19
from bzrlib import (
 
20
    branch as _mod_branch,
 
21
    errors,
 
22
    revision as _mod_revision,
 
23
    tests,
 
24
    )
 
25
from bzrlib.branchbuilder import BranchBuilder
 
26
 
 
27
 
 
28
class TestBranchBuilder(tests.TestCaseWithMemoryTransport):
 
29
    
 
30
    def test_create(self):
 
31
        """Test the constructor api."""
 
32
        builder = BranchBuilder(self.get_transport().clone('foo'))
 
33
        # we dont care if the branch has been built or not at this point.
 
34
 
 
35
    def test_get_branch(self):
 
36
        """get_branch returns the created branch."""
 
37
        builder = BranchBuilder(self.get_transport().clone('foo'))
 
38
        branch = builder.get_branch()
 
39
        self.assertIsInstance(branch, _mod_branch.Branch)
 
40
        self.assertEqual(self.get_transport().clone('foo').base,
 
41
            branch.base)
 
42
        self.assertEqual(
 
43
            (0, _mod_revision.NULL_REVISION),
 
44
            branch.last_revision_info())
 
45
 
 
46
    def test_format(self):
 
47
        """Making a BranchBuilder with a format option sets the branch type."""
 
48
        builder = BranchBuilder(self.get_transport(), format='dirstate-tags')
 
49
        branch = builder.get_branch()
 
50
        self.assertIsInstance(branch, _mod_branch.BzrBranch6)
 
51
 
 
52
    def test_build_one_commit(self):
 
53
        """doing build_commit causes a commit to happen."""
 
54
        builder = BranchBuilder(self.get_transport().clone('foo'))
 
55
        rev_id = builder.build_commit()
 
56
        branch = builder.get_branch()
 
57
        self.assertEqual((1, rev_id), branch.last_revision_info())
 
58
        self.assertEqual(
 
59
            'commit 1',
 
60
            branch.repository.get_revision(branch.last_revision()).message)
 
61
 
 
62
    def test_build_two_commits(self):
 
63
        """The second commit has the right parents and message."""
 
64
        builder = BranchBuilder(self.get_transport().clone('foo'))
 
65
        rev_id1 = builder.build_commit()
 
66
        rev_id2 = builder.build_commit()
 
67
        branch = builder.get_branch()
 
68
        self.assertEqual((2, rev_id2), branch.last_revision_info())
 
69
        self.assertEqual(
 
70
            'commit 2',
 
71
            branch.repository.get_revision(branch.last_revision()).message)
 
72
        self.assertEqual(
 
73
            [rev_id1],
 
74
            branch.repository.get_revision(branch.last_revision()).parent_ids)
 
75
 
 
76
 
 
77
class TestBranchBuilderBuildSnapshot(tests.TestCaseWithMemoryTransport):
 
78
 
 
79
    def assertTreeShape(self, expected_shape, tree):
 
80
        """Check that the tree shape matches expectations."""
 
81
        tree.lock_read()
 
82
        try:
 
83
            entries = [(path, ie.file_id, ie.kind)
 
84
                       for path, ie in tree.iter_entries_by_dir()]
 
85
        finally:
 
86
            tree.unlock()
 
87
        self.assertEqual(expected_shape, entries)
 
88
 
 
89
    def build_a_rev(self):
 
90
        builder = BranchBuilder(self.get_transport().clone('foo'))
 
91
        rev_id1 = builder.build_snapshot('A-id', None,
 
92
            [('add', ('', 'a-root-id', 'directory', None)),
 
93
             ('add', ('a', 'a-id', 'file', 'contents'))])
 
94
        self.assertEqual('A-id', rev_id1)
 
95
        return builder
 
96
 
 
97
    def test_add_one_file(self):
 
98
        builder = self.build_a_rev()
 
99
        branch = builder.get_branch()
 
100
        self.assertEqual((1, 'A-id'), branch.last_revision_info())
 
101
        rev_tree = branch.repository.revision_tree('A-id')
 
102
        rev_tree.lock_read()
 
103
        self.addCleanup(rev_tree.unlock)
 
104
        self.assertTreeShape([(u'', 'a-root-id', 'directory'),
 
105
                              (u'a', 'a-id', 'file')], rev_tree)
 
106
        self.assertEqual('contents', rev_tree.get_file_text('a-id'))
 
107
 
 
108
    def test_add_second_file(self):
 
109
        builder = self.build_a_rev()
 
110
        rev_id2 = builder.build_snapshot('B-id', None,
 
111
            [('add', ('b', 'b-id', 'file', 'content_b'))])
 
112
        self.assertEqual('B-id', rev_id2)
 
113
        branch = builder.get_branch()
 
114
        self.assertEqual((2, rev_id2), branch.last_revision_info())
 
115
        rev_tree = branch.repository.revision_tree(rev_id2)
 
116
        rev_tree.lock_read()
 
117
        self.addCleanup(rev_tree.unlock)
 
118
        self.assertTreeShape([(u'', 'a-root-id', 'directory'),
 
119
                              (u'a', 'a-id', 'file'),
 
120
                              (u'b', 'b-id', 'file')], rev_tree)
 
121
        self.assertEqual('content_b', rev_tree.get_file_text('b-id'))
 
122
 
 
123
    def test_add_empty_dir(self):
 
124
        builder = self.build_a_rev()
 
125
        rev_id2 = builder.build_snapshot('B-id', None,
 
126
            [('add', ('b', 'b-id', 'directory', None))])
 
127
        rev_tree = builder.get_branch().repository.revision_tree('B-id')
 
128
        self.assertTreeShape([(u'', 'a-root-id', 'directory'),
 
129
                              (u'a', 'a-id', 'file'),
 
130
                              (u'b', 'b-id', 'directory'),
 
131
                             ], rev_tree)
 
132
 
 
133
    def test_commit_message_default(self):
 
134
        builder = BranchBuilder(self.get_transport().clone('foo'))
 
135
        rev_id = builder.build_snapshot(None, None,
 
136
            [('add', (u'', None, 'directory', None))])
 
137
        branch = builder.get_branch()
 
138
        rev = branch.repository.get_revision(rev_id)
 
139
        self.assertEqual(u'commit 1', rev.message)
 
140
 
 
141
    def test_commit_message_supplied(self):
 
142
        builder = BranchBuilder(self.get_transport().clone('foo'))
 
143
        rev_id = builder.build_snapshot(None, None,
 
144
            [('add', (u'', None, 'directory', None))],
 
145
            message=u'Foo')
 
146
        branch = builder.get_branch()
 
147
        rev = branch.repository.get_revision(rev_id)
 
148
        self.assertEqual(u'Foo', rev.message)
 
149
 
 
150
    def test_modify_file(self):
 
151
        builder = self.build_a_rev()
 
152
        rev_id2 = builder.build_snapshot('B-id', None,
 
153
            [('modify', ('a-id', 'new\ncontent\n'))])
 
154
        self.assertEqual('B-id', rev_id2)
 
155
        branch = builder.get_branch()
 
156
        rev_tree = branch.repository.revision_tree(rev_id2)
 
157
        rev_tree.lock_read()
 
158
        self.addCleanup(rev_tree.unlock)
 
159
        self.assertEqual('new\ncontent\n', rev_tree.get_file_text('a-id'))
 
160
 
 
161
    def test_delete_file(self):
 
162
        builder = self.build_a_rev()
 
163
        rev_id2 = builder.build_snapshot('B-id', None,
 
164
            [('unversion', 'a-id')])
 
165
        self.assertEqual('B-id', rev_id2)
 
166
        branch = builder.get_branch()
 
167
        rev_tree = branch.repository.revision_tree(rev_id2)
 
168
        rev_tree.lock_read()
 
169
        self.addCleanup(rev_tree.unlock)
 
170
        self.assertTreeShape([(u'', 'a-root-id', 'directory')], rev_tree)
 
171
 
 
172
    def test_delete_directory(self):
 
173
        builder = self.build_a_rev()
 
174
        rev_id2 = builder.build_snapshot('B-id', None,
 
175
            [('add', ('b', 'b-id', 'directory', None)),
 
176
             ('add', ('b/c', 'c-id', 'file', 'foo\n')),
 
177
             ('add', ('b/d', 'd-id', 'directory', None)),
 
178
             ('add', ('b/d/e', 'e-id', 'file', 'eff\n')),
 
179
            ])
 
180
        rev_tree = builder.get_branch().repository.revision_tree('B-id')
 
181
        self.assertTreeShape([(u'', 'a-root-id', 'directory'),
 
182
                              (u'a', 'a-id', 'file'),
 
183
                              (u'b', 'b-id', 'directory'),
 
184
                              (u'b/c', 'c-id', 'file'),
 
185
                              (u'b/d', 'd-id', 'directory'),
 
186
                              (u'b/d/e', 'e-id', 'file')], rev_tree)
 
187
        # Removing a directory removes all child dirs
 
188
        builder.build_snapshot('C-id', None, [('unversion', 'b-id')])
 
189
        rev_tree = builder.get_branch().repository.revision_tree('C-id')
 
190
        self.assertTreeShape([(u'', 'a-root-id', 'directory'),
 
191
                              (u'a', 'a-id', 'file'),
 
192
                             ], rev_tree)
 
193
 
 
194
    def test_unknown_action(self):
 
195
        builder = self.build_a_rev()
 
196
        e = self.assertRaises(ValueError,
 
197
            builder.build_snapshot, 'B-id', None, [('weirdo', ('foo',))])
 
198
        self.assertEqual('Unknown build action: "weirdo"', str(e))
 
199
 
 
200
    def test_rename(self):
 
201
        builder = self.build_a_rev()
 
202
        builder.build_snapshot('B-id', None,
 
203
            [('rename', ('a', 'b'))])
 
204
        rev_tree = builder.get_branch().repository.revision_tree('B-id')
 
205
        self.assertTreeShape([(u'', 'a-root-id', 'directory'),
 
206
                              (u'b', 'a-id', 'file')], rev_tree)
 
207
 
 
208
    def test_rename_into_subdir(self):
 
209
        builder = self.build_a_rev()
 
210
        builder.build_snapshot('B-id', None,
 
211
            [('add', ('dir', 'dir-id', 'directory', None)),
 
212
             ('rename', ('a', 'dir/a'))])
 
213
        rev_tree = builder.get_branch().repository.revision_tree('B-id')
 
214
        self.assertTreeShape([(u'', 'a-root-id', 'directory'),
 
215
                              (u'dir', 'dir-id', 'directory'),
 
216
                              (u'dir/a', 'a-id', 'file')], rev_tree)
 
217
 
 
218
    def test_set_parent(self):
 
219
        builder = self.build_a_rev()
 
220
        builder.start_series()
 
221
        self.addCleanup(builder.finish_series)
 
222
        builder.build_snapshot('B-id', ['A-id'],
 
223
            [('modify', ('a-id', 'new\ncontent\n'))])
 
224
        builder.build_snapshot('C-id', ['A-id'], 
 
225
            [('add', ('c', 'c-id', 'file', 'alt\ncontent\n'))])
 
226
        # We should now have a graph:
 
227
        #   A
 
228
        #   |\
 
229
        #   C B
 
230
        # And not A => B => C
 
231
        repo = builder.get_branch().repository
 
232
        self.assertEqual({'B-id': ('A-id',), 'C-id': ('A-id',)},
 
233
                         repo.get_parent_map(['B-id', 'C-id']))
 
234
        b_tree = repo.revision_tree('B-id')
 
235
        self.assertTreeShape([(u'', 'a-root-id', 'directory'),
 
236
                              (u'a', 'a-id', 'file'),
 
237
                             ], b_tree)
 
238
        self.assertEqual('new\ncontent\n', b_tree.get_file_text('a-id'))
 
239
 
 
240
        # We should still be using the content from A in C, not from B
 
241
        c_tree = repo.revision_tree('C-id')
 
242
        self.assertTreeShape([(u'', 'a-root-id', 'directory'),
 
243
                              (u'a', 'a-id', 'file'),
 
244
                              (u'c', 'c-id', 'file'),
 
245
                             ], c_tree)
 
246
        self.assertEqual('contents', c_tree.get_file_text('a-id'))
 
247
        self.assertEqual('alt\ncontent\n', c_tree.get_file_text('c-id'))
 
248
 
 
249
    def test_set_merge_parent(self):
 
250
        builder = self.build_a_rev()
 
251
        builder.start_series()
 
252
        self.addCleanup(builder.finish_series)
 
253
        builder.build_snapshot('B-id', ['A-id'],
 
254
            [('add', ('b', 'b-id', 'file', 'b\ncontent\n'))])
 
255
        builder.build_snapshot('C-id', ['A-id'],
 
256
            [('add', ('c', 'c-id', 'file', 'alt\ncontent\n'))])
 
257
        builder.build_snapshot('D-id', ['B-id', 'C-id'], [])
 
258
        repo = builder.get_branch().repository
 
259
        self.assertEqual({'B-id': ('A-id',), 'C-id': ('A-id',),
 
260
                          'D-id': ('B-id', 'C-id')},
 
261
                         repo.get_parent_map(['B-id', 'C-id', 'D-id']))
 
262
        d_tree = repo.revision_tree('D-id')
 
263
        # Note: by default a merge node does *not* pull in the changes from the
 
264
        #       merged tree, you have to supply it yourself.
 
265
        self.assertTreeShape([(u'', 'a-root-id', 'directory'),
 
266
                              (u'a', 'a-id', 'file'),
 
267
                              (u'b', 'b-id', 'file'),
 
268
                             ], d_tree)
 
269
 
 
270
    def test_set_merge_parent_and_contents(self):
 
271
        builder = self.build_a_rev()
 
272
        builder.start_series()
 
273
        self.addCleanup(builder.finish_series)
 
274
        builder.build_snapshot('B-id', ['A-id'],
 
275
            [('add', ('b', 'b-id', 'file', 'b\ncontent\n'))])
 
276
        builder.build_snapshot('C-id', ['A-id'],
 
277
            [('add', ('c', 'c-id', 'file', 'alt\ncontent\n'))])
 
278
        builder.build_snapshot('D-id', ['B-id', 'C-id'],
 
279
            [('add', ('c', 'c-id', 'file', 'alt\ncontent\n'))])
 
280
        repo = builder.get_branch().repository
 
281
        self.assertEqual({'B-id': ('A-id',), 'C-id': ('A-id',),
 
282
                          'D-id': ('B-id', 'C-id')},
 
283
                         repo.get_parent_map(['B-id', 'C-id', 'D-id']))
 
284
        d_tree = repo.revision_tree('D-id')
 
285
        self.assertTreeShape([(u'', 'a-root-id', 'directory'),
 
286
                              (u'a', 'a-id', 'file'),
 
287
                              (u'b', 'b-id', 'file'),
 
288
                              (u'c', 'c-id', 'file'),
 
289
                             ], d_tree)
 
290
        # Because we copied the exact text into *this* tree, the 'c' file
 
291
        # should look like it was not modified in the merge
 
292
        self.assertEqual('C-id', d_tree.inventory['c-id'].revision)
 
293
 
 
294
    def test_start_finish_series(self):
 
295
        builder = BranchBuilder(self.get_transport().clone('foo'))
 
296
        builder.start_series()
 
297
        try:
 
298
            self.assertIsNot(None, builder._tree)
 
299
            self.assertEqual('w', builder._tree._lock_mode)
 
300
            self.assertTrue(builder._branch.is_locked())
 
301
        finally:
 
302
            builder.finish_series()
 
303
        self.assertIs(None, builder._tree)
 
304
        self.assertFalse(builder._branch.is_locked())