/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,
7143.15.2 by Jelmer Vernooij
Run autopep8.
43
                         branch.base)
2466.7.4 by Robert Collins
Add BranchBuilder.get_branch().
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,
7143.15.2 by Jelmer Vernooij
Run autopep8.
120
                                         [('add', ('', b'a-root-id', 'directory', None)),
121
                                          ('add', ('a', b'a-id', 'file', b'contents'))],
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,
7143.15.2 by Jelmer Vernooij
Run autopep8.
140
                                         [('add', ('b', b'b-id', 'file', b'content_b'))],
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,
7143.15.2 by Jelmer Vernooij
Run autopep8.
156
                                         [('add', ('b', b'b-id', 'directory', None))],
157
                                         revision_id=b'B-id')
6973.5.2 by Jelmer Vernooij
Add more bees.
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'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
162
                              ], rev_tree)
3567.4.7 by John Arbash Meinel
Revert back to using MemoryTree.mkdir() rather than creating the directory during add().
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,
7143.15.2 by Jelmer Vernooij
Run autopep8.
167
                                        [('add', (u'', None, 'directory', None))],
168
                                        timestamp=1234567890)
4070.5.1 by Martin Pool
BranchBuilder now takes a timestamp for commits
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,
7143.15.2 by Jelmer Vernooij
Run autopep8.
177
                                        [('add', (u'', None, 'directory', None))])
3567.4.15 by John Arbash Meinel
Allow setting the commit message.
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,
7143.15.2 by Jelmer Vernooij
Run autopep8.
185
                                        [('add', (u'', None, 'directory', None))],
186
                                        message=u'Foo')
3567.4.15 by John Arbash Meinel
Allow setting the commit message.
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,
7143.15.2 by Jelmer Vernooij
Run autopep8.
194
                                        [('add', (u'', None, 'directory', None))],
195
                                        message_callback=lambda x: u'Foo')
5060.1.1 by Robert Collins
``bzrlib.branchbuilder.BranchBuilder.build_snapshot`` now accepts a
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,
7143.15.2 by Jelmer Vernooij
Run autopep8.
203
                                         [('modify', ('a', b'new\ncontent\n'))],
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,
7143.15.2 by Jelmer Vernooij
Run autopep8.
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,
7143.15.2 by Jelmer Vernooij
Run autopep8.
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',
230
                                                      'directory', None)),
231
                                             ('add', ('b/d/e', b'e-id',
232
                                                      'file', b'eff\n')),
233
                                          ], revision_id=b'B-id')
