/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
5557.1.15 by John Arbash Meinel
Merge bzr.dev 5597 to resolve NEWS, aka bzr-2.3.txt
1
# Copyright (C) 2007-2011 Canonical Ltd
2466.7.3 by Robert Collins
Create bzrlib.branchbuilder.
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2466.7.3 by Robert Collins
Create bzrlib.branchbuilder.
16
17
"""Tests for the BranchBuilder class."""
18
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
19
from .. import (
2466.7.4 by Robert Collins
Add BranchBuilder.get_branch().
20
    branch as _mod_branch,
21
    revision as _mod_revision,
22
    tests,
23
    )
6670.4.1 by Jelmer Vernooij
Update imports.
24
from ..bzr import (
25
    branch as _mod_bzrbranch,
26
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
27
from ..branchbuilder import BranchBuilder
2466.7.3 by Robert Collins
Create bzrlib.branchbuilder.
28
29
30
class TestBranchBuilder(tests.TestCaseWithMemoryTransport):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
31
2466.7.3 by Robert Collins
Create bzrlib.branchbuilder.
32
    def test_create(self):
33
        """Test the constructor api."""
34
        builder = BranchBuilder(self.get_transport().clone('foo'))
35
        # we dont care if the branch has been built or not at this point.
2466.7.4 by Robert Collins
Add BranchBuilder.get_branch().
36
37
    def test_get_branch(self):
38
        """get_branch returns the created branch."""
39
        builder = BranchBuilder(self.get_transport().clone('foo'))
40
        branch = builder.get_branch()
41
        self.assertIsInstance(branch, _mod_branch.Branch)
42
        self.assertEqual(self.get_transport().clone('foo').base,
43
            branch.base)
44
        self.assertEqual(
45
            (0, _mod_revision.NULL_REVISION),
46
            branch.last_revision_info())
2466.7.6 by Robert Collins
Add BranchBuilder.build_commit.
47
2466.7.10 by Robert Collins
Add a format parameter to BranchBuilder.
48
    def test_format(self):
49
        """Making a BranchBuilder with a format option sets the branch type."""
50
        builder = BranchBuilder(self.get_transport(), format='dirstate-tags')
51
        branch = builder.get_branch()
6653.1.9 by Jelmer Vernooij
Fix set_default.
52
        self.assertIsInstance(branch, _mod_bzrbranch.BzrBranch6)
2466.7.10 by Robert Collins
Add a format parameter to BranchBuilder.
53
2466.7.6 by Robert Collins
Add BranchBuilder.build_commit.
54
    def test_build_one_commit(self):
55
        """doing build_commit causes a commit to happen."""
56
        builder = BranchBuilder(self.get_transport().clone('foo'))
2466.7.9 by Robert Collins
Return the commited revision id from BranchBuilder.build_commit to save later instrospection.
57
        rev_id = builder.build_commit()
2466.7.6 by Robert Collins
Add BranchBuilder.build_commit.
58
        branch = builder.get_branch()
2466.7.9 by Robert Collins
Return the commited revision id from BranchBuilder.build_commit to save later instrospection.
59
        self.assertEqual((1, rev_id), branch.last_revision_info())
2466.7.6 by Robert Collins
Add BranchBuilder.build_commit.
60
        self.assertEqual(
61
            'commit 1',
62
            branch.repository.get_revision(branch.last_revision()).message)
63
4070.5.1 by Martin Pool
BranchBuilder now takes a timestamp for commits
64
    def test_build_commit_timestamp(self):
65
        """You can set a date when committing."""
66
        builder = self.make_branch_builder('foo')
67
        rev_id = builder.build_commit(timestamp=1236043340)
68
        branch = builder.get_branch()
69
        self.assertEqual((1, rev_id), branch.last_revision_info())
70
        rev = branch.repository.get_revision(branch.last_revision())
71
        self.assertEqual(
72
            'commit 1',
73
            rev.message)
74
        self.assertEqual(
75
            1236043340,
76
            int(rev.timestamp))
77
2466.7.6 by Robert Collins
Add BranchBuilder.build_commit.
78
    def test_build_two_commits(self):
79
        """The second commit has the right parents and message."""
80
        builder = BranchBuilder(self.get_transport().clone('foo'))
2466.7.9 by Robert Collins
Return the commited revision id from BranchBuilder.build_commit to save later instrospection.
81
        rev_id1 = builder.build_commit()
82
        rev_id2 = builder.build_commit()
2466.7.6 by Robert Collins
Add BranchBuilder.build_commit.
83
        branch = builder.get_branch()
2466.7.9 by Robert Collins
Return the commited revision id from BranchBuilder.build_commit to save later instrospection.
84
        self.assertEqual((2, rev_id2), branch.last_revision_info())
2466.7.6 by Robert Collins
Add BranchBuilder.build_commit.
85
        self.assertEqual(
86
            'commit 2',
87
            branch.repository.get_revision(branch.last_revision()).message)
88
        self.assertEqual(
2466.7.9 by Robert Collins
Return the commited revision id from BranchBuilder.build_commit to save later instrospection.
89
            [rev_id1],
2466.7.6 by Robert Collins
Add BranchBuilder.build_commit.
90
            branch.repository.get_revision(branch.last_revision()).parent_ids)
3567.4.1 by John Arbash Meinel
Initial work to have BranchBuilder allow us to do tree-shape work.
91
6225.1.1 by Jelmer Vernooij
Add parent_ids argument to BranchBuilder.build_commit.
92
    def test_build_commit_parent_ids(self):
93
        """build_commit() takes a parent_ids argument."""
94
        builder = BranchBuilder(self.get_transport().clone('foo'))
95
        rev_id1 = builder.build_commit(
6973.7.3 by Jelmer Vernooij
Fix some more tests.
96
            parent_ids=[b"ghost"], allow_leftmost_as_ghost=True)
6225.1.1 by Jelmer Vernooij
Add parent_ids argument to BranchBuilder.build_commit.
97
        rev_id2 = builder.build_commit(parent_ids=[])
98
        branch = builder.get_branch()
99
        self.assertEqual((1, rev_id2), branch.last_revision_info())
100
        self.assertEqual(
6973.7.3 by Jelmer Vernooij
Fix some more tests.
101
            [b"ghost"],
6225.1.1 by Jelmer Vernooij
Add parent_ids argument to BranchBuilder.build_commit.
102
            branch.repository.get_revision(rev_id1).parent_ids)
103
3567.4.3 by John Arbash Meinel
Add an action for modifying an existing file
104
105
class TestBranchBuilderBuildSnapshot(tests.TestCaseWithMemoryTransport):
106
107
    def assertTreeShape(self, expected_shape, tree):
108
        """Check that the tree shape matches expectations."""
109
        tree.lock_read()
110
        try:
111
            entries = [(path, ie.file_id, ie.kind)
112
                       for path, ie in tree.iter_entries_by_dir()]
113
        finally:
114
            tree.unlock()
115
        self.assertEqual(expected_shape, entries)
116
117
    def build_a_rev(self):
3567.4.1 by John Arbash Meinel
Initial work to have BranchBuilder allow us to do tree-shape work.
118
        builder = BranchBuilder(self.get_transport().clone('foo'))
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
119
        rev_id1 = builder.build_snapshot(None,
6973.7.3 by Jelmer Vernooij
Fix some more tests.
120
            [('add', ('', b'a-root-id', 'directory', None)),
121
             ('add', ('a', b'a-id', 'file', b'contents'))],
6973.5.2 by Jelmer Vernooij
Add more bees.
122
            revision_id=b'A-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
123
        self.assertEqual(b'A-id', rev_id1)
3567.4.3 by John Arbash Meinel
Add an action for modifying an existing file
124
        return builder
125
126
    def test_add_one_file(self):
127
        builder = self.build_a_rev()
3567.4.1 by John Arbash Meinel
Initial work to have BranchBuilder allow us to do tree-shape work.
128
        branch = builder.get_branch()
6973.7.3 by Jelmer Vernooij
Fix some more tests.
129
        self.assertEqual((1, b'A-id'), branch.last_revision_info())
6973.5.2 by Jelmer Vernooij
Add more bees.
130
        rev_tree = branch.repository.revision_tree(b'A-id')
3567.4.1 by John Arbash Meinel
Initial work to have BranchBuilder allow us to do tree-shape work.
131
        rev_tree.lock_read()
132
        self.addCleanup(rev_tree.unlock)
6973.7.3 by Jelmer Vernooij
Fix some more tests.
133
        self.assertTreeShape([(u'', b'a-root-id', 'directory'),
134
                              (u'a', b'a-id', 'file')], rev_tree)
135
        self.assertEqual(b'contents', rev_tree.get_file_text('a'))
3567.4.2 by John Arbash Meinel
test that we can add more files into an existing build
136
3567.4.3 by John Arbash Meinel
Add an action for modifying an existing file
137
    def test_add_second_file(self):
138
        builder = self.build_a_rev()
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
139
        rev_id2 = builder.build_snapshot(None,
6973.7.3 by Jelmer Vernooij
Fix some more tests.
140
            [('add', ('b', b'b-id', 'file', b'content_b'))],
6973.5.2 by Jelmer Vernooij
Add more bees.
141
            revision_id=b'B-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
142
        self.assertEqual(b'B-id', rev_id2)
3567.4.2 by John Arbash Meinel
test that we can add more files into an existing build
143
        branch = builder.get_branch()
144
        self.assertEqual((2, rev_id2), branch.last_revision_info())
145
        rev_tree = branch.repository.revision_tree(rev_id2)
146
        rev_tree.lock_read()
147
        self.addCleanup(rev_tree.unlock)
6973.7.3 by Jelmer Vernooij
Fix some more tests.
148
        self.assertTreeShape([(u'', b'a-root-id', 'directory'),
149
                              (u'a', b'a-id', 'file'),
150
                              (u'b', b'b-id', 'file')], rev_tree)
151
        self.assertEqual(b'content_b', rev_tree.get_file_text('b'))
3567.4.3 by John Arbash Meinel
Add an action for modifying an existing file
152
3567.4.7 by John Arbash Meinel
Revert back to using MemoryTree.mkdir() rather than creating the directory during add().
153
    def test_add_empty_dir(self):
154
        builder = self.build_a_rev()
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
155
        rev_id2 = builder.build_snapshot(None,
6973.10.1 by Jelmer Vernooij
Fix some tests.
156
            [('add', ('b', b'b-id', 'directory', None))],
6973.5.2 by Jelmer Vernooij
Add more bees.
157
            revision_id=b'B-id')
158
        rev_tree = builder.get_branch().repository.revision_tree(b'B-id')
6973.10.1 by Jelmer Vernooij
Fix some tests.
159
        self.assertTreeShape([(u'', b'a-root-id', 'directory'),
160
                              (u'a', b'a-id', 'file'),
161
                              (u'b', b'b-id', 'directory'),
3567.4.7 by John Arbash Meinel
Revert back to using MemoryTree.mkdir() rather than creating the directory during add().
162
                             ], rev_tree)
163
4070.5.1 by Martin Pool
BranchBuilder now takes a timestamp for commits
164
    def test_commit_timestamp(self):
165
        builder = self.make_branch_builder('foo')
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
166
        rev_id = builder.build_snapshot(None,
4070.5.1 by Martin Pool
BranchBuilder now takes a timestamp for commits
167
            [('add', (u'', None, 'directory', None))],
168
            timestamp=1234567890)
169
        rev = builder.get_branch().repository.get_revision(rev_id)
170
        self.assertEqual(
171
            1234567890,
172
            int(rev.timestamp))
173
3567.4.15 by John Arbash Meinel
Allow setting the commit message.
174
    def test_commit_message_default(self):
175
        builder = BranchBuilder(self.get_transport().clone('foo'))
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
176
        rev_id = builder.build_snapshot(None,
3567.4.15 by John Arbash Meinel
Allow setting the commit message.
177
            [('add', (u'', None, 'directory', None))])
178
        branch = builder.get_branch()
179
        rev = branch.repository.get_revision(rev_id)
180
        self.assertEqual(u'commit 1', rev.message)
181
182
    def test_commit_message_supplied(self):
183
        builder = BranchBuilder(self.get_transport().clone('foo'))
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
184
        rev_id = builder.build_snapshot(None,
3567.4.15 by John Arbash Meinel
Allow setting the commit message.
185
            [('add', (u'', None, 'directory', None))],
186
            message=u'Foo')
187
        branch = builder.get_branch()
188
        rev = branch.repository.get_revision(rev_id)
189
        self.assertEqual(u'Foo', rev.message)
190
5060.1.1 by Robert Collins
``bzrlib.branchbuilder.BranchBuilder.build_snapshot`` now accepts a
191
    def test_commit_message_callback(self):
192
        builder = BranchBuilder(self.get_transport().clone('foo'))
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
193
        rev_id = builder.build_snapshot(None,
5060.1.1 by Robert Collins
``bzrlib.branchbuilder.BranchBuilder.build_snapshot`` now accepts a
194
            [('add', (u'', None, 'directory', None))],
195
            message_callback=lambda x:u'Foo')
196
        branch = builder.get_branch()
197
        rev = branch.repository.get_revision(rev_id)
198
        self.assertEqual(u'Foo', rev.message)
199
3567.4.3 by John Arbash Meinel
Add an action for modifying an existing file
200
    def test_modify_file(self):
201
        builder = self.build_a_rev()
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
202
        rev_id2 = builder.build_snapshot(None,
6973.7.3 by Jelmer Vernooij
Fix some more tests.
203
            [('modify', ('a', b'new\ncontent\n'))],
6973.5.2 by Jelmer Vernooij
Add more bees.
204
            revision_id=b'B-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
205
        self.assertEqual(b'B-id', rev_id2)
3567.4.3 by John Arbash Meinel
Add an action for modifying an existing file
206
        branch = builder.get_branch()
207
        rev_tree = branch.repository.revision_tree(rev_id2)
208
        rev_tree.lock_read()
209
        self.addCleanup(rev_tree.unlock)
6973.7.3 by Jelmer Vernooij
Fix some more tests.
210
        self.assertEqual(b'new\ncontent\n',
6855.4.1 by Jelmer Vernooij
Yet more bees.
211
                         rev_tree.get_file_text(rev_tree.id2path(b'a-id')))
3567.4.4 by John Arbash Meinel
Add the ability to 'unversion' files, and handle unknown actions.
212
213
    def test_delete_file(self):
214
        builder = self.build_a_rev()
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
215
        rev_id2 = builder.build_snapshot(None,
6973.5.2 by Jelmer Vernooij
Add more bees.
216
            [('unversion', 'a')], revision_id=b'B-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
217
        self.assertEqual(b'B-id', rev_id2)
3567.4.4 by John Arbash Meinel
Add the ability to 'unversion' files, and handle unknown actions.
218
        branch = builder.get_branch()
219
        rev_tree = branch.repository.revision_tree(rev_id2)
220
        rev_tree.lock_read()
221
        self.addCleanup(rev_tree.unlock)
6973.7.3 by Jelmer Vernooij
Fix some more tests.
222
        self.assertTreeShape([(u'', b'a-root-id', 'directory')], rev_tree)
3567.4.4 by John Arbash Meinel
Add the ability to 'unversion' files, and handle unknown actions.
223
3567.4.5 by John Arbash Meinel
MemoryTree.add(directory) will now create a directory node in the Transport
224
    def test_delete_directory(self):
225
        builder = self.build_a_rev()
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
226
        rev_id2 = builder.build_snapshot(None,
6973.7.3 by Jelmer Vernooij
Fix some more tests.
227
            [('add', ('b', b'b-id', 'directory', None)),
228
             ('add', ('b/c', b'c-id', 'file', b'foo\n')),
229
             ('add', ('b/d', b'd-id', 'directory', None)),
230
             ('add', ('b/d/e', b'e-id', 'file', b'eff\n')),
6973.5.2 by Jelmer Vernooij
Add more bees.
231
            ], revision_id=b'B-id')
232
        rev_tree = builder.get_branch().repository.revision_tree(b'B-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
233
        self.assertTreeShape([(u'', b'a-root-id', 'directory'),
234
                              (u'a', b'a-id', 'file'),
235
                              (u'b', b'b-id', 'directory'),
236
                              (u'b/c', b'c-id', 'file'),
237
                              (u'b/d', b'd-id', 'directory'),
238
                              (u'b/d/e', b'e-id', 'file')], rev_tree)
3567.4.6 by John Arbash Meinel
unversioning a directory is recursive.
239
        # Removing a directory removes all child dirs
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
240
        builder.build_snapshot(
6883.22.1 by Jelmer Vernooij
Take paths in BranchBuilder.
241
                None, [('unversion', 'b')],
6973.5.2 by Jelmer Vernooij
Add more bees.
242
                revision_id=b'C-id')
243
        rev_tree = builder.get_branch().repository.revision_tree(b'C-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
244
        self.assertTreeShape([(u'', b'a-root-id', 'directory'),
245
                              (u'a', b'a-id', 'file'),
3567.4.6 by John Arbash Meinel
unversioning a directory is recursive.
246
                             ], rev_tree)
3567.4.5 by John Arbash Meinel
MemoryTree.add(directory) will now create a directory node in the Transport
247
3567.4.4 by John Arbash Meinel
Add the ability to 'unversion' files, and handle unknown actions.
248
    def test_unknown_action(self):
249
        builder = self.build_a_rev()
3567.4.18 by John Arbash Meinel
Apply the review changes from Martin to the exact patch he approved.
250
        e = self.assertRaises(ValueError,
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
251
            builder.build_snapshot, None, [('weirdo', ('foo',))],
6973.5.2 by Jelmer Vernooij
Add more bees.
252
            revision_id=b'B-id')
3567.4.18 by John Arbash Meinel
Apply the review changes from Martin to the exact patch he approved.
253
        self.assertEqual('Unknown build action: "weirdo"', str(e))
3567.4.8 by John Arbash Meinel
Add the ability to force a basis for a revision.
254
3567.5.1 by John Arbash Meinel
Implement rename_one on MemoryTree, and expose that in the Branch Builder
255
    def test_rename(self):
256
        builder = self.build_a_rev()
6816.2.3 by Jelmer Vernooij
Port over last uses of build_snapshot.
257
        builder.build_snapshot(None,
6973.5.2 by Jelmer Vernooij
Add more bees.
258
            [('rename', ('a', 'b'))], revision_id=b'B-id')
259
        rev_tree = builder.get_branch().repository.revision_tree(b'B-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
260
        self.assertTreeShape([(u'', b'a-root-id', 'directory'),
261
                              (u'b', b'a-id', 'file')], rev_tree)
3567.5.1 by John Arbash Meinel
Implement rename_one on MemoryTree, and expose that in the Branch Builder
262
263
    def test_rename_into_subdir(self):
264
        builder = self.build_a_rev()
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
265
        builder.build_snapshot(None,
6973.7.3 by Jelmer Vernooij
Fix some more tests.
266
            [('add', ('dir', b'dir-id', 'directory', None)),
6973.5.2 by Jelmer Vernooij
Add more bees.
267
             ('rename', ('a', 'dir/a'))], revision_id=b'B-id')
268
        rev_tree = builder.get_branch().repository.revision_tree(b'B-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
269
        self.assertTreeShape([(u'', b'a-root-id', 'directory'),
270
                              (u'dir', b'dir-id', 'directory'),
271
                              (u'dir/a', b'a-id', 'file')], rev_tree)
3567.4.8 by John Arbash Meinel
Add the ability to force a basis for a revision.
272
6008.2.1 by Andrew Bennetts
Allow renaming entries out of a dir and unversioning a dir in the one build_snapshot call.
273
    def test_rename_out_of_unversioned_subdir(self):
274
        builder = self.build_a_rev()
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
275
        builder.build_snapshot(None,
6973.7.3 by Jelmer Vernooij
Fix some more tests.
276
            [('add', ('dir', b'dir-id', 'directory', None)),
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
277
             ('rename', ('a', 'dir/a'))],
6973.5.2 by Jelmer Vernooij
Add more bees.
278
            revision_id=b'B-id')
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
279
        builder.build_snapshot(None,
6008.2.1 by Andrew Bennetts
Allow renaming entries out of a dir and unversioning a dir in the one build_snapshot call.
280
            [('rename', ('dir/a', 'a')),
6973.5.2 by Jelmer Vernooij
Add more bees.
281
             ('unversion', 'dir')], revision_id=b'C-id')
282
        rev_tree = builder.get_branch().repository.revision_tree(b'C-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
283
        self.assertTreeShape([(u'', b'a-root-id', 'directory'),
284
                              (u'a', b'a-id', 'file')], rev_tree)
6008.2.1 by Andrew Bennetts
Allow renaming entries out of a dir and unversioning a dir in the one build_snapshot call.
285
3567.4.8 by John Arbash Meinel
Add the ability to force a basis for a revision.
286
    def test_set_parent(self):
287
        builder = self.build_a_rev()
3567.4.17 by John Arbash Meinel
Add the ability to define a series of commits, which allows us to hold open the locks.
288
        builder.start_series()
289
        self.addCleanup(builder.finish_series)
6973.7.3 by Jelmer Vernooij
Fix some more tests.
290
        builder.build_snapshot([b'A-id'],
291
            [('modify', ('a', b'new\ncontent\n'))],
6973.5.2 by Jelmer Vernooij
Add more bees.
292
            revision_id=b'B-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
293
        builder.build_snapshot([b'A-id'],
294
            [('add', ('c', b'c-id', 'file', b'alt\ncontent\n'))],
6973.5.2 by Jelmer Vernooij
Add more bees.
295
            revision_id=b'C-id')
3567.4.8 by John Arbash Meinel
Add the ability to force a basis for a revision.
296
        # We should now have a graph:
297
        #   A
298
        #   |\
299
        #   C B
300
        # And not A => B => C
301
        repo = builder.get_branch().repository
6973.7.3 by Jelmer Vernooij
Fix some more tests.
302
        self.assertEqual({b'B-id': (b'A-id',), b'C-id': (b'A-id',)},
303
                         repo.get_parent_map([b'B-id', b'C-id']))
6973.5.2 by Jelmer Vernooij
Add more bees.
304
        b_tree = repo.revision_tree(b'B-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
305
        self.assertTreeShape([(u'', b'a-root-id', 'directory'),
306
                              (u'a', b'a-id', 'file'),
3567.4.8 by John Arbash Meinel
Add the ability to force a basis for a revision.
307
                             ], b_tree)
6973.7.3 by Jelmer Vernooij
Fix some more tests.
308
        self.assertEqual(b'new\ncontent\n', b_tree.get_file_text('a'))
3567.4.8 by John Arbash Meinel
Add the ability to force a basis for a revision.
309
310
        # We should still be using the content from A in C, not from B
6973.5.2 by Jelmer Vernooij
Add more bees.
311
        c_tree = repo.revision_tree(b'C-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
312
        self.assertTreeShape([(u'', b'a-root-id', 'directory'),
313
                              (u'a', b'a-id', 'file'),
314
                              (u'c', b'c-id', 'file'),
3567.4.8 by John Arbash Meinel
Add the ability to force a basis for a revision.
315
                             ], c_tree)
6973.7.3 by Jelmer Vernooij
Fix some more tests.
316
        self.assertEqual(b'contents', c_tree.get_file_text('a'))
317
        self.assertEqual(b'alt\ncontent\n', c_tree.get_file_text('c'))
3567.4.8 by John Arbash Meinel
Add the ability to force a basis for a revision.
318
319
    def test_set_merge_parent(self):
320
        builder = self.build_a_rev()
3567.4.17 by John Arbash Meinel
Add the ability to define a series of commits, which allows us to hold open the locks.
321
        builder.start_series()
322
        self.addCleanup(builder.finish_series)
6973.7.3 by Jelmer Vernooij
Fix some more tests.
323
        builder.build_snapshot([b'A-id'],
324
            [('add', ('b', b'b-id', 'file', b'b\ncontent\n'))],
6973.5.2 by Jelmer Vernooij
Add more bees.
325
            revision_id=b'B-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
326
        builder.build_snapshot([b'A-id'],
327
            [('add', ('c', b'c-id', 'file', b'alt\ncontent\n'))],
6973.5.2 by Jelmer Vernooij
Add more bees.
328
            revision_id=b'C-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
329
        builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
3567.4.8 by John Arbash Meinel
Add the ability to force a basis for a revision.
330
        repo = builder.get_branch().repository
6973.7.3 by Jelmer Vernooij
Fix some more tests.
331
        self.assertEqual({b'B-id': (b'A-id',), b'C-id': (b'A-id',),
332
                          b'D-id': (b'B-id', b'C-id')},
333
                         repo.get_parent_map([b'B-id', b'C-id', b'D-id']))
6973.5.2 by Jelmer Vernooij
Add more bees.
334
        d_tree = repo.revision_tree(b'D-id')
3567.4.8 by John Arbash Meinel
Add the ability to force a basis for a revision.
335
        # Note: by default a merge node does *not* pull in the changes from the
336
        #       merged tree, you have to supply it yourself.
6973.7.3 by Jelmer Vernooij
Fix some more tests.
337
        self.assertTreeShape([(u'', b'a-root-id', 'directory'),
338
                              (u'a', b'a-id', 'file'),
339
                              (u'b', b'b-id', 'file'),
3567.4.8 by John Arbash Meinel
Add the ability to force a basis for a revision.
340
                             ], d_tree)
341
342
    def test_set_merge_parent_and_contents(self):
343
        builder = self.build_a_rev()
3567.4.17 by John Arbash Meinel
Add the ability to define a series of commits, which allows us to hold open the locks.
344
        builder.start_series()
345
        self.addCleanup(builder.finish_series)
6973.7.3 by Jelmer Vernooij
Fix some more tests.
346
        builder.build_snapshot([b'A-id'],
347
            [('add', ('b', b'b-id', 'file', b'b\ncontent\n'))],
6973.5.2 by Jelmer Vernooij
Add more bees.
348
            revision_id=b'B-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
349
        builder.build_snapshot([b'A-id'],
350
            [('add', ('c', b'c-id', 'file', b'alt\ncontent\n'))],
6973.5.2 by Jelmer Vernooij
Add more bees.
351
            revision_id=b'C-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
352
        builder.build_snapshot([b'B-id', b'C-id'],
353
            [('add', ('c', b'c-id', 'file', b'alt\ncontent\n'))],
6973.5.2 by Jelmer Vernooij
Add more bees.
354
            revision_id=b'D-id')
3567.4.8 by John Arbash Meinel
Add the ability to force a basis for a revision.
355
        repo = builder.get_branch().repository
6973.7.3 by Jelmer Vernooij
Fix some more tests.
356
        self.assertEqual({b'B-id': (b'A-id',), b'C-id': (b'A-id',),
357
                          b'D-id': (b'B-id', b'C-id')},
358
                         repo.get_parent_map([b'B-id', b'C-id', b'D-id']))
6973.5.2 by Jelmer Vernooij
Add more bees.
359
        d_tree = repo.revision_tree(b'D-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
360
        self.assertTreeShape([(u'', b'a-root-id', 'directory'),
361
                              (u'a', b'a-id', 'file'),
362
                              (u'b', b'b-id', 'file'),
363
                              (u'c', b'c-id', 'file'),
3567.4.8 by John Arbash Meinel
Add the ability to force a basis for a revision.
364
                             ], d_tree)
365
        # Because we copied the exact text into *this* tree, the 'c' file
366
        # should look like it was not modified in the merge
6973.7.3 by Jelmer Vernooij
Fix some more tests.
367
        self.assertEqual(b'C-id', d_tree.get_file_revision('c'))
3567.4.17 by John Arbash Meinel
Add the ability to define a series of commits, which allows us to hold open the locks.
368
5540.1.1 by Gary van der Merwe
Make ``BranchBuilder.build_snapshot`` accept parent_ids == ['null:'].
369
    def test_set_parent_to_null(self):
370
        builder = self.build_a_rev()
371
        builder.start_series()
372
        self.addCleanup(builder.finish_series)
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
373
        builder.build_snapshot([],
374
            [('add', ('', None, 'directory', None))],
6973.5.2 by Jelmer Vernooij
Add more bees.
375
            revision_id=b'B-id')
5540.1.1 by Gary van der Merwe
Make ``BranchBuilder.build_snapshot`` accept parent_ids == ['null:'].
376
        # We should now have a graph:
377
        #   A B
378
        # And not A => B
379
        repo = builder.get_branch().repository
6973.7.3 by Jelmer Vernooij
Fix some more tests.
380
        self.assertEqual({b'A-id': (_mod_revision.NULL_REVISION,),
381
                          b'B-id': (_mod_revision.NULL_REVISION,),},
382
                         repo.get_parent_map([b'A-id', b'B-id']))
5540.1.1 by Gary van der Merwe
Make ``BranchBuilder.build_snapshot`` accept parent_ids == ['null:'].
383
3567.4.17 by John Arbash Meinel
Add the ability to define a series of commits, which allows us to hold open the locks.
384
    def test_start_finish_series(self):
385
        builder = BranchBuilder(self.get_transport().clone('foo'))
386
        builder.start_series()
387
        try:
388
            self.assertIsNot(None, builder._tree)
389
            self.assertEqual('w', builder._tree._lock_mode)
390
            self.assertTrue(builder._branch.is_locked())
391
        finally:
392
            builder.finish_series()
393
        self.assertIs(None, builder._tree)
394
        self.assertFalse(builder._branch.is_locked())
4324.3.1 by Robert Collins
When adding rich root data follow the standard revision graph rules, so it does not create 'inconstent parents'.
395
396
    def test_ghost_mainline_history(self):
397
        builder = BranchBuilder(self.get_transport().clone('foo'))
398
        builder.start_series()
399
        try:
6973.7.3 by Jelmer Vernooij
Fix some more tests.
400
            builder.build_snapshot([b'ghost'],
401
                [('add', ('', b'ROOT_ID', 'directory', ''))],
6973.5.2 by Jelmer Vernooij
Add more bees.
402
                allow_leftmost_as_ghost=True, revision_id=b'tip')
4324.3.1 by Robert Collins
When adding rich root data follow the standard revision graph rules, so it does not create 'inconstent parents'.
403
        finally:
404
            builder.finish_series()
405
        b = builder.get_branch()
406
        b.lock_read()
407
        self.addCleanup(b.unlock)
6973.7.3 by Jelmer Vernooij
Fix some more tests.
408
        self.assertEqual((b'ghost',),
409
            b.repository.get_graph().get_parent_map([b'tip'])[b'tip'])
6008.2.2 by Andrew Bennetts
Add unit test for regression.
410
411
    def test_unversion_root_add_new_root(self):
412
        builder = BranchBuilder(self.get_transport().clone('foo'))
413
        builder.start_series()
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
414
        builder.build_snapshot(None,
6973.7.3 by Jelmer Vernooij
Fix some more tests.
415
            [('add', ('', b'TREE_ROOT', 'directory', ''))],
6973.5.2 by Jelmer Vernooij
Add more bees.
416
            revision_id=b'rev-1')
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
417
        builder.build_snapshot(None,
6883.22.1 by Jelmer Vernooij
Take paths in BranchBuilder.
418
            [('unversion', ''),
6973.7.3 by Jelmer Vernooij
Fix some more tests.
419
             ('add', ('', b'my-root', 'directory', ''))],
6973.5.2 by Jelmer Vernooij
Add more bees.
420
            revision_id=b'rev-2')
6008.2.2 by Andrew Bennetts
Add unit test for regression.
421
        builder.finish_series()
6973.5.2 by Jelmer Vernooij
Add more bees.
422
        rev_tree = builder.get_branch().repository.revision_tree(b'rev-2')
6973.10.1 by Jelmer Vernooij
Fix some tests.
423
        self.assertTreeShape([(u'', b'my-root', 'directory')], rev_tree)
6008.2.2 by Andrew Bennetts
Add unit test for regression.
424
6008.2.5 by Andrew Bennetts
Rename 'checkpoint' to 'flush', add some unit tests and more comments.
425
    def test_empty_flush(self):
426
        """A flush with no actions before it is a no-op."""
427
        builder = BranchBuilder(self.get_transport().clone('foo'))
428
        builder.start_series()
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
429
        builder.build_snapshot(None,
6973.7.3 by Jelmer Vernooij
Fix some more tests.
430
            [('add', ('', b'TREE_ROOT', 'directory', ''))],
6973.5.2 by Jelmer Vernooij
Add more bees.
431
            revision_id=b'rev-1')
432
        builder.build_snapshot(None, [('flush', None)], revision_id=b'rev-2')
6008.2.5 by Andrew Bennetts
Rename 'checkpoint' to 'flush', add some unit tests and more comments.
433
        builder.finish_series()
6973.5.2 by Jelmer Vernooij
Add more bees.
434
        rev_tree = builder.get_branch().repository.revision_tree(b'rev-2')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
435
        self.assertTreeShape([(u'', b'TREE_ROOT', 'directory')], rev_tree)
6008.2.5 by Andrew Bennetts
Rename 'checkpoint' to 'flush', add some unit tests and more comments.
436
437
    def test_kind_change(self):
438
        """It's possible to change the kind of an entry in a single snapshot
439
        with a bit of help from the 'flush' action.
440
        """
441
        builder = BranchBuilder(self.get_transport().clone('foo'))
442
        builder.start_series()
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
443
        builder.build_snapshot(None,
6973.7.3 by Jelmer Vernooij
Fix some more tests.
444
            [('add', (u'', b'a-root-id', 'directory', None)),
6973.10.1 by Jelmer Vernooij
Fix some tests.
445
             ('add', (u'a', b'a-id', 'file', b'content\n'))],
6973.5.2 by Jelmer Vernooij
Add more bees.
446
            revision_id=b'A-id')
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
447
        builder.build_snapshot(None,
6883.22.1 by Jelmer Vernooij
Take paths in BranchBuilder.
448
            [('unversion', 'a'),
6008.2.5 by Andrew Bennetts
Rename 'checkpoint' to 'flush', add some unit tests and more comments.
449
             ('flush', None),
6973.7.3 by Jelmer Vernooij
Fix some more tests.
450
             ('add', (u'a', b'a-id', 'directory', None))],
6973.5.2 by Jelmer Vernooij
Add more bees.
451
            revision_id=b'B-id')
6008.2.5 by Andrew Bennetts
Rename 'checkpoint' to 'flush', add some unit tests and more comments.
452
        builder.finish_series()
6973.5.2 by Jelmer Vernooij
Add more bees.
453
        rev_tree = builder.get_branch().repository.revision_tree(b'B-id')
6008.2.5 by Andrew Bennetts
Rename 'checkpoint' to 'flush', add some unit tests and more comments.
454
        self.assertTreeShape(
6973.7.3 by Jelmer Vernooij
Fix some more tests.
455
            [(u'', b'a-root-id', 'directory'), (u'a', b'a-id', 'directory')],
6008.2.5 by Andrew Bennetts
Rename 'checkpoint' to 'flush', add some unit tests and more comments.
456
            rev_tree)
457
458
    def test_pivot_root(self):
459
        """It's possible (albeit awkward) to move an existing dir to the root
460
        in a single snapshot by using unversion then flush then add.
461
        """
462
        builder = BranchBuilder(self.get_transport().clone('foo'))
463
        builder.start_series()
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
464
        builder.build_snapshot(None,
6973.7.3 by Jelmer Vernooij
Fix some more tests.
465
            [('add', (u'', b'orig-root', 'directory', None)),
466
             ('add', (u'dir', b'dir-id', 'directory', None))],
6973.5.2 by Jelmer Vernooij
Add more bees.
467
            revision_id=b'A-id')
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
468
        builder.build_snapshot(None,
6883.22.1 by Jelmer Vernooij
Take paths in BranchBuilder.
469
            [('unversion', ''),  # implicitly unversions all children
6008.2.5 by Andrew Bennetts
Rename 'checkpoint' to 'flush', add some unit tests and more comments.
470
             ('flush', None),
6973.7.3 by Jelmer Vernooij
Fix some more tests.
471
             ('add', (u'', b'dir-id', 'directory', None))],
6973.5.2 by Jelmer Vernooij
Add more bees.
472
            revision_id=b'B-id')
6008.2.5 by Andrew Bennetts
Rename 'checkpoint' to 'flush', add some unit tests and more comments.
473
        builder.finish_series()
6973.5.2 by Jelmer Vernooij
Add more bees.
474
        rev_tree = builder.get_branch().repository.revision_tree(b'B-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
475
        self.assertTreeShape([(u'', b'dir-id', 'directory')], rev_tree)
6008.2.5 by Andrew Bennetts
Rename 'checkpoint' to 'flush', add some unit tests and more comments.
476