/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2052.3.2 by John Arbash Meinel
Change Copyright .. by Canonical to Copyright ... Canonical
1
# Copyright (C) 2006 Canonical Ltd
1908.5.2 by Robert Collins
Create and test set_parent_trees.
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
1908.5.2 by Robert Collins
Create and test set_parent_trees.
16
1908.5.3 by Robert Collins
Rename the tree.set_parents tests to tree.parents - preparing to add related function tests. Also remove duplication within the tests by factoring out a helper assert.
17
"""Tests of the parent related functions of WorkingTrees."""
18
1908.5.2 by Robert Collins
Create and test set_parent_trees.
19
import os
20
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
21
from ... import (
2598.5.2 by Aaron Bentley
Got all tests passing with Branch returning 'null:' for null revision
22
    errors,
23
    revision as _mod_revision,
24
    )
6670.4.3 by Jelmer Vernooij
Fix more imports.
25
from ...bzr.inventory import (
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
26
    Inventory,
27
    InventoryFile,
28
    InventoryDirectory,
29
    InventoryLink,
30
    )
6913.4.2 by Jelmer Vernooij
Skip parents tests against non-inventory trees.
31
from ...bzr.inventorytree import (
32
    InventoryRevisionTree,
33
    InventoryTree,
34
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
35
from ...sixish import (
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
36
    BytesIO,
37
    )
6913.4.2 by Jelmer Vernooij
Skip parents tests against non-inventory trees.
38
from ...tests import TestNotApplicable
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
39
from ..per_workingtree import TestCaseWithWorkingTree
40
from .. import (
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
41
    features,
42
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
43
from ...uncommit import uncommit
1908.5.2 by Robert Collins
Create and test set_parent_trees.
44
45
1908.5.3 by Robert Collins
Rename the tree.set_parents tests to tree.parents - preparing to add related function tests. Also remove duplication within the tests by factoring out a helper assert.
46
class TestParents(TestCaseWithWorkingTree):
47
48
    def assertConsistentParents(self, expected, tree):
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
49
        """Check that the parents found are as expected.
50
51
        This test helper also checks that they are consistent with
52
        the pre-get_parent_ids() api - which is now deprecated.
53
        """
1908.5.3 by Robert Collins
Rename the tree.set_parents tests to tree.parents - preparing to add related function tests. Also remove duplication within the tests by factoring out a helper assert.
54
        self.assertEqual(expected, tree.get_parent_ids())
55
        if expected == []:
2598.5.7 by Aaron Bentley
Updates from review
56
            self.assertEqual(_mod_revision.NULL_REVISION,
57
                             _mod_revision.ensure_null(tree.last_revision()))
1908.5.3 by Robert Collins
Rename the tree.set_parents tests to tree.parents - preparing to add related function tests. Also remove duplication within the tests by factoring out a helper assert.
58
        else:
1908.7.11 by Robert Collins
Merge bzr.dev and undeprecated WorkingTree.last_revision as per review feedback.
59
            self.assertEqual(expected[0], tree.last_revision())
1908.5.3 by Robert Collins
Rename the tree.set_parents tests to tree.parents - preparing to add related function tests. Also remove duplication within the tests by factoring out a helper assert.
60
61
2598.5.2 by Aaron Bentley
Got all tests passing with Branch returning 'null:' for null revision
62
class TestGetParents(TestParents):
63
64
    def test_get_parents(self):
65
        t = self.make_branch_and_tree('.')
66
        self.assertEqual([], t.get_parent_ids())
67
68
1908.5.3 by Robert Collins
Rename the tree.set_parents tests to tree.parents - preparing to add related function tests. Also remove duplication within the tests by factoring out a helper assert.
69
class TestSetParents(TestParents):
1908.5.2 by Robert Collins
Create and test set_parent_trees.
70
71
    def test_set_no_parents(self):
72
        t = self.make_branch_and_tree('.')
73
        t.set_parent_trees([])
74
        self.assertEqual([], t.get_parent_ids())
75
        # now give it a real parent, and then set it to no parents again.
76
        t.commit('first post')
77
        t.set_parent_trees([])
1908.5.3 by Robert Collins
Rename the tree.set_parents tests to tree.parents - preparing to add related function tests. Also remove duplication within the tests by factoring out a helper assert.
78
        self.assertConsistentParents([], t)
1908.5.2 by Robert Collins
Create and test set_parent_trees.
79
2598.5.2 by Aaron Bentley
Got all tests passing with Branch returning 'null:' for null revision
80
    def test_set_null_parent(self):
81
        t = self.make_branch_and_tree('.')
6973.11.7 by Jelmer Vernooij
Fix more tests.
82
        self.assertRaises(errors.ReservedId, t.set_parent_ids, [b'null:'],
2598.5.2 by Aaron Bentley
Got all tests passing with Branch returning 'null:' for null revision
83
                          allow_leftmost_as_ghost=True)
84
        self.assertRaises(errors.ReservedId, t.set_parent_trees,
6973.11.7 by Jelmer Vernooij
Fix more tests.
85
                          [(b'null:', None)], allow_leftmost_as_ghost=True)
2598.5.2 by Aaron Bentley
Got all tests passing with Branch returning 'null:' for null revision
86
1908.5.9 by Robert Collins
Add a guard against setting the tree last-revision value to a ghost in the new tree parent management api.
87
    def test_set_one_ghost_parent_rejects(self):
88
        t = self.make_branch_and_tree('.')
1908.5.12 by Robert Collins
Apply review feedback - paired with Martin.
89
        self.assertRaises(errors.GhostRevisionUnusableHere,
6973.11.7 by Jelmer Vernooij
Fix more tests.
90
            t.set_parent_trees, [(b'missing-revision-id', None)])
1908.5.9 by Robert Collins
Add a guard against setting the tree last-revision value to a ghost in the new tree parent management api.
91
92
    def test_set_one_ghost_parent_force(self):
93
        t = self.make_branch_and_tree('.')
6844.1.2 by Jelmer Vernooij
Add supports_leftmost_parent_id_as_ghost.
94
        if t._format.supports_leftmost_parent_id_as_ghost:
6973.11.7 by Jelmer Vernooij
Fix more tests.
95
            t.set_parent_trees([(b'missing-revision-id', None)],
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
96
                allow_leftmost_as_ghost=True)
6973.11.7 by Jelmer Vernooij
Fix more tests.
97
            self.assertConsistentParents([b'missing-revision-id'], t)
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
98
        else:
99
            self.assertRaises(errors.GhostRevisionUnusableHere,
6973.11.7 by Jelmer Vernooij
Fix more tests.
100
                t.set_parent_trees, [(b'missing-revision-id', None)])
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
101
            self.assertConsistentParents([], t)
1908.5.2 by Robert Collins
Create and test set_parent_trees.
102
103
    def test_set_two_parents_one_ghost(self):
104
        t = self.make_branch_and_tree('.')
105
        revision_in_repo = t.commit('first post')
106
        # remove the tree's history
107
        uncommit(t.branch, tree=t)
108
        rev_tree = t.branch.repository.revision_tree(revision_in_repo)
6861.5.1 by Jelmer Vernooij
Add supports_righthand_parent_id_as_ghost flag.
109
        if t._format.supports_righthand_parent_id_as_ghost:
110
            t.set_parent_trees([(revision_in_repo, rev_tree),
6973.11.7 by Jelmer Vernooij
Fix more tests.
111
                (b'another-missing', None)])
112
            self.assertConsistentParents([revision_in_repo, b'another-missing'], t)
6861.5.1 by Jelmer Vernooij
Add supports_righthand_parent_id_as_ghost flag.
113
        else:
114
            self.assertRaises(errors.GhostRevisionUnusableHere,
115
                t.set_parent_trees, [(revision_in_repo, rev_tree),
6973.11.7 by Jelmer Vernooij
Fix more tests.
116
                (b'another-missing', None)])
1908.5.2 by Robert Collins
Create and test set_parent_trees.
117
118
    def test_set_three_parents(self):
119
        t = self.make_branch_and_tree('.')
120
        first_revision = t.commit('first post')
121
        uncommit(t.branch, tree=t)
122
        second_revision = t.commit('second post')
123
        uncommit(t.branch, tree=t)
124
        third_revision = t.commit('third post')
125
        uncommit(t.branch, tree=t)
126
        rev_tree1 = t.branch.repository.revision_tree(first_revision)
127
        rev_tree2 = t.branch.repository.revision_tree(second_revision)
128
        rev_tree3 = t.branch.repository.revision_tree(third_revision)
129
        t.set_parent_trees([(first_revision, rev_tree1),
130
            (second_revision, rev_tree2),
131
            (third_revision, rev_tree3)])
1908.5.3 by Robert Collins
Rename the tree.set_parents tests to tree.parents - preparing to add related function tests. Also remove duplication within the tests by factoring out a helper assert.
132
        self.assertConsistentParents(
133
            [first_revision, second_revision, third_revision], t)
1908.5.4 by Robert Collins
Add add_parent_tree_id WorkingTree helper api.
134
1908.5.5 by Robert Collins
Add WorkingTree.set_parent_ids.
135
    def test_set_no_parents_ids(self):
136
        t = self.make_branch_and_tree('.')
137
        t.set_parent_ids([])
138
        self.assertEqual([], t.get_parent_ids())
139
        # now give it a real parent, and then set it to no parents again.
140
        t.commit('first post')
141
        t.set_parent_ids([])
142
        self.assertConsistentParents([], t)
143
1908.5.9 by Robert Collins
Add a guard against setting the tree last-revision value to a ghost in the new tree parent management api.
144
    def test_set_one_ghost_parent_ids_rejects(self):
145
        t = self.make_branch_and_tree('.')
1908.5.12 by Robert Collins
Apply review feedback - paired with Martin.
146
        self.assertRaises(errors.GhostRevisionUnusableHere,
6973.11.7 by Jelmer Vernooij
Fix more tests.
147
            t.set_parent_ids, [b'missing-revision-id'])
1908.5.9 by Robert Collins
Add a guard against setting the tree last-revision value to a ghost in the new tree parent management api.
148
149
    def test_set_one_ghost_parent_ids_force(self):
150
        t = self.make_branch_and_tree('.')
6844.1.2 by Jelmer Vernooij
Add supports_leftmost_parent_id_as_ghost.
151
        if t._format.supports_leftmost_parent_id_as_ghost:
6973.10.6 by Jelmer Vernooij
Fix tests.
152
            t.set_parent_ids([b'missing-revision-id'],
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
153
                allow_leftmost_as_ghost=True)
6973.10.6 by Jelmer Vernooij
Fix tests.
154
            self.assertConsistentParents([b'missing-revision-id'], t)
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
155
        else:
156
            self.assertRaises(
157
                errors.GhostRevisionUnusableHere, t.set_parent_ids,
6973.10.6 by Jelmer Vernooij
Fix tests.
158
                [b'missing-revision-id'], allow_leftmost_as_ghost=True)
1908.5.5 by Robert Collins
Add WorkingTree.set_parent_ids.
159
160
    def test_set_two_parents_one_ghost_ids(self):
161
        t = self.make_branch_and_tree('.')
162
        revision_in_repo = t.commit('first post')
163
        # remove the tree's history
164
        uncommit(t.branch, tree=t)
165
        rev_tree = t.branch.repository.revision_tree(revision_in_repo)
6861.5.1 by Jelmer Vernooij
Add supports_righthand_parent_id_as_ghost flag.
166
        if t._format.supports_righthand_parent_id_as_ghost:
6973.10.6 by Jelmer Vernooij
Fix tests.
167
            t.set_parent_ids([revision_in_repo, b'another-missing'])
168
            self.assertConsistentParents([revision_in_repo, b'another-missing'], t)
6861.5.1 by Jelmer Vernooij
Add supports_righthand_parent_id_as_ghost flag.
169
        else:
170
            self.assertRaises(errors.GhostRevisionUnusableHere,
6973.10.6 by Jelmer Vernooij
Fix tests.
171
                t.set_parent_ids, [revision_in_repo, b'another-missing'])
1908.5.5 by Robert Collins
Add WorkingTree.set_parent_ids.
172
173
    def test_set_three_parents_ids(self):
174
        t = self.make_branch_and_tree('.')
175
        first_revision = t.commit('first post')
176
        uncommit(t.branch, tree=t)
177
        second_revision = t.commit('second post')
178
        uncommit(t.branch, tree=t)
179
        third_revision = t.commit('third post')
180
        uncommit(t.branch, tree=t)
181
        rev_tree1 = t.branch.repository.revision_tree(first_revision)
182
        rev_tree2 = t.branch.repository.revision_tree(second_revision)
183
        rev_tree3 = t.branch.repository.revision_tree(third_revision)
184
        t.set_parent_ids([first_revision, second_revision, third_revision])
185
        self.assertConsistentParents(
186
            [first_revision, second_revision, third_revision], t)
187
3462.1.2 by John Arbash Meinel
Change WT.set_parent_(ids/trees) to filter out ancestors.
188
    def test_set_duplicate_parent_ids(self):
189
        t = self.make_branch_and_tree('.')
190
        rev1 = t.commit('first post')
191
        uncommit(t.branch, tree=t)
192
        rev2 = t.commit('second post')
193
        uncommit(t.branch, tree=t)
194
        rev3 = t.commit('third post')
195
        uncommit(t.branch, tree=t)
196
        t.set_parent_ids([rev1, rev2, rev2, rev3])
197
        # We strip the duplicate, but preserve the ordering
198
        self.assertConsistentParents([rev1, rev2, rev3], t)
199
200
    def test_set_duplicate_parent_trees(self):
201
        t = self.make_branch_and_tree('.')
202
        rev1 = t.commit('first post')
203
        uncommit(t.branch, tree=t)
204
        rev2 = t.commit('second post')
205
        uncommit(t.branch, tree=t)
206
        rev3 = t.commit('third post')
207
        uncommit(t.branch, tree=t)
208
        rev_tree1 = t.branch.repository.revision_tree(rev1)
209
        rev_tree2 = t.branch.repository.revision_tree(rev2)
210
        rev_tree3 = t.branch.repository.revision_tree(rev3)
211
        t.set_parent_trees([(rev1, rev_tree1), (rev2, rev_tree2),
212
                            (rev2, rev_tree2), (rev3, rev_tree3)])
213
        # We strip the duplicate, but preserve the ordering
214
        self.assertConsistentParents([rev1, rev2, rev3], t)
215
216
    def test_set_parent_ids_in_ancestry(self):
217
        t = self.make_branch_and_tree('.')
218
        rev1 = t.commit('first post')
219
        rev2 = t.commit('second post')
220
        rev3 = t.commit('third post')
221
        # Reset the tree, back to rev1
222
        t.set_parent_ids([rev1])
223
        t.branch.set_last_revision_info(1, rev1)
224
        self.assertConsistentParents([rev1], t)
225
        t.set_parent_ids([rev1, rev2, rev3])
226
        # rev2 is in the ancestry of rev3, so it will be filtered out
227
        self.assertConsistentParents([rev1, rev3], t)
228
        # Order should be preserved, and the first revision should always be
229
        # kept
230
        t.set_parent_ids([rev2, rev3, rev1])
231
        self.assertConsistentParents([rev2, rev3], t)
232
233
    def test_set_parent_trees_in_ancestry(self):
234
        t = self.make_branch_and_tree('.')
235
        rev1 = t.commit('first post')
236
        rev2 = t.commit('second post')
237
        rev3 = t.commit('third post')
238
        # Reset the tree, back to rev1
239
        t.set_parent_ids([rev1])
240
        t.branch.set_last_revision_info(1, rev1)
241
        self.assertConsistentParents([rev1], t)
242
        rev_tree1 = t.branch.repository.revision_tree(rev1)
243
        rev_tree2 = t.branch.repository.revision_tree(rev2)
244
        rev_tree3 = t.branch.repository.revision_tree(rev3)
245
        t.set_parent_trees([(rev1, rev_tree1), (rev2, rev_tree2),
246
                            (rev3, rev_tree3)])
247
        # rev2 is in the ancestry of rev3, so it will be filtered out
248
        self.assertConsistentParents([rev1, rev3], t)
249
        # Order should be preserved, and the first revision should always be
250
        # kept
251
        t.set_parent_trees([(rev2, rev_tree2), (rev1, rev_tree1),
252
                            (rev3, rev_tree3)])
253
        self.assertConsistentParents([rev2, rev3], t)
254
3763.9.7 by Daniel Clemente
Tested Unicode target rather than always trying to create it in UTF-8. Test renamed
255
    def test_unicode_symlink(self):
3763.9.1 by Daniel Clemente
New testcase for bug 272444 (support symlinks to non-ASCII files)
256
        # this tests bug #272444
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
257
        self.requireFeature(features.SymlinkFeature)
258
        self.requireFeature(features.UnicodeFilenameFeature)
3763.9.1 by Daniel Clemente
New testcase for bug 272444 (support symlinks to non-ASCII files)
259
3763.9.3 by Daniel Clemente
Clearer test with better names and just one parent
260
        tree = self.make_branch_and_tree('tree1')
3763.9.2 by Daniel Clemente
Adapted test to use set_parent_ids and raise KnownFailure
261
3763.9.9 by Daniel Clemente
Used a greek omega instead of an accented 'o' to avoid combining characters
262
        # The link points to a file whose name is an omega
263
        # U+03A9 GREEK CAPITAL LETTER OMEGA
264
        # UTF-8: ce a9  UTF-16BE: 03a9  Decimal: Ω
4241.14.12 by Vincent Ladeuil
Far too many modifications for a single commit, need to restart.
265
        target = u'\u03a9'
266
        link_name = u'\N{Euro Sign}link'
267
        os.symlink(target, 'tree1/' + link_name)
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
268
        tree.add([link_name])
3763.9.2 by Daniel Clemente
Adapted test to use set_parent_ids and raise KnownFailure
269
4095.3.1 by Vincent Ladeuil
Fix #339055 and #277444 by handling non ascii symlink targets.
270
        revision1 = tree.commit('added a link to a Unicode target')
271
        revision2 = tree.commit('this revision will be discarded')
272
        tree.set_parent_ids([revision1])
4241.14.12 by Vincent Ladeuil
Far too many modifications for a single commit, need to restart.
273
        tree.lock_read()
274
        self.addCleanup(tree.unlock)
275
        # Check that the symlink target is safely round-tripped in the trees.
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
276
        self.assertEqual(target, tree.get_symlink_target(link_name))
4241.14.12 by Vincent Ladeuil
Far too many modifications for a single commit, need to restart.
277
        basis = tree.basis_tree()
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
278
        self.assertEqual(target, basis.get_symlink_target(link_name))
3763.9.1 by Daniel Clemente
New testcase for bug 272444 (support symlinks to non-ASCII files)
279
1908.5.4 by Robert Collins
Add add_parent_tree_id WorkingTree helper api.
280
1908.5.6 by Robert Collins
Add add_parent_tree to WorkingTree.
281
class TestAddParent(TestParents):
1908.5.4 by Robert Collins
Add add_parent_tree_id WorkingTree helper api.
282
283
    def test_add_first_parent_id(self):
284
        """Test adding the first parent id"""
285
        tree = self.make_branch_and_tree('.')
286
        first_revision = tree.commit('first post')
287
        uncommit(tree.branch, tree=tree)
288
        tree.add_parent_tree_id(first_revision)
289
        self.assertConsistentParents([first_revision], tree)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
290
1908.5.9 by Robert Collins
Add a guard against setting the tree last-revision value to a ghost in the new tree parent management api.
291
    def test_add_first_parent_id_ghost_rejects(self):
292
        """Test adding the first parent id - as a ghost"""
293
        tree = self.make_branch_and_tree('.')
1908.5.12 by Robert Collins
Apply review feedback - paired with Martin.
294
        self.assertRaises(errors.GhostRevisionUnusableHere,
6973.10.4 by Jelmer Vernooij
Update python3.passing.
295
            tree.add_parent_tree_id, b'first-revision')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
296
1908.5.9 by Robert Collins
Add a guard against setting the tree last-revision value to a ghost in the new tree parent management api.
297
    def test_add_first_parent_id_ghost_force(self):
298
        """Test adding the first parent id - as a ghost"""
299
        tree = self.make_branch_and_tree('.')
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
300
        try:
6973.10.4 by Jelmer Vernooij
Update python3.passing.
301
            tree.add_parent_tree_id(b'first-revision', allow_leftmost_as_ghost=True)
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
302
        except errors.GhostRevisionUnusableHere:
6844.1.2 by Jelmer Vernooij
Add supports_leftmost_parent_id_as_ghost.
303
            self.assertFalse(tree._format.supports_leftmost_parent_id_as_ghost)
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
304
        else:
6844.1.2 by Jelmer Vernooij
Add supports_leftmost_parent_id_as_ghost.
305
            self.assertTrue(tree._format.supports_leftmost_parent_id_as_ghost)
6973.10.4 by Jelmer Vernooij
Update python3.passing.
306
            self.assertConsistentParents([b'first-revision'], tree)
1908.5.13 by Robert Collins
Adding a parent when the first is a ghost already should not require forcing it.
307
308
    def test_add_second_parent_id_with_ghost_first(self):
309
        """Test adding the second parent when the first is a ghost."""
310
        tree = self.make_branch_and_tree('.')
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
311
        try:
6973.10.4 by Jelmer Vernooij
Update python3.passing.
312
            tree.add_parent_tree_id(b'first-revision', allow_leftmost_as_ghost=True)
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
313
        except errors.GhostRevisionUnusableHere:
6844.1.2 by Jelmer Vernooij
Add supports_leftmost_parent_id_as_ghost.
314
            self.assertFalse(tree._format.supports_leftmost_parent_id_as_ghost)
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
315
        else:
6973.10.4 by Jelmer Vernooij
Update python3.passing.
316
            tree.add_parent_tree_id(b'second')
317
            self.assertConsistentParents([b'first-revision', b'second'], tree)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
318
1908.5.4 by Robert Collins
Add add_parent_tree_id WorkingTree helper api.
319
    def test_add_second_parent_id(self):
320
        """Test adding the second parent id"""
321
        tree = self.make_branch_and_tree('.')
322
        first_revision = tree.commit('first post')
323
        uncommit(tree.branch, tree=tree)
324
        second_revision = tree.commit('second post')
325
        tree.add_parent_tree_id(first_revision)
326
        self.assertConsistentParents([second_revision, first_revision], tree)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
327
1908.5.4 by Robert Collins
Add add_parent_tree_id WorkingTree helper api.
328
    def test_add_second_parent_id_ghost(self):
329
        """Test adding the second parent id - as a ghost"""
330
        tree = self.make_branch_and_tree('.')
331
        first_revision = tree.commit('first post')
6861.5.1 by Jelmer Vernooij
Add supports_righthand_parent_id_as_ghost flag.
332
        if tree._format.supports_righthand_parent_id_as_ghost:
6973.10.4 by Jelmer Vernooij
Update python3.passing.
333
            tree.add_parent_tree_id(b'second')
334
            self.assertConsistentParents([first_revision, b'second'], tree)
6861.5.1 by Jelmer Vernooij
Add supports_righthand_parent_id_as_ghost flag.
335
        else:
336
            self.assertRaises(errors.GhostRevisionUnusableHere,
6973.10.4 by Jelmer Vernooij
Update python3.passing.
337
                    tree.add_parent_tree_id, b'second')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
338
1908.5.6 by Robert Collins
Add add_parent_tree to WorkingTree.
339
    def test_add_first_parent_tree(self):
340
        """Test adding the first parent id"""
341
        tree = self.make_branch_and_tree('.')
342
        first_revision = tree.commit('first post')
343
        uncommit(tree.branch, tree=tree)
344
        tree.add_parent_tree((first_revision,
345
            tree.branch.repository.revision_tree(first_revision)))
346
        self.assertConsistentParents([first_revision], tree)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
347
1908.5.9 by Robert Collins
Add a guard against setting the tree last-revision value to a ghost in the new tree parent management api.
348
    def test_add_first_parent_tree_ghost_rejects(self):
349
        """Test adding the first parent id - as a ghost"""
350
        tree = self.make_branch_and_tree('.')
1908.5.12 by Robert Collins
Apply review feedback - paired with Martin.
351
        self.assertRaises(errors.GhostRevisionUnusableHere,
1908.5.9 by Robert Collins
Add a guard against setting the tree last-revision value to a ghost in the new tree parent management api.
352
            tree.add_parent_tree, ('first-revision', None))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
353
1908.5.9 by Robert Collins
Add a guard against setting the tree last-revision value to a ghost in the new tree parent management api.
354
    def test_add_first_parent_tree_ghost_force(self):
355
        """Test adding the first parent id - as a ghost"""
356
        tree = self.make_branch_and_tree('.')
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
357
        try:
358
            tree.add_parent_tree(('first-revision', None),
359
                allow_leftmost_as_ghost=True)
360
        except errors.GhostRevisionUnusableHere:
6844.1.2 by Jelmer Vernooij
Add supports_leftmost_parent_id_as_ghost.
361
            self.assertFalse(tree._format.supports_leftmost_parent_id_as_ghost)
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
362
        else:
6844.1.2 by Jelmer Vernooij
Add supports_leftmost_parent_id_as_ghost.
363
            self.assertTrue(tree._format.supports_leftmost_parent_id_as_ghost)
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
364
            self.assertConsistentParents(['first-revision'], tree)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
365
1908.5.6 by Robert Collins
Add add_parent_tree to WorkingTree.
366
    def test_add_second_parent_tree(self):
367
        """Test adding the second parent id"""
368
        tree = self.make_branch_and_tree('.')
369
        first_revision = tree.commit('first post')
370
        uncommit(tree.branch, tree=tree)
371
        second_revision = tree.commit('second post')
372
        tree.add_parent_tree((first_revision,
373
            tree.branch.repository.revision_tree(first_revision)))
374
        self.assertConsistentParents([second_revision, first_revision], tree)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
375
1908.5.6 by Robert Collins
Add add_parent_tree to WorkingTree.
376
    def test_add_second_parent_tree_ghost(self):
377
        """Test adding the second parent id - as a ghost"""
378
        tree = self.make_branch_and_tree('.')
379
        first_revision = tree.commit('first post')
6861.5.1 by Jelmer Vernooij
Add supports_righthand_parent_id_as_ghost flag.
380
        if tree._format.supports_righthand_parent_id_as_ghost:
381
            tree.add_parent_tree(('second', None))
382
            self.assertConsistentParents([first_revision, 'second'], tree)
383
        else:
384
            self.assertRaises(errors.GhostRevisionUnusableHere,
385
                    tree.add_parent_tree, ('second', None))
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
386
387
3253.2.1 by John Arbash Meinel
Fix moving directories to root nodes.
388
class UpdateToOneParentViaDeltaTests(TestCaseWithWorkingTree):
2903.2.7 by Martin Pool
Rename update_to_one_parent_via_delta to more wieldy update_basis_by_delta
389
    """Tests for the update_basis_by_delta call.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
390
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
391
    This is intuitively defined as 'apply an inventory delta to the basis and
392
    discard other parents', but for trees that have an inventory that is not
393
    managed as a tree-by-id, the implementation requires roughly duplicated
394
    tests with those for apply_inventory_delta on the main tree.
395
    """
396
397
    def assertDeltaApplicationResultsInExpectedBasis(self, tree, revid, delta,
398
        expected_inventory):
6913.4.2 by Jelmer Vernooij
Skip parents tests against non-inventory trees.
399
        with tree.lock_write():
2929.2.1 by Robert Collins
* Commit updates the state of the working tree via a delta rather than
400
            tree.update_basis_by_delta(revid, delta)
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
401
        # check the last revision was adjusted to rev_id
402
        self.assertEqual(revid, tree.last_revision())
403
        # check the parents are what we expect
404
        self.assertEqual([revid], tree.get_parent_ids())
405
        # check that the basis tree has the inventory we expect from applying
406
        # the delta.
407
        result_basis = tree.basis_tree()
6913.4.2 by Jelmer Vernooij
Skip parents tests against non-inventory trees.
408
        with result_basis.lock_read():
6405.2.9 by Jelmer Vernooij
More test fixes.
409
            self.assertEqual(expected_inventory, result_basis.root_inventory)
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
410
411
    def make_inv_delta(self, old, new):
412
        """Make an inventory delta from two inventories."""
6656.1.1 by Martin
Apply 2to3 dict fixer and clean up resulting mess using view helpers
413
        old_ids = set(old._byid)
414
        new_ids = set(new._byid)
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
415
        adds = new_ids - old_ids
416
        deletes = old_ids - new_ids
417
        common = old_ids.intersection(new_ids)
418
        delta = []
419
        for file_id in deletes:
420
            delta.append((old.id2path(file_id), None, file_id, None))
421
        for file_id in adds:
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
422
            delta.append((None, new.id2path(file_id), file_id, new.get_entry(file_id)))
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
423
        for file_id in common:
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
424
            if old.get_entry(file_id) != new.get_entry(file_id):
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
425
                delta.append((old.id2path(file_id), new.id2path(file_id),
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
426
                    file_id, new.get_entry(file_id)))
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
427
        return delta
428
429
    def fake_up_revision(self, tree, revid, shape):
5809.4.1 by Jelmer Vernooij
Avoid .texts.add_lines, rather use Repository.get_commit_builder.
430
6913.4.2 by Jelmer Vernooij
Skip parents tests against non-inventory trees.
431
        if not isinstance(tree, InventoryTree):
432
            raise TestNotApplicable("test requires inventory tree")
433
5809.4.1 by Jelmer Vernooij
Avoid .texts.add_lines, rather use Repository.get_commit_builder.
434
        class ShapeTree(InventoryRevisionTree):
435
436
            def __init__(self, shape):
437
                self._repository = tree.branch.repository
438
                self._inventory = shape
439
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
440
            def get_file_text(self, path, file_id=None):
441
                if file_id is None:
442
                    file_id = self.path2id(path)
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
443
                ie = self.root_inventory.get_entry(file_id)
5809.4.1 by Jelmer Vernooij
Avoid .texts.add_lines, rather use Repository.get_commit_builder.
444
                if ie.kind != "file":
6977.2.1 by Jelmer Vernooij
Require that get_file implementations are contect managers, simplify file handling in transform.
445
                    return b""
446
                return b'a' * ie.text_size
5809.4.1 by Jelmer Vernooij
Avoid .texts.add_lines, rather use Repository.get_commit_builder.
447
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
448
            def get_file(self, path, file_id=None):
449
                return BytesIO(self.get_file_text(path, file_id))
5809.4.1 by Jelmer Vernooij
Avoid .texts.add_lines, rather use Repository.get_commit_builder.
450
6851.1.1 by Jelmer Vernooij
More foreign branch fixes.
451
        with tree.lock_write():
5809.4.1 by Jelmer Vernooij
Avoid .texts.add_lines, rather use Repository.get_commit_builder.
452
            if shape.root.revision is None:
453
                shape.root.revision = revid
454
            builder = tree.branch.get_commit_builder(
455
                    parents=[],
456
                    timestamp=0,
457
                    timezone=None,
458
                    committer="Foo Bar <foo@example.com>",
459
                    revision_id=revid)
460
            shape_tree = ShapeTree(shape)
5809.4.3 by Jelmer Vernooij
Fix base revid.
461
            base_tree = tree.branch.repository.revision_tree(
462
                    _mod_revision.NULL_REVISION)
5809.4.1 by Jelmer Vernooij
Avoid .texts.add_lines, rather use Repository.get_commit_builder.
463
            changes = shape_tree.iter_changes(
5809.4.3 by Jelmer Vernooij
Fix base revid.
464
                base_tree)
5809.4.1 by Jelmer Vernooij
Avoid .texts.add_lines, rather use Repository.get_commit_builder.
465
            list(builder.record_iter_changes(shape_tree,
5809.4.3 by Jelmer Vernooij
Fix base revid.
466
                base_tree.get_revision_id(), changes))
5809.4.1 by Jelmer Vernooij
Avoid .texts.add_lines, rather use Repository.get_commit_builder.
467
            builder.finish_inventory()
468
            builder.commit("Message")
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
469
470
    def add_entry(self, inv, rev_id, entry):
471
        entry.revision = rev_id
472
        inv.add(entry)
473
474
    def add_dir(self, inv, rev_id, file_id, parent_id, name):
475
        new_dir = InventoryDirectory(file_id, name, parent_id)
476
        self.add_entry(inv, rev_id, new_dir)
477
478
    def add_file(self, inv, rev_id, file_id, parent_id, name, sha, size):
479
        new_file = InventoryFile(file_id, name, parent_id)
480
        new_file.text_sha1 = sha
481
        new_file.text_size = size
482
        self.add_entry(inv, rev_id, new_file)
483
484
    def add_link(self, inv, rev_id, file_id, parent_id, name, target):
485
        new_link = InventoryLink(file_id, name, parent_id)
486
        new_link.symlink_target = target
487
        self.add_entry(inv, rev_id, new_link)
488
489
    def add_new_root(self, new_shape, old_revid, new_revid):
490
        if self.bzrdir_format.repository_format.rich_root_data:
6973.11.7 by Jelmer Vernooij
Fix more tests.
491
            self.add_dir(new_shape, old_revid, b'root-id', None, '')
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
492
        else:
6973.11.7 by Jelmer Vernooij
Fix more tests.
493
            self.add_dir(new_shape, new_revid, b'root-id', None, '')
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
494
495
    def assertTransitionFromBasisToShape(self, basis_shape, basis_revid,
6015.45.2 by Brian de Alwis, John Arbash Meinel
Backport the fix for bug #855155 to bzr-2.4
496
        new_shape, new_revid, extra_parent=None, set_current_inventory=True):
2889.1.1 by Robert Collins
* The class ``bzrlib.repofmt.knitrepo.KnitRepository3`` has been folded into
497
        # set the inventory revision ids.
498
        basis_shape.revision_id = basis_revid
499
        new_shape.revision_id = new_revid
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
500
        delta = self.make_inv_delta(basis_shape, new_shape)
501
        tree = self.make_branch_and_tree('tree')
502
        # the shapes need to be in the tree's repository to be able to set them
503
        # as a parent, but the file content is not needed.
504
        if basis_revid is not None:
505
            self.fake_up_revision(tree, basis_revid, basis_shape)
506
            parents = [basis_revid]
507
            if extra_parent is not None:
508
                parents.append(extra_parent)
509
            tree.set_parent_ids(parents)
510
        self.fake_up_revision(tree, new_revid, new_shape)
6015.45.2 by Brian de Alwis, John Arbash Meinel
Backport the fix for bug #855155 to bzr-2.4
511
        if set_current_inventory:
512
            # give tree an inventory of new_shape
513
            tree._write_inventory(new_shape)
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
514
        self.assertDeltaApplicationResultsInExpectedBasis(tree, new_revid,
515
            delta, new_shape)
2929.2.2 by Robert Collins
Review feedback on dirstate update_basis_via_delta logic.
516
        # The tree should be internally consistent; while this is a moderately
517
        # large hammer, this is a particularly sensitive area of code, so the
518
        # extra assurance is well worth it.
519
        tree._validate()
6437.70.4 by John Arbash Meinel
Now that we have 2 possible locations where things exist, we must cleanup both.
520
        # If tree.branch is remote
6437.70.5 by John Arbash Meinel
user_url seems a cleaner way to do the same thing.
521
        if tree.user_url != tree.branch.user_url:
6437.70.4 by John Arbash Meinel
Now that we have 2 possible locations where things exist, we must cleanup both.
522
            # We have a lightweight checkout, delete both locations
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
523
            tree.branch.controldir.root_transport.delete_tree('.')
524
        tree.controldir.root_transport.delete_tree('.')
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
525
526
    def test_no_parents_just_root(self):
527
        """Test doing an empty commit - no parent, set a root only."""
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
528
        basis_shape = Inventory(root_id=None)  # empty tree
529
        new_shape = Inventory()  # tree with a root
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
530
        self.assertTransitionFromBasisToShape(basis_shape, None, new_shape,
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
531
            b'new_parent')
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
532
533
    def test_no_parents_full_tree(self):
534
        """Test doing a regular initial commit with files and dirs."""
535
        basis_shape = Inventory(root_id=None) # empty tree
6973.11.7 by Jelmer Vernooij
Fix more tests.
536
        revid = b'new-parent'
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
537
        new_shape = Inventory(root_id=None)
6973.11.7 by Jelmer Vernooij
Fix more tests.
538
        self.add_dir(new_shape, revid, b'root-id', None, '')
539
        self.add_link(new_shape, revid, b'link-id', b'root-id', 'link', 'target')
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
540
        self.add_file(new_shape, revid, b'file-id', b'root-id', 'file', b'1' * 32,
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
541
            12)
6973.11.7 by Jelmer Vernooij
Fix more tests.
542
        self.add_dir(new_shape, revid, b'dir-id', b'root-id', 'dir')
543
        self.add_file(new_shape, revid, b'subfile-id', b'dir-id', 'subfile',
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
544
            b'2' * 32, 24)
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
545
        self.assertTransitionFromBasisToShape(basis_shape, None, new_shape,
546
            revid)
547
548
    def test_file_content_change(self):
6973.11.7 by Jelmer Vernooij
Fix more tests.
549
        old_revid = b'old-parent'
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
550
        basis_shape = Inventory(root_id=None)
6973.11.7 by Jelmer Vernooij
Fix more tests.
551
        self.add_dir(basis_shape, old_revid, b'root-id', None, '')
552
        self.add_file(basis_shape, old_revid, b'file-id', b'root-id', 'file',
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
553
            b'1' * 32, 12)
6973.11.7 by Jelmer Vernooij
Fix more tests.
554
        new_revid = b'new-parent'
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
555
        new_shape = Inventory(root_id=None)
556
        self.add_new_root(new_shape, old_revid, new_revid)
6973.11.7 by Jelmer Vernooij
Fix more tests.
557
        self.add_file(new_shape, new_revid, b'file-id', b'root-id', 'file',
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
558
            b'2' * 32, 24)
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
559
        self.assertTransitionFromBasisToShape(basis_shape, old_revid,
560
            new_shape, new_revid)
561
562
    def test_link_content_change(self):
6973.11.7 by Jelmer Vernooij
Fix more tests.
563
        old_revid = b'old-parent'
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
564
        basis_shape = Inventory(root_id=None)
6973.11.7 by Jelmer Vernooij
Fix more tests.
565
        self.add_dir(basis_shape, old_revid, b'root-id', None, '')
566
        self.add_link(basis_shape, old_revid, b'link-id', b'root-id', 'link',
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
567
            'old-target')
6973.11.7 by Jelmer Vernooij
Fix more tests.
568
        new_revid = b'new-parent'
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
569
        new_shape = Inventory(root_id=None)
570
        self.add_new_root(new_shape, old_revid, new_revid)
6973.11.7 by Jelmer Vernooij
Fix more tests.
571
        self.add_link(new_shape, new_revid, b'link-id', b'root-id', 'link',
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
572
            'new-target')
573
        self.assertTransitionFromBasisToShape(basis_shape, old_revid,
574
            new_shape, new_revid)
575
576
    def test_kind_changes(self):
577
        def do_file(inv, revid):
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
578
            self.add_file(inv, revid, b'path-id', b'root-id', 'path', b'1' * 32,
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
579
                12)
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
580
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
581
        def do_link(inv, revid):
6973.11.7 by Jelmer Vernooij
Fix more tests.
582
            self.add_link(inv, revid, b'path-id', b'root-id', 'path', 'target')
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
583
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
584
        def do_dir(inv, revid):
6973.11.7 by Jelmer Vernooij
Fix more tests.
585
            self.add_dir(inv, revid, b'path-id', b'root-id', 'path')
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
586
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
587
        for old_factory in (do_file, do_link, do_dir):
588
            for new_factory in (do_file, do_link, do_dir):
589
                if old_factory == new_factory:
590
                    continue
6973.11.7 by Jelmer Vernooij
Fix more tests.
591
                old_revid = b'old-parent'
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
592
                basis_shape = Inventory(root_id=None)
6973.11.7 by Jelmer Vernooij
Fix more tests.
593
                self.add_dir(basis_shape, old_revid, b'root-id', None, '')
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
594
                old_factory(basis_shape, old_revid)
6973.11.7 by Jelmer Vernooij
Fix more tests.
595
                new_revid = b'new-parent'
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
596
                new_shape = Inventory(root_id=None)
597
                self.add_new_root(new_shape, old_revid, new_revid)
598
                new_factory(new_shape, new_revid)
599
                self.assertTransitionFromBasisToShape(basis_shape, old_revid,
600
                    new_shape, new_revid)
601
602
    def test_content_from_second_parent_is_dropped(self):
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
603
        left_revid = b'left-parent'
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
604
        basis_shape = Inventory(root_id=None)
6973.11.7 by Jelmer Vernooij
Fix more tests.
605
        self.add_dir(basis_shape, left_revid, b'root-id', None, '')
606
        self.add_link(basis_shape, left_revid, b'link-id', b'root-id', 'link',
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
607
            'left-target')
608
        # the right shape has content - file, link, subdir with a child,
609
        # that should all be discarded by the call.
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
610
        right_revid = b'right-parent'
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
611
        right_shape = Inventory(root_id=None)
6973.11.7 by Jelmer Vernooij
Fix more tests.
612
        self.add_dir(right_shape, left_revid, b'root-id', None, '')
613
        self.add_link(right_shape, right_revid, b'link-id', b'root-id', 'link',
2865.1.3 by Robert Collins
Review feedback.
614
            'some-target')
6973.11.7 by Jelmer Vernooij
Fix more tests.
615
        self.add_dir(right_shape, right_revid, b'subdir-id', b'root-id', 'dir')
616
        self.add_file(right_shape, right_revid, b'file-id', b'subdir-id', 'file',
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
617
            b'2' * 32, 24)
6973.11.7 by Jelmer Vernooij
Fix more tests.
618
        new_revid = b'new-parent'
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
619
        new_shape = Inventory(root_id=None)
620
        self.add_new_root(new_shape, left_revid, new_revid)
6973.11.7 by Jelmer Vernooij
Fix more tests.
621
        self.add_link(new_shape, new_revid, b'link-id', b'root-id', 'link',
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
622
            'new-target')
623
        self.assertTransitionFromBasisToShape(basis_shape, left_revid,
624
            new_shape, new_revid, right_revid)
625
626
    def test_parent_id_changed(self):
2865.1.3 by Robert Collins
Review feedback.
627
        # test that when the only change to an entry is its parent id changing
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
628
        # that it is handled correctly (that is it keeps the same path)
6973.11.7 by Jelmer Vernooij
Fix more tests.
629
        old_revid = b'old-parent'
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
630
        basis_shape = Inventory(root_id=None)
6973.11.7 by Jelmer Vernooij
Fix more tests.
631
        self.add_dir(basis_shape, old_revid, b'root-id', None, '')
632
        self.add_dir(basis_shape, old_revid, b'orig-parent-id', b'root-id', 'dir')
633
        self.add_dir(basis_shape, old_revid, b'dir-id', b'orig-parent-id', 'dir')
634
        new_revid = b'new-parent'
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
635
        new_shape = Inventory(root_id=None)
636
        self.add_new_root(new_shape, old_revid, new_revid)
6973.11.7 by Jelmer Vernooij
Fix more tests.
637
        self.add_dir(new_shape, new_revid, b'new-parent-id', b'root-id', 'dir')
638
        self.add_dir(new_shape, new_revid, b'dir-id', b'new-parent-id', 'dir')
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
639
        self.assertTransitionFromBasisToShape(basis_shape, old_revid,
640
            new_shape, new_revid)
641
642
    def test_name_changed(self):
2865.1.3 by Robert Collins
Review feedback.
643
        # test that when the only change to an entry is its name changing that
644
        # it is handled correctly (that is it keeps the same parent id)
6973.11.7 by Jelmer Vernooij
Fix more tests.
645
        old_revid = b'old-parent'
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
646
        basis_shape = Inventory(root_id=None)
6973.11.7 by Jelmer Vernooij
Fix more tests.
647
        self.add_dir(basis_shape, old_revid, b'root-id', None, '')
648
        self.add_dir(basis_shape, old_revid, b'parent-id', b'root-id', 'origdir')
649
        self.add_dir(basis_shape, old_revid, b'dir-id', b'parent-id', 'olddir')
650
        new_revid = b'new-parent'
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
651
        new_shape = Inventory(root_id=None)
652
        self.add_new_root(new_shape, old_revid, new_revid)
6973.11.7 by Jelmer Vernooij
Fix more tests.
653
        self.add_dir(new_shape, new_revid, b'parent-id', b'root-id', 'newdir')
654
        self.add_dir(new_shape, new_revid, b'dir-id', b'parent-id', 'newdir')
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
655
        self.assertTransitionFromBasisToShape(basis_shape, old_revid,
656
            new_shape, new_revid)
657
2929.2.2 by Robert Collins
Review feedback on dirstate update_basis_via_delta logic.
658
    def test_parent_child_swap(self):
659
        # test a A->A/B and A/B->A path swap.
6973.11.7 by Jelmer Vernooij
Fix more tests.
660
        old_revid = b'old-parent'
2929.2.2 by Robert Collins
Review feedback on dirstate update_basis_via_delta logic.
661
        basis_shape = Inventory(root_id=None)
6973.11.7 by Jelmer Vernooij
Fix more tests.
662
        self.add_dir(basis_shape, old_revid, b'root-id', None, '')
663
        self.add_dir(basis_shape, old_revid, b'dir-id-A', b'root-id', 'A')
664
        self.add_dir(basis_shape, old_revid, b'dir-id-B', b'dir-id-A', 'B')
665
        self.add_link(basis_shape, old_revid, b'link-id-C', b'dir-id-B', 'C', 'C')
666
        new_revid = b'new-parent'
2929.2.2 by Robert Collins
Review feedback on dirstate update_basis_via_delta logic.
667
        new_shape = Inventory(root_id=None)
668
        self.add_new_root(new_shape, old_revid, new_revid)
6973.11.7 by Jelmer Vernooij
Fix more tests.
669
        self.add_dir(new_shape, new_revid, b'dir-id-B', b'root-id', 'A')
670
        self.add_dir(new_shape, new_revid, b'dir-id-A', b'dir-id-B', 'B')
671
        self.add_link(new_shape, new_revid, b'link-id-C', b'dir-id-A', 'C', 'C')
2929.2.2 by Robert Collins
Review feedback on dirstate update_basis_via_delta logic.
672
        self.assertTransitionFromBasisToShape(basis_shape, old_revid,
673
            new_shape, new_revid)
674
3253.2.1 by John Arbash Meinel
Fix moving directories to root nodes.
675
    def test_parent_deleted_child_renamed(self):
676
        # test a A->None and A/B->A.
6973.11.7 by Jelmer Vernooij
Fix more tests.
677
        old_revid = b'old-parent'
3253.2.1 by John Arbash Meinel
Fix moving directories to root nodes.
678
        basis_shape = Inventory(root_id=None)
6973.11.7 by Jelmer Vernooij
Fix more tests.
679
        self.add_dir(basis_shape, old_revid, b'root-id', None, '')
680
        self.add_dir(basis_shape, old_revid, b'dir-id-A', b'root-id', 'A')
681
        self.add_dir(basis_shape, old_revid, b'dir-id-B', b'dir-id-A', 'B')
682
        self.add_link(basis_shape, old_revid, b'link-id-C', b'dir-id-B', 'C', 'C')
683
        new_revid = b'new-parent'
3253.2.1 by John Arbash Meinel
Fix moving directories to root nodes.
684
        new_shape = Inventory(root_id=None)
685
        self.add_new_root(new_shape, old_revid, new_revid)
6973.11.7 by Jelmer Vernooij
Fix more tests.
686
        self.add_dir(new_shape, new_revid, b'dir-id-B', b'root-id', 'A')
687
        self.add_link(new_shape, old_revid, b'link-id-C', b'dir-id-B', 'C', 'C')
3253.2.1 by John Arbash Meinel
Fix moving directories to root nodes.
688
        self.assertTransitionFromBasisToShape(basis_shape, old_revid,
689
            new_shape, new_revid)
690
691
    def test_dir_to_root(self):
692
        # test a A->''.
6973.11.7 by Jelmer Vernooij
Fix more tests.
693
        old_revid = b'old-parent'
3253.2.1 by John Arbash Meinel
Fix moving directories to root nodes.
694
        basis_shape = Inventory(root_id=None)
6973.11.7 by Jelmer Vernooij
Fix more tests.
695
        self.add_dir(basis_shape, old_revid, b'root-id', None, '')
696
        self.add_dir(basis_shape, old_revid, b'dir-id-A', b'root-id', 'A')
697
        self.add_link(basis_shape, old_revid, b'link-id-B', b'dir-id-A', 'B', 'B')
698
        new_revid = b'new-parent'
3253.2.1 by John Arbash Meinel
Fix moving directories to root nodes.
699
        new_shape = Inventory(root_id=None)
6973.11.7 by Jelmer Vernooij
Fix more tests.
700
        self.add_dir(new_shape, new_revid, b'dir-id-A', None, '')
701
        self.add_link(new_shape, old_revid, b'link-id-B', b'dir-id-A', 'B', 'B')
3253.2.1 by John Arbash Meinel
Fix moving directories to root nodes.
702
        self.assertTransitionFromBasisToShape(basis_shape, old_revid,
703
            new_shape, new_revid)
704
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
705
    def test_path_swap(self):
706
        # test a A->B and B->A path swap.
6973.11.7 by Jelmer Vernooij
Fix more tests.
707
        old_revid = b'old-parent'
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
708
        basis_shape = Inventory(root_id=None)
6973.11.7 by Jelmer Vernooij
Fix more tests.
709
        self.add_dir(basis_shape, old_revid, b'root-id', None, '')
710
        self.add_dir(basis_shape, old_revid, b'dir-id-A', b'root-id', 'A')
711
        self.add_dir(basis_shape, old_revid, b'dir-id-B', b'root-id', 'B')
712
        self.add_link(basis_shape, old_revid, b'link-id-C', b'root-id', 'C', 'C')
713
        self.add_link(basis_shape, old_revid, b'link-id-D', b'root-id', 'D', 'D')
714
        self.add_file(basis_shape, old_revid, b'file-id-E', b'root-id', 'E',
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
715
            b'1' * 32, 12)
6973.11.7 by Jelmer Vernooij
Fix more tests.
716
        self.add_file(basis_shape, old_revid, b'file-id-F', b'root-id', 'F',
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
717
            b'2' * 32, 24)
6973.11.7 by Jelmer Vernooij
Fix more tests.
718
        new_revid = b'new-parent'
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
719
        new_shape = Inventory(root_id=None)
720
        self.add_new_root(new_shape, old_revid, new_revid)
6973.11.7 by Jelmer Vernooij
Fix more tests.
721
        self.add_dir(new_shape, new_revid, b'dir-id-A', b'root-id', 'B')
722
        self.add_dir(new_shape, new_revid, b'dir-id-B', b'root-id', 'A')
723
        self.add_link(new_shape, new_revid, b'link-id-C', b'root-id', 'D', 'C')
724
        self.add_link(new_shape, new_revid, b'link-id-D', b'root-id', 'C', 'D')
725
        self.add_file(new_shape, new_revid, b'file-id-E', b'root-id', 'F',
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
726
            b'1' * 32, 12)
6973.11.7 by Jelmer Vernooij
Fix more tests.
727
        self.add_file(new_shape, new_revid, b'file-id-F', b'root-id', 'E',
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
728
            b'2' * 32, 24)
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
729
        self.assertTransitionFromBasisToShape(basis_shape, old_revid,
730
            new_shape, new_revid)
731
732
    def test_adds(self):
733
        # test adding paths and dirs, including adding to a newly added dir.
6973.11.7 by Jelmer Vernooij
Fix more tests.
734
        old_revid = b'old-parent'
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
735
        basis_shape = Inventory(root_id=None)
736
        # with a root, so its a commit after the first.
6973.11.7 by Jelmer Vernooij
Fix more tests.
737
        self.add_dir(basis_shape, old_revid, b'root-id', None, '')
738
        new_revid = b'new-parent'
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
739
        new_shape = Inventory(root_id=None)
740
        self.add_new_root(new_shape, old_revid, new_revid)
6973.11.7 by Jelmer Vernooij
Fix more tests.
741
        self.add_dir(new_shape, new_revid, b'dir-id-A', b'root-id', 'A')
742
        self.add_link(new_shape, new_revid, b'link-id-B', b'root-id', 'B', 'C')
743
        self.add_file(new_shape, new_revid, b'file-id-C', b'root-id', 'C',
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
744
            b'1' * 32, 12)
6973.11.7 by Jelmer Vernooij
Fix more tests.
745
        self.add_file(new_shape, new_revid, b'file-id-D', b'dir-id-A', 'D',
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
746
            b'2' * 32, 24)
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
747
        self.assertTransitionFromBasisToShape(basis_shape, old_revid,
748
            new_shape, new_revid)
749
750
    def test_removes(self):
751
        # test removing paths, including paths that are within other also
752
        # removed paths.
6973.11.7 by Jelmer Vernooij
Fix more tests.
753
        old_revid = b'old-parent'
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
754
        basis_shape = Inventory(root_id=None)
6973.11.7 by Jelmer Vernooij
Fix more tests.
755
        self.add_dir(basis_shape, old_revid, b'root-id', None, '')
756
        self.add_dir(basis_shape, old_revid, b'dir-id-A', b'root-id', 'A')
757
        self.add_link(basis_shape, old_revid, b'link-id-B', b'root-id', 'B', 'C')
758
        self.add_file(basis_shape, old_revid, b'file-id-C', b'root-id', 'C',
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
759
            b'1' * 32, 12)
6973.11.7 by Jelmer Vernooij
Fix more tests.
760
        self.add_file(basis_shape, old_revid, b'file-id-D', b'dir-id-A', 'D',
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
761
            b'2' * 32, 24)
6973.11.7 by Jelmer Vernooij
Fix more tests.
762
        new_revid = b'new-parent'
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
763
        new_shape = Inventory(root_id=None)
764
        self.add_new_root(new_shape, old_revid, new_revid)
765
        self.assertTransitionFromBasisToShape(basis_shape, old_revid,
766
            new_shape, new_revid)
767
768
    def test_move_to_added_dir(self):
6973.11.7 by Jelmer Vernooij
Fix more tests.
769
        old_revid = b'old-parent'
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
770
        basis_shape = Inventory(root_id=None)
6973.11.7 by Jelmer Vernooij
Fix more tests.
771
        self.add_dir(basis_shape, old_revid, b'root-id', None, '')
772
        self.add_link(basis_shape, old_revid, b'link-id-B', b'root-id', 'B', 'C')
773
        new_revid = b'new-parent'
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
774
        new_shape = Inventory(root_id=None)
775
        self.add_new_root(new_shape, old_revid, new_revid)
6973.11.7 by Jelmer Vernooij
Fix more tests.
776
        self.add_dir(new_shape, new_revid, b'dir-id-A', b'root-id', 'A')
777
        self.add_link(new_shape, new_revid, b'link-id-B', b'dir-id-A', 'B', 'C')
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
778
        self.assertTransitionFromBasisToShape(basis_shape, old_revid,
779
            new_shape, new_revid)
780
781
    def test_move_from_removed_dir(self):
6973.11.7 by Jelmer Vernooij
Fix more tests.
782
        old_revid = b'old-parent'
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
783
        basis_shape = Inventory(root_id=None)
6973.11.7 by Jelmer Vernooij
Fix more tests.
784
        self.add_dir(basis_shape, old_revid, b'root-id', None, '')
785
        self.add_dir(basis_shape, old_revid, b'dir-id-A', b'root-id', 'A')
786
        self.add_link(basis_shape, old_revid, b'link-id-B', b'dir-id-A', 'B', 'C')
787
        new_revid = b'new-parent'
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
788
        new_shape = Inventory(root_id=None)
789
        self.add_new_root(new_shape, old_revid, new_revid)
6973.11.7 by Jelmer Vernooij
Fix more tests.
790
        self.add_link(new_shape, new_revid, b'link-id-B', b'root-id', 'B', 'C')
2865.1.1 by Robert Collins
Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.
791
        self.assertTransitionFromBasisToShape(basis_shape, old_revid,
792
            new_shape, new_revid)
2929.2.1 by Robert Collins
* Commit updates the state of the working tree via a delta rather than
793
794
    def test_move_moves_children_recursively(self):
6973.11.7 by Jelmer Vernooij
Fix more tests.
795
        old_revid = b'old-parent'
2929.2.1 by Robert Collins
* Commit updates the state of the working tree via a delta rather than
796
        basis_shape = Inventory(root_id=None)
6973.11.7 by Jelmer Vernooij
Fix more tests.
797
        self.add_dir(basis_shape, old_revid, b'root-id', None, '')
798
        self.add_dir(basis_shape, old_revid, b'dir-id-A', b'root-id', 'A')
799
        self.add_dir(basis_shape, old_revid, b'dir-id-B', b'dir-id-A', 'B')
800
        self.add_link(basis_shape, old_revid, b'link-id-C', b'dir-id-B', 'C', 'D')
801
        new_revid = b'new-parent'
2929.2.1 by Robert Collins
* Commit updates the state of the working tree via a delta rather than
802
        new_shape = Inventory(root_id=None)
803
        self.add_new_root(new_shape, old_revid, new_revid)
804
        # the moved path:
6973.11.7 by Jelmer Vernooij
Fix more tests.
805
        self.add_dir(new_shape, new_revid, b'dir-id-A', b'root-id', 'B')
2929.2.1 by Robert Collins
* Commit updates the state of the working tree via a delta rather than
806
        # unmoved children.
6973.11.7 by Jelmer Vernooij
Fix more tests.
807
        self.add_dir(new_shape, old_revid, b'dir-id-B', b'dir-id-A', 'B')
808
        self.add_link(new_shape, old_revid, b'link-id-C', b'dir-id-B', 'C', 'D')
2929.2.1 by Robert Collins
* Commit updates the state of the working tree via a delta rather than
809
        self.assertTransitionFromBasisToShape(basis_shape, old_revid,
810
            new_shape, new_revid)
6015.45.2 by Brian de Alwis, John Arbash Meinel
Backport the fix for bug #855155 to bzr-2.4
811
812
    def test_add_files_to_empty_directory(self):
6973.11.7 by Jelmer Vernooij
Fix more tests.
813
        old_revid = b'old-parent'
6015.45.2 by Brian de Alwis, John Arbash Meinel
Backport the fix for bug #855155 to bzr-2.4
814
        basis_shape = Inventory(root_id=None)
6973.11.7 by Jelmer Vernooij
Fix more tests.
815
        self.add_dir(basis_shape, old_revid, b'root-id', None, '')
816
        self.add_dir(basis_shape, old_revid, b'dir-id-A', b'root-id', 'A')
817
        new_revid = b'new-parent'
6015.45.2 by Brian de Alwis, John Arbash Meinel
Backport the fix for bug #855155 to bzr-2.4
818
        new_shape = Inventory(root_id=None)
819
        self.add_new_root(new_shape, old_revid, new_revid)
6973.11.7 by Jelmer Vernooij
Fix more tests.
820
        self.add_dir(new_shape, old_revid, b'dir-id-A', b'root-id', 'A')
821
        self.add_file(new_shape, new_revid, b'file-id-B', b'dir-id-A', 'B',
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
822
            b'1' * 32, 24)
6015.45.2 by Brian de Alwis, John Arbash Meinel
Backport the fix for bug #855155 to bzr-2.4
823
        self.assertTransitionFromBasisToShape(basis_shape, old_revid,
824
                new_shape, new_revid, set_current_inventory=False)