6973.5.2 by Jelmer Vernooij
Add more bees.
234
        rev_tree = builder.get_branch().repository.revision_tree(b'B-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
235
        self.assertTreeShape([(u'', b'a-root-id', 'directory'),
236
                              (u'a', b'a-id', 'file'),
237
                              (u'b', b'b-id', 'directory'),
238
                              (u'b/c', b'c-id', 'file'),
239
                              (u'b/d', b'd-id', 'directory'),
240
                              (u'b/d/e', b'e-id', 'file')], rev_tree)
3567.4.6 by John Arbash Meinel
unversioning a directory is recursive.
241
        # 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.
242
        builder.build_snapshot(
7143.15.2 by Jelmer Vernooij
Run autopep8.
243
            None, [('unversion', 'b')],
244
            revision_id=b'C-id')
6973.5.2 by Jelmer Vernooij
Add more bees.
245
        rev_tree = builder.get_branch().repository.revision_tree(b'C-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
246
        self.assertTreeShape([(u'', b'a-root-id', 'directory'),
247
                              (u'a', b'a-id', 'file'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
248
                              ], rev_tree)
3567.4.5 by John Arbash Meinel
MemoryTree.add(directory) will now create a directory node in the Transport
249
3567.4.4 by John Arbash Meinel
Add the ability to 'unversion' files, and handle unknown actions.
250
    def test_unknown_action(self):
251
        builder = self.build_a_rev()
3567.4.18 by John Arbash Meinel
Apply the review changes from Martin to the exact patch he approved.
252
        e = self.assertRaises(ValueError,
7143.15.2 by Jelmer Vernooij
Run autopep8.
253
                              builder.build_snapshot, None, [
254
                                  ('weirdo', ('foo',))],
255
                              revision_id=b'B-id')
3567.4.18 by John Arbash Meinel
Apply the review changes from Martin to the exact patch he approved.
256
        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.
257
3567.5.1 by John Arbash Meinel
Implement rename_one on MemoryTree, and expose that in the Branch Builder
258
    def test_rename(self):
259
        builder = self.build_a_rev()
6816.2.3 by Jelmer Vernooij
Port over last uses of build_snapshot.
260
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
261
                               [('rename', ('a', 'b'))], revision_id=b'B-id')
6973.5.2 by Jelmer Vernooij
Add more bees.
262
        rev_tree = builder.get_branch().repository.revision_tree(b'B-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
263
        self.assertTreeShape([(u'', b'a-root-id', 'directory'),
264
                              (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
265
266
    def test_rename_into_subdir(self):
267
        builder = self.build_a_rev()
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
268
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
269
                               [('add', ('dir', b'dir-id', 'directory', None)),
270
                                ('rename', ('a', 'dir/a'))], revision_id=b'B-id')
6973.5.2 by Jelmer Vernooij
Add more bees.
271
        rev_tree = builder.get_branch().repository.revision_tree(b'B-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
272
        self.assertTreeShape([(u'', b'a-root-id', 'directory'),
273
                              (u'dir', b'dir-id', 'directory'),
274
                              (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.
275
6008.2.1 by Andrew Bennetts
Allow renaming entries out of a dir and unversioning a dir in the one build_snapshot call.
276
    def test_rename_out_of_unversioned_subdir(self):
277
        builder = self.build_a_rev()
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
278
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
279
                               [('add', ('dir', b'dir-id', 'directory', None)),
280
                                ('rename', ('a', 'dir/a'))],
281
                               revision_id=b'B-id')
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
282
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
283
                               [('rename', ('dir/a', 'a')),
284
                                ('unversion', 'dir')], revision_id=b'C-id')
6973.5.2 by Jelmer Vernooij
Add more bees.
285
        rev_tree = builder.get_branch().repository.revision_tree(b'C-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
286
        self.assertTreeShape([(u'', b'a-root-id', 'directory'),
287
                              (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.
288
3567.4.8 by John Arbash Meinel
Add the ability to force a basis for a revision.
289
    def test_set_parent(self):
290
        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.
291
        builder.start_series()
292
        self.addCleanup(builder.finish_series)
6973.7.3 by Jelmer Vernooij
Fix some more tests.
293
        builder.build_snapshot([b'A-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
294
                               [('modify', ('a', b'new\ncontent\n'))],
295
                               revision_id=b'B-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
296
        builder.build_snapshot([b'A-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
297
                               [('add', ('c', b'c-id', 'file', b'alt\ncontent\n'))],
298
                               revision_id=b'C-id')
3567.4.8 by John Arbash Meinel
Add the ability to force a basis for a revision.
299
        # We should now have a graph:
300
        #   A
301
        #   |\
302
        #   C B
303
        # And not A => B => C
304
        repo = builder.get_branch().repository
6973.7.3 by Jelmer Vernooij
Fix some more tests.
305
        self.assertEqual({b'B-id': (b'A-id',), b'C-id': (b'A-id',)},
306
                         repo.get_parent_map([b'B-id', b'C-id']))
6973.5.2 by Jelmer Vernooij
Add more bees.
307
        b_tree = repo.revision_tree(b'B-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
308
        self.assertTreeShape([(u'', b'a-root-id', 'directory'),
309
                              (u'a', b'a-id', 'file'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
310
                              ], b_tree)
6973.7.3 by Jelmer Vernooij
Fix some more tests.
311
        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.
312
313
        # We should still be using the content from A in C, not from B
6973.5.2 by Jelmer Vernooij
Add more bees.
314
        c_tree = repo.revision_tree(b'C-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
315
        self.assertTreeShape([(u'', b'a-root-id', 'directory'),
316
                              (u'a', b'a-id', 'file'),
317
                              (u'c', b'c-id', 'file'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
318
                              ], c_tree)
6973.7.3 by Jelmer Vernooij
Fix some more tests.
319
        self.assertEqual(b'contents', c_tree.get_file_text('a'))
320
        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.
321
322
    def test_set_merge_parent(self):
323
        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.
324
        builder.start_series()
325
        self.addCleanup(builder.finish_series)
6973.7.3 by Jelmer Vernooij
Fix some more tests.
326
        builder.build_snapshot([b'A-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
327
                               [('add', ('b', b'b-id', 'file', b'b\ncontent\n'))],
328
                               revision_id=b'B-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
329
        builder.build_snapshot([b'A-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
330
                               [('add', ('c', b'c-id', 'file', b'alt\ncontent\n'))],
331
                               revision_id=b'C-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
332
        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.
333
        repo = builder.get_branch().repository
6973.7.3 by Jelmer Vernooij
Fix some more tests.
334
        self.assertEqual({b'B-id': (b'A-id',), b'C-id': (b'A-id',),
335
                          b'D-id': (b'B-id', b'C-id')},
336
                         repo.get_parent_map([b'B-id', b'C-id', b'D-id']))
6973.5.2 by Jelmer Vernooij
Add more bees.
337
        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.
338
        # Note: by default a merge node does *not* pull in the changes from the
339
        #       merged tree, you have to supply it yourself.
6973.7.3 by Jelmer Vernooij
Fix some more tests.
340
        self.assertTreeShape([(u'', b'a-root-id', 'directory'),
341
                              (u'a', b'a-id', 'file'),
342
                              (u'b', b'b-id', 'file'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
343
                              ], d_tree)
3567.4.8 by John Arbash Meinel
Add the ability to force a basis for a revision.
344
345
    def test_set_merge_parent_and_contents(self):
346
        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.
347
        builder.start_series()
348
        self.addCleanup(builder.finish_series)
6973.7.3 by Jelmer Vernooij
Fix some more tests.
349
        builder.build_snapshot([b'A-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
350
                               [('add', ('b', b'b-id', 'file', b'b\ncontent\n'))],
351
                               revision_id=b'B-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
352
        builder.build_snapshot([b'A-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
353
                               [('add', ('c', b'c-id', 'file', b'alt\ncontent\n'))],
354
                               revision_id=b'C-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
355
        builder.build_snapshot([b'B-id', b'C-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
356
                               [('add', ('c', b'c-id', 'file', b'alt\ncontent\n'))],
357
                               revision_id=b'D-id')
3567.4.8 by John Arbash Meinel
Add the ability to force a basis for a revision.
358
        repo = builder.get_branch().repository
6973.7.3 by Jelmer Vernooij
Fix some more tests.
359
        self.assertEqual({b'B-id': (b'A-id',), b'C-id': (b'A-id',),
360
                          b'D-id': (b'B-id', b'C-id')},
361
                         repo.get_parent_map([b'B-id', b'C-id', b'D-id']))
6973.5.2 by Jelmer Vernooij
Add more bees.
362
        d_tree = repo.revision_tree(b'D-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
363
        self.assertTreeShape([(u'', b'a-root-id', 'directory'),
364
                              (u'a', b'a-id', 'file'),
365
                              (u'b', b'b-id', 'file'),
366
                              (u'c', b'c-id', 'file'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
367
                              ], d_tree)
3567.4.8 by John Arbash Meinel
Add the ability to force a basis for a revision.
368
        # Because we copied the exact text into *this* tree, the 'c' file
369
        # should look like it was not modified in the merge
6973.7.3 by Jelmer Vernooij
Fix some more tests.
370
        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.
371
5540.1.1 by Gary van der Merwe
Make ``BranchBuilder.build_snapshot`` accept parent_ids == ['null:'].
372
    def test_set_parent_to_null(self):
373
        builder = self.build_a_rev()
374
        builder.start_series()
375
        self.addCleanup(builder.finish_series)
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
376
        builder.build_snapshot([],
7143.15.2 by Jelmer Vernooij
Run autopep8.
377
                               [('add', ('', None, 'directory', None))],
378
                               revision_id=b'B-id')
5540.1.1 by Gary van der Merwe
Make ``BranchBuilder.build_snapshot`` accept parent_ids == ['null:'].
379
        # We should now have a graph:
380
        #   A B
381
        # And not A => B
382
        repo = builder.get_branch().repository
6973.7.3 by Jelmer Vernooij
Fix some more tests.
383
        self.assertEqual({b'A-id': (_mod_revision.NULL_REVISION,),
7143.15.2 by Jelmer Vernooij
Run autopep8.
384
                          b'B-id': (_mod_revision.NULL_REVISION,), },
6973.7.3 by Jelmer Vernooij
Fix some more tests.
385
                         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:'].
386
3567.4.17 by John Arbash Meinel
Add the ability to define a series of commits, which allows us to hold open the locks.
387
    def test_start_finish_series(self):
388
        builder = BranchBuilder(self.get_transport().clone('foo'))
389
        builder.start_series()
390
        try:
391
            self.assertIsNot(None, builder._tree)
392
            self.assertEqual('w', builder._tree._lock_mode)
393
            self.assertTrue(builder._branch.is_locked())
394
        finally:
395
            builder.finish_series()
396
        self.assertIs(None, builder._tree)
397
        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'.
398
399
    def test_ghost_mainline_history(self):
400
        builder = BranchBuilder(self.get_transport().clone('foo'))
401
        builder.start_series()
402
        try:
6973.7.3 by Jelmer Vernooij
Fix some more tests.
403
            builder.build_snapshot([b'ghost'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
404
                                   [('add', ('', b'ROOT_ID', 'directory', ''))],
405
                                   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'.
406
        finally:
407
            builder.finish_series()
408
        b = builder.get_branch()
409
        b.lock_read()
410
        self.addCleanup(b.unlock)
6973.7.3 by Jelmer Vernooij
Fix some more tests.
411
        self.assertEqual((b'ghost',),
7143.15.2 by Jelmer Vernooij
Run autopep8.
412
                         b.repository.get_graph().get_parent_map([b'tip'])[b'tip'])
6008.2.2 by Andrew Bennetts
Add unit test for regression.
413
414
    def test_unversion_root_add_new_root(self):
415
        builder = BranchBuilder(self.get_transport().clone('foo'))
416
        builder.start_series()
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
417
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
418
                               [('add', ('', b'TREE_ROOT', 'directory', ''))],
419
                               revision_id=b'rev-1')
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
420
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
421
                               [('unversion', ''),
422
                                ('add', ('', b'my-root', 'directory', ''))],
423
                               revision_id=b'rev-2')
6008.2.2 by Andrew Bennetts
Add unit test for regression.
424
        builder.finish_series()
6973.5.2 by Jelmer Vernooij
Add more bees.
425
        rev_tree = builder.get_branch().repository.revision_tree(b'rev-2')
6973.10.1 by Jelmer Vernooij
Fix some tests.
426
        self.assertTreeShape([(u'', b'my-root', 'directory')], rev_tree)
6008.2.2 by Andrew Bennetts
Add unit test for regression.
427
6008.2.5 by Andrew Bennetts
Rename 'checkpoint' to 'flush', add some unit tests and more comments.
428
    def test_empty_flush(self):
429
        """A flush with no actions before it is a no-op."""
430
        builder = BranchBuilder(self.get_transport().clone('foo'))
431
        builder.start_series()
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
432
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
433
                               [('add', ('', b'TREE_ROOT', 'directory', ''))],
434
                               revision_id=b'rev-1')
6973.5.2 by Jelmer Vernooij
Add more bees.
435
        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.
436
        builder.finish_series()
6973.5.2 by Jelmer Vernooij
Add more bees.
437
        rev_tree = builder.get_branch().repository.revision_tree(b'rev-2')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
438
        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.
439
440
    def test_kind_change(self):
441
        """It's possible to change the kind of an entry in a single snapshot
442
        with a bit of help from the 'flush' action.
443
        """
444
        builder = BranchBuilder(self.get_transport().clone('foo'))
445
        builder.start_series()
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
446
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
447
                               [('add', (u'', b'a-root-id', 'directory', None)),
448
                                ('add', (u'a', b'a-id', 'file', b'content\n'))],
449
                               revision_id=b'A-id')
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
450
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
451
                               [('unversion', 'a'),
452
                                ('flush', None),
453
                                   ('add', (u'a', b'a-id', 'directory', None))],
454
                               revision_id=b'B-id')
6008.2.5 by Andrew Bennetts
Rename 'checkpoint' to 'flush', add some unit tests and more comments.
455
        builder.finish_series()
6973.5.2 by Jelmer Vernooij
Add more bees.
456
        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.
457
        self.assertTreeShape(
6973.7.3 by Jelmer Vernooij
Fix some more tests.
458
            [(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.
459
            rev_tree)
460
461
    def test_pivot_root(self):
462
        """It's possible (albeit awkward) to move an existing dir to the root
463
        in a single snapshot by using unversion then flush then add.
464
        """
465
        builder = BranchBuilder(self.get_transport().clone('foo'))
466
        builder.start_series()
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
467
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
468
                               [('add', (u'', b'orig-root', 'directory', None)),
469
                                ('add', (u'dir', b'dir-id', 'directory', None))],
470
                               revision_id=b'A-id')
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
471
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
472
                               [('unversion', ''),  # implicitly unversions all children
473
                                ('flush', None),
474
                                   ('add', (u'', b'dir-id', 'directory', None))],
475
                               revision_id=b'B-id')
6008.2.5 by Andrew Bennetts
Rename 'checkpoint' to 'flush', add some unit tests and more comments.
476
        builder.finish_series()
6973.5.2 by Jelmer Vernooij
Add more bees.
477
        rev_tree = builder.get_branch().repository.revision_tree(b'B-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
478
        self.assertTreeShape([(u'', b'dir-id', 'directory')], rev_tree)