/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2255.2.152 by Martin Pool
(broken) merge aaron's workingtree format changes
1
# Copyright (C) 2006, 2007 Canonical Ltd
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
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
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
16
17
"""Tests for the InterTree.compare() function."""
18
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
19
import os
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
20
import shutil
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
21
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
22
from breezy import (
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
23
    errors,
4503.1.3 by Vincent Ladeuil
Take review comments into account.
24
    mutabletree,
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
25
    tests,
26
    )
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
27
from breezy.osutils import has_symlinks
7490.120.3 by Jelmer Vernooij
Split out InventoryTreeChange from TreeChange.
28
from breezy.bzr.inventorytree import InventoryTreeChange
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
29
from breezy.tests.per_intertree import TestCaseWithTwoTrees
30
from breezy.tests import (
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
31
    features,
32
    )
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
33
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
34
# TODO: test the include_root option.
35
# TODO: test that renaming a directory x->y does not emit a rename for the
36
#       child x/a->y/a.
37
# TODO: test that renaming a directory x-> does not emit a rename for the child
38
#        x/a -> y/a when a supplied_files argument gives either 'x/' or 'y/a'
39
#        -> that is, when the renamed parent is not processed by the function.
40
# TODO: test items are only emitted once when a specific_files list names a dir
41
#       whose parent is now a child.
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
42
# TODO: test comparisons between trees with different root ids. mbp 20070301
2255.2.189 by Martin Pool
Add and fix up basic comparison of subtrees.
43
#
44
# TODO: More comparisons between trees with subtrees in different states.
2255.2.236 by Martin Pool
Review cleanups: mostly updating or removing todo comments.
45
#
46
# TODO: Many tests start out by setting the tree roots ids the same, maybe
47
#       that should just be the default for these tests, by changing
48
#       make_branch_and_tree.  mbp 20070307
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
49
7067.6.2 by Jelmer Vernooij
Move key function to top-level.
50
51
def _change_key(change):
52
    """Return a valid key for sorting Tree.iter_changes entries."""
7322.1.6 by Jelmer Vernooij
Use the new attributes on TreeChange.
53
    return (change.file_id or b'', (change.path[0] or '', change.path[1] or ''),
54
            change.versioned, change.parent_id, change.name, change.kind,
55
            change.executable)
7067.6.2 by Jelmer Vernooij
Move key function to top-level.
56
57
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
58
class TestCompare(TestCaseWithTwoTrees):
59
6793.5.1 by Jelmer Vernooij
Hardcode fileids in fewer places.
60
    def _make_abc_tree(self, tree):
61
        """setup an abc content tree."""
62
        files = ['a', 'b/', 'b/c']
63
        self.build_tree(files, line_endings='binary',
64
                        transport=tree.controldir.root_transport)
6855.3.1 by Jelmer Vernooij
Several more fixes.
65
        tree.set_root_id(b'root-id')
66
        tree.add(files, [b'a-id', b'b-id', b'c-id'])
6793.5.1 by Jelmer Vernooij
Hardcode fileids in fewer places.
67
68
    def get_tree_no_parents_abc_content(self, tree, converter=None):
69
        """return a test tree with a, b/, b/c contents."""
70
        self._make_abc_tree(tree)
71
        return self._convert_tree(tree, converter)
72
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
73
    def test_compare_empty_trees(self):
74
        tree1 = self.make_branch_and_tree('1')
75
        tree2 = self.make_to_branch_and_tree('2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
76
        tree2.set_root_id(tree1.path2id(''))
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
77
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
78
        tree2 = self.get_tree_no_parents_no_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
79
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
80
        d = self.intertree_class(tree1, tree2).compare()
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
81
        self.assertEqual([], d.added)
82
        self.assertEqual([], d.modified)
83
        self.assertEqual([], d.removed)
84
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
85
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
86
87
    def test_empty_to_abc_content(self):
88
        tree1 = self.make_branch_and_tree('1')
89
        tree2 = self.make_to_branch_and_tree('2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
90
        tree2.set_root_id(tree1.path2id(''))
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
91
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
92
        tree2 = self.get_tree_no_parents_abc_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
93
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
94
        d = self.intertree_class(tree1, tree2).compare()
7358.11.3 by Jelmer Vernooij
TreeDelta holds TreeChange objects rather than tuples of various sizes.
95
        self.assertEqual(
96
            [('a', 'file'), ('b', 'directory'), ('b/c', 'file')],
97
            [(c.path[1], c.kind[1]) for c in d.added])
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
98
        self.assertEqual([], d.modified)
99
        self.assertEqual([], d.removed)
100
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
101
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
102
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
103
    def test_dangling(self):
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
104
        # This test depends on the ability for some trees to have a difference
105
        # between a 'versioned present' and 'versioned not present' (aka
106
        # dangling) file. In this test there are two trees each with a separate
107
        # dangling file, and the dangling files should be considered absent for
108
        # the test.
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
109
        tree1 = self.make_branch_and_tree('1')
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
110
        tree2 = self.make_to_branch_and_tree('2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
111
        tree2.set_root_id(tree1.path2id(''))
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
112
        self.build_tree(['2/a'])
113
        tree2.add('a')
114
        os.unlink('2/a')
115
        self.build_tree(['1/b'])
116
        tree1.add('b')
117
        os.unlink('1/b')
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
118
        # the conversion to test trees here will leave the trees intact for the
119
        # default intertree, but may perform a commit for other tree types,
120
        # which may reduce the validity of the test. XXX: Think about how to
121
        # address this.
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
122
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
123
        d = self.intertree_class(tree1, tree2).compare()
124
        self.assertEqual([], d.added)
125
        self.assertEqual([], d.modified)
126
        self.assertEqual([], d.removed)
127
        self.assertEqual([], d.renamed)
128
        self.assertEqual([], d.unchanged)
129
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
130
    def test_abc_content_to_empty(self):
131
        tree1 = self.make_branch_and_tree('1')
132
        tree2 = self.make_to_branch_and_tree('2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
133
        tree2.set_root_id(tree1.path2id(''))
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
134
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
135
        tree2 = self.get_tree_no_parents_no_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
136
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
137
        d = self.intertree_class(tree1, tree2).compare()
138
        self.assertEqual([], d.added)
139
        self.assertEqual([], d.modified)
7358.11.3 by Jelmer Vernooij
TreeDelta holds TreeChange objects rather than tuples of various sizes.
140
        self.assertEqual([('a', 'file'),
141
                          ('b', 'directory'),
142
                          ('b/c', 'file'),
143
                          ], [(c.path[0], c.kind[0]) for c in d.removed])
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
144
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
145
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
146
147
    def test_content_modification(self):
148
        tree1 = self.make_branch_and_tree('1')
149
        tree2 = self.make_to_branch_and_tree('2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
150
        tree2.set_root_id(tree1.path2id(''))
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
151
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
152
        tree2 = self.get_tree_no_parents_abc_content_2(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
153
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
154
        d = self.intertree_class(tree1, tree2).compare()
155
        self.assertEqual([], d.added)
7143.15.2 by Jelmer Vernooij
Run autopep8.
156
        self.assertEqual(
7358.11.3 by Jelmer Vernooij
TreeDelta holds TreeChange objects rather than tuples of various sizes.
157
            [('a', 'file', True, False)],
158
            [(c.path[1], c.kind[1], c.changed_content, c.meta_modified())
159
             for c in d.modified])
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
160
        self.assertEqual([], d.removed)
161
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
162
        self.assertEqual([], d.unchanged)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
163
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
164
    def test_meta_modification(self):
165
        tree1 = self.make_branch_and_tree('1')
166
        tree2 = self.make_to_branch_and_tree('2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
167
        tree2.set_root_id(tree1.path2id(''))
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
168
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
169
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
170
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
171
        d = self.intertree_class(tree1, tree2).compare()
172
        self.assertEqual([], d.added)
7143.15.2 by Jelmer Vernooij
Run autopep8.
173
        self.assertEqual(
7358.11.3 by Jelmer Vernooij
TreeDelta holds TreeChange objects rather than tuples of various sizes.
174
            [('b/c', 'file', False, True)],
175
            [(c.path[1], c.kind[1], c.changed_content, c.meta_modified())
176
             for c in d.modified])
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
177
        self.assertEqual([], d.removed)
178
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
179
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
180
181
    def test_file_rename(self):
182
        tree1 = self.make_branch_and_tree('1')
183
        tree2 = self.make_to_branch_and_tree('2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
184
        tree2.set_root_id(tree1.path2id(''))
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
185
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
186
        tree2 = self.get_tree_no_parents_abc_content_4(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
187
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
188
        d = self.intertree_class(tree1, tree2).compare()
189
        self.assertEqual([], d.added)
190
        self.assertEqual([], d.modified)
191
        self.assertEqual([], d.removed)
7143.15.2 by Jelmer Vernooij
Run autopep8.
192
        self.assertEqual(
7358.11.3 by Jelmer Vernooij
TreeDelta holds TreeChange objects rather than tuples of various sizes.
193
            [('a', 'd', 'file', False, False)],
194
            [(c.path[0], c.path[1], c.kind[1], c.changed_content, c.meta_modified())
195
             for c in d.renamed])
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
196
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
197
198
    def test_file_rename_and_modification(self):
199
        tree1 = self.make_branch_and_tree('1')
200
        tree2 = self.make_to_branch_and_tree('2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
201
        tree2.set_root_id(tree1.path2id(''))
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
202
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
203
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
204
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
205
        d = self.intertree_class(tree1, tree2).compare()
206
        self.assertEqual([], d.added)
207
        self.assertEqual([], d.modified)
208
        self.assertEqual([], d.removed)
7143.15.2 by Jelmer Vernooij
Run autopep8.
209
        self.assertEqual(
7358.11.3 by Jelmer Vernooij
TreeDelta holds TreeChange objects rather than tuples of various sizes.
210
            [('a', 'd', 'file', True, False)],
211
            [(c.path[0], c.path[1], c.kind[1], c.changed_content, c.meta_modified())
212
             for c in d.renamed])
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
213
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
214
215
    def test_file_rename_and_meta_modification(self):
216
        tree1 = self.make_branch_and_tree('1')
217
        tree2 = self.make_to_branch_and_tree('2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
218
        tree2.set_root_id(tree1.path2id(''))
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
219
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
220
        tree2 = self.get_tree_no_parents_abc_content_6(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
221
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
222
        d = self.intertree_class(tree1, tree2).compare()
223
        self.assertEqual([], d.added)
224
        self.assertEqual([], d.modified)
225
        self.assertEqual([], d.removed)
7143.15.2 by Jelmer Vernooij
Run autopep8.
226
        self.assertEqual(
7358.11.3 by Jelmer Vernooij
TreeDelta holds TreeChange objects rather than tuples of various sizes.
227
            [('b/c', 'e', 'file', False, True)],
228
            [(c.path[0], c.path[1], c.kind[1], c.changed_content, c.meta_modified())
229
             for c in d.renamed])
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
230
        self.assertEqual([], d.unchanged)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
231
232
    def test_empty_to_abc_content_a_only(self):
233
        tree1 = self.make_branch_and_tree('1')
234
        tree2 = self.make_to_branch_and_tree('2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
235
        tree2.set_root_id(tree1.path2id(''))
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
236
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
237
        tree2 = self.get_tree_no_parents_abc_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
238
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
239
        d = self.intertree_class(tree1, tree2).compare(specific_files=['a'])
7358.11.3 by Jelmer Vernooij
TreeDelta holds TreeChange objects rather than tuples of various sizes.
240
        self.assertEqual(
241
            [('a', 'file')],
242
            [(c.path[1], c.kind[1]) for c in d.added])
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
243
        self.assertEqual([], d.modified)
244
        self.assertEqual([], d.removed)
245
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
246
        self.assertEqual([], d.unchanged)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
247
248
    def test_empty_to_abc_content_a_and_c_only(self):
249
        tree1 = self.make_branch_and_tree('1')
250
        tree2 = self.make_to_branch_and_tree('2')
251
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
252
        tree2 = self.get_tree_no_parents_abc_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
253
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
254
        d = self.intertree_class(tree1, tree2).compare(
255
            specific_files=['a', 'b/c'])
256
        self.assertEqual(
7358.11.3 by Jelmer Vernooij
TreeDelta holds TreeChange objects rather than tuples of various sizes.
257
            [('a', 'file'),
258
             (u'b', 'directory'),
259
             ('b/c', 'file')],
260
            [(c.path[1], c.kind[1]) for c in d.added])
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
261
        self.assertEqual([], d.modified)
262
        self.assertEqual([], d.removed)
263
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
264
        self.assertEqual([], d.unchanged)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
265
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
266
    def test_empty_to_abc_content_c_only(self):
267
        tree1 = self.make_branch_and_tree('1')
268
        tree2 = self.make_to_branch_and_tree('2')
269
        tree1 = self.get_tree_no_parents_no_content(tree1)
270
        tree2 = self.get_tree_no_parents_abc_content(tree2)
271
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
272
        d = self.intertree_class(tree1, tree2).compare(
273
            specific_files=['b/c'])
274
        self.assertEqual(
7358.11.3 by Jelmer Vernooij
TreeDelta holds TreeChange objects rather than tuples of various sizes.
275
            [(u'b', 'directory'), ('b/c', 'file')],
276
            [(c.path[1], c.kind[1]) for c in d.added])
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
277
        self.assertEqual([], d.modified)
278
        self.assertEqual([], d.removed)
279
        self.assertEqual([], d.renamed)
280
        self.assertEqual([], d.unchanged)
281
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
282
    def test_empty_to_abc_content_b_only(self):
283
        """Restricting to a dir matches the children of the dir."""
284
        tree1 = self.make_branch_and_tree('1')
285
        tree2 = self.make_to_branch_and_tree('2')
286
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
287
        tree2 = self.get_tree_no_parents_abc_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
288
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
289
        d = self.intertree_class(tree1, tree2).compare(specific_files=['b'])
290
        self.assertEqual(
7358.11.3 by Jelmer Vernooij
TreeDelta holds TreeChange objects rather than tuples of various sizes.
291
            [('b', 'directory'), ('b/c', 'file')],
292
            [(c.path[1], c.kind[1]) for c in d.added])
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
293
        self.assertEqual([], d.modified)
294
        self.assertEqual([], d.removed)
295
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
296
        self.assertEqual([], d.unchanged)
297
298
    def test_unchanged_with_renames_and_modifications(self):
299
        """want_unchanged should generate a list of unchanged entries."""
300
        tree1 = self.make_branch_and_tree('1')
301
        tree2 = self.make_to_branch_and_tree('2')
302
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
303
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
304
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
305
        d = self.intertree_class(tree1, tree2).compare(want_unchanged=True)
306
        self.assertEqual([], d.added)
307
        self.assertEqual([], d.modified)
308
        self.assertEqual([], d.removed)
7358.11.3 by Jelmer Vernooij
TreeDelta holds TreeChange objects rather than tuples of various sizes.
309
        self.assertEqual(
310
            [('a', 'd', 'file', True, False)],
311
            [(c.path[0], c.path[1], c.kind[1], c.changed_content, c.meta_modified()) for c in d.renamed])
312
        self.assertEqual(
313
            [(u'b', 'directory'), (u'b/c', 'file')],
314
            [(c.path[0], c.kind[0]) for c in d.unchanged])
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
315
316
    def test_extra_trees_finds_ids(self):
317
        """Ask for a delta between two trees with a path present in a third."""
318
        tree1 = self.make_branch_and_tree('1')
319
        tree2 = self.make_to_branch_and_tree('2')
320
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
321
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
322
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
323
        d = self.intertree_class(tree1, tree2).compare(specific_files=['b'])
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
324
        # the type of tree-3 does not matter - it is used as a lookup, not
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
325
        # a dispatch. XXX: For dirstate it does speak to the optimisability of
326
        # the lookup, in merged trees it can be fast-pathed. We probably want
327
        # two tests: one as is, and one with it as a pending merge.
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
328
        tree3 = self.make_branch_and_tree('3')
329
        tree3 = self.get_tree_no_parents_abc_content_6(tree3)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
330
        tree3.lock_read()
331
        self.addCleanup(tree3.unlock)
6855.3.1 by Jelmer Vernooij
Several more fixes.
332
        # tree 3 has 'e' which is b'c-id'. Tree 1 has c-id at b/c, and Tree 2
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
333
        # has c-id at b/c with its exec flag toggled.
334
        # without extra_trees, we should get no modifications from this
335
        # so do one, to be sure the test is valid.
336
        d = self.intertree_class(tree1, tree2).compare(
337
            specific_files=['e'])
338
        self.assertEqual([], d.modified)
339
        # now give it an additional lookup:
340
        d = self.intertree_class(tree1, tree2).compare(
341
            specific_files=['e'], extra_trees=[tree3])
342
        self.assertEqual([], d.added)
7358.11.3 by Jelmer Vernooij
TreeDelta holds TreeChange objects rather than tuples of various sizes.
343
        self.assertEqual(
344
            [('b/c', 'file', False, True)],
345
            [(c.path[1], c.kind[1], c.changed_content, c.meta_modified()) for c in d.modified])
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
346
        self.assertEqual([], d.removed)
347
        self.assertEqual([], d.renamed)
348
        self.assertEqual([], d.unchanged)
1852.9.5 by Robert Collins
Add tests for require_versioned to the InterTree.compare() test suite.
349
350
    def test_require_versioned(self):
351
        # this does not quite robustly test, as it is passing in missing paths
352
        # rather than present-but-not-versioned paths. At the moment there is
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
353
        # no mechanism for managing the test trees (which are readonly) to
1852.9.5 by Robert Collins
Add tests for require_versioned to the InterTree.compare() test suite.
354
        # get present-but-not-versioned files for trees that can do that.
355
        tree1 = self.make_branch_and_tree('1')
356
        tree2 = self.make_to_branch_and_tree('2')
357
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
358
        tree2 = self.get_tree_no_parents_abc_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
359
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
360
        self.assertRaises(errors.PathsNotVersionedError,
7143.15.2 by Jelmer Vernooij
Run autopep8.
361
                          self.intertree_class(tree1, tree2).compare,
362
                          specific_files=['d'],
363
                          require_versioned=True)
2012.1.1 by Aaron Bentley
Implement change iterator
364
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
365
    def test_default_ignores_unversioned_files(self):
366
        tree1 = self.make_branch_and_tree('tree1')
367
        tree2 = self.make_to_branch_and_tree('tree2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
368
        tree2.set_root_id(tree1.path2id(''))
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
369
        self.build_tree(['tree1/a', 'tree1/c',
370
                         'tree2/a', 'tree2/b', 'tree2/c'])
6855.3.1 by Jelmer Vernooij
Several more fixes.
371
        tree1.add(['a', 'c'], [b'a-id', b'c-id'])
372
        tree2.add(['a', 'c'], [b'a-id', b'c-id'])
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
373
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
374
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.7.91 by Robert Collins
Move unknown detection in long status into the delta creation, saving a tree-scan.
375
        d = self.intertree_class(tree1, tree2).compare()
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
376
        self.assertEqual([], d.added)
7358.11.3 by Jelmer Vernooij
TreeDelta holds TreeChange objects rather than tuples of various sizes.
377
        self.assertEqual([(u'a', 'file', True, False),
378
                          (u'c', 'file', True, False)],
379
                         [(c.path[1], c.kind[1], c.changed_content, c.meta_modified())
380
                          for c in d.modified])
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
381
        self.assertEqual([], d.removed)
382
        self.assertEqual([], d.renamed)
383
        self.assertEqual([], d.unchanged)
384
        self.assertEqual([], d.unversioned)
385
386
    def test_unversioned_paths_in_tree(self):
387
        tree1 = self.make_branch_and_tree('tree1')
388
        tree2 = self.make_to_branch_and_tree('tree2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
389
        tree2.set_root_id(tree1.path2id(''))
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
390
        self.build_tree(['tree2/file', 'tree2/dir/'])
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
391
        if has_symlinks():
392
            os.symlink('target', 'tree2/link')
393
            links_supported = True
394
        else:
395
            links_supported = False
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
396
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
397
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
398
        d = self.intertree_class(tree1, tree2).compare(want_unversioned=True)
399
        self.assertEqual([], d.added)
400
        self.assertEqual([], d.modified)
401
        self.assertEqual([], d.removed)
402
        self.assertEqual([], d.renamed)
403
        self.assertEqual([], d.unchanged)
7358.11.3 by Jelmer Vernooij
TreeDelta holds TreeChange objects rather than tuples of various sizes.
404
        expected_unversioned = [(u'dir', 'directory'),
405
                                (u'file', 'file')]
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
406
        if links_supported:
7358.11.3 by Jelmer Vernooij
TreeDelta holds TreeChange objects rather than tuples of various sizes.
407
            expected_unversioned.append((u'link', 'symlink'))
408
        self.assertEqual(
409
            expected_unversioned,
410
            [(c.path[1], c.kind[1]) for c in d.unversioned])
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
411
2012.1.1 by Aaron Bentley
Implement change iterator
412
2012.1.3 by Aaron Bentley
Always generate tuples (because kind is always used, even when not different)
413
class TestIterChanges(TestCaseWithTwoTrees):
2012.1.1 by Aaron Bentley
Implement change iterator
414
    """Test the comparison iterator"""
415
6793.5.1 by Jelmer Vernooij
Hardcode fileids in fewer places.
416
    def _make_abc_tree(self, tree):
417
        """setup an abc content tree."""
418
        files = ['a', 'b/', 'b/c']
419
        self.build_tree(files, line_endings='binary',
420
                        transport=tree.controldir.root_transport)
6855.4.1 by Jelmer Vernooij
Yet more bees.
421
        tree.set_root_id(b'root-id')
6855.3.1 by Jelmer Vernooij
Several more fixes.
422
        tree.add(files, [b'a-id', b'b-id', b'c-id'])
6793.5.1 by Jelmer Vernooij
Hardcode fileids in fewer places.
423
424
    def get_tree_no_parents_abc_content(self, tree, converter=None):
425
        """return a test tree with a, b/, b/c contents."""
426
        self._make_abc_tree(tree)
427
        return self._convert_tree(tree, converter)
428
429
    def get_tree_no_parents_abc_content_7(self, tree, converter=None):
430
        """return a test tree with a, b/, d/e contents.
431
6855.3.1 by Jelmer Vernooij
Several more fixes.
432
        This variation adds a dir 'd' (b'd-id'), renames b to d/e.
6793.5.1 by Jelmer Vernooij
Hardcode fileids in fewer places.
433
        """
434
        self._make_abc_tree(tree)
435
        self.build_tree(['d/'], transport=tree.controldir.root_transport)
6855.3.1 by Jelmer Vernooij
Several more fixes.
436
        tree.add(['d'], [b'd-id'])
7490.77.2 by Jelmer Vernooij
Split out git and bzr-specific transforms.
437
        tt = tree.transform()
6793.5.1 by Jelmer Vernooij
Hardcode fileids in fewer places.
438
        trans_id = tt.trans_id_tree_path('b')
439
        parent_trans_id = tt.trans_id_tree_path('d')
440
        tt.adjust_path('e', parent_trans_id, trans_id)
441
        tt.apply()
442
        return self._convert_tree(tree, converter)
443
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
444
    def assertEqualIterChanges(self, left_changes, right_changes):
445
        """Assert that left_changes == right_changes.
446
447
        :param left_changes: A list of the output from iter_changes.
448
        :param right_changes: A list of the output from iter_changes.
449
        """
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
450
        left_changes = self.sorted(left_changes)
451
        right_changes = self.sorted(right_changes)
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
452
        if left_changes == right_changes:
453
            return
454
        # setify to get item by item differences, but we can only do this
455
        # when all the ids are unique on both sides.
456
        left_dict = dict((item[0], item) for item in left_changes)
457
        right_dict = dict((item[0], item) for item in right_changes)
7143.15.2 by Jelmer Vernooij
Run autopep8.
458
        if (len(left_dict) != len(left_changes)
459
                or len(right_dict) != len(right_changes)):
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
460
            # Can't do a direct comparison. We could do a sequence diff, but
461
            # for now just do a regular assertEqual for now.
462
            self.assertEqual(left_changes, right_changes)
463
        keys = set(left_dict).union(set(right_dict))
464
        different = []
465
        same = []
466
        for key in keys:
467
            left_item = left_dict.get(key)
468
            right_item = right_dict.get(key)
469
            if left_item == right_item:
470
                same.append(str(left_item))
471
            else:
472
                different.append(" %s\n %s" % (left_item, right_item))
7143.15.2 by Jelmer Vernooij
Run autopep8.
473
        self.fail("iter_changes output different. Unchanged items:\n"
474
                  + "\n".join(same) + "\nChanged items:\n" + "\n".join(different))
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
475
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
476
    def do_iter_changes(self, tree1, tree2, **extra_args):
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
477
        """Helper to run iter_changes from tree1 to tree2.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
478
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
479
        :param tree1, tree2:  The source and target trees. These will be locked
480
            automatically.
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
481
        :param **extra_args: Extra args to pass to iter_changes. This is not
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
482
            inspected by this test helper.
483
        """
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
484
        with tree1.lock_read(), tree2.lock_read():
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
485
            # sort order of output is not strictly defined
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
486
            return self.sorted(self.intertree_class(tree1, tree2)
7143.15.2 by Jelmer Vernooij
Run autopep8.
487
                               .iter_changes(**extra_args))
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
488
4503.1.3 by Vincent Ladeuil
Take review comments into account.
489
    def check_has_changes(self, expected, tree1, tree2):
490
        # has_changes is defined for mutable trees only
491
        if not isinstance(tree2, mutabletree.MutableTree):
492
            if isinstance(tree1, mutabletree.MutableTree):
493
                # Let's switch the trees since has_changes() is commutative
494
                # (where we can apply it)
495
                tree2, tree1 = tree1, tree2
496
            else:
497
                # Neither tree can be used
498
                return
7199.3.1 by Jelmer Vernooij
Don't report empty directories as changes.
499
        with tree1.lock_read(), tree2.lock_read():
500
            return tree2.has_changes(tree1)
4503.1.1 by Vincent Ladeuil
Add tree.has_changes() to quickly check iter_changes().
501
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
502
    def mutable_trees_to_locked_test_trees(self, tree1, tree2):
503
        """Convert the working trees into test trees.
504
505
        Read lock them, and add the unlock to the cleanup.
506
        """
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
507
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
508
        tree1.lock_read()
509
        self.addCleanup(tree1.unlock)
510
        tree2.lock_read()
511
        self.addCleanup(tree2.unlock)
512
        return tree1, tree2
513
2255.7.15 by John Arbash Meinel
Try to create an intertree test that exposes the walkdir vs dirstate mismatch. No luck yet.
514
    def make_tree_with_special_names(self):
515
        """Create a tree with filenames chosen to exercise the walk order."""
516
        tree1 = self.make_branch_and_tree('tree1')
517
        tree2 = self.make_to_branch_and_tree('tree2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
518
        tree2.set_root_id(tree1.path2id(''))
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
519
        paths = self._create_special_names(tree2, 'tree2')
6855.3.1 by Jelmer Vernooij
Several more fixes.
520
        tree2.commit('initial', rev_id=b'rev-1')
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
521
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
522
        return (tree1, tree2, paths)
2255.7.22 by John Arbash Meinel
add a test that shows _iter_changes works when only contents have changed, and nothing is considered newly added.
523
524
    def make_trees_with_special_names(self):
525
        """Both trees will use the special names.
526
527
        But the contents will differ for each file.
528
        """
529
        tree1 = self.make_branch_and_tree('tree1')
530
        tree2 = self.make_to_branch_and_tree('tree2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
531
        tree2.set_root_id(tree1.path2id(''))
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
532
        paths = self._create_special_names(tree1, 'tree1')
533
        paths = self._create_special_names(tree2, 'tree2')
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
534
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
535
        return (tree1, tree2, paths)
2255.7.22 by John Arbash Meinel
add a test that shows _iter_changes works when only contents have changed, and nothing is considered newly added.
536
537
    def _create_special_names(self, tree, base_path):
538
        """Create a tree with paths that expose differences in sort orders."""
539
        # Each directory will have a single file named 'f' inside
540
        dirs = ['a',
541
                'a-a',
542
                'a/a',
543
                'a/a-a',
544
                'a/a/a',
545
                'a/a/a-a',
546
                'a/a/a/a',
547
                'a/a/a/a-a',
548
                'a/a/a/a/a',
7143.15.2 by Jelmer Vernooij
Run autopep8.
549
                ]
2255.7.22 by John Arbash Meinel
add a test that shows _iter_changes works when only contents have changed, and nothing is considered newly added.
550
        with_slashes = []
551
        paths = []
552
        path_ids = []
553
        for d in dirs:
554
            with_slashes.append(base_path + '/' + d + '/')
555
            with_slashes.append(base_path + '/' + d + '/f')
556
            paths.append(d)
7143.15.2 by Jelmer Vernooij
Run autopep8.
557
            paths.append(d + '/f')
6855.3.1 by Jelmer Vernooij
Several more fixes.
558
            path_ids.append((d.replace('/', '_') + '-id').encode('ascii'))
559
            path_ids.append((d.replace('/', '_') + '_f-id').encode('ascii'))
2255.7.22 by John Arbash Meinel
add a test that shows _iter_changes works when only contents have changed, and nothing is considered newly added.
560
        self.build_tree(with_slashes)
561
        tree.add(paths, path_ids)
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
562
        return paths
2255.7.15 by John Arbash Meinel
Try to create an intertree test that exposes the walkdir vs dirstate mismatch. No luck yet.
563
2012.1.1 by Aaron Bentley
Implement change iterator
564
    def test_compare_empty_trees(self):
565
        tree1 = self.make_branch_and_tree('1')
566
        tree2 = self.make_to_branch_and_tree('2')
567
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
568
        tree2 = self.get_tree_no_parents_no_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
569
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
3254.1.2 by Aaron Bentley
Fix doiter_changes
570
        self.assertEqual([], self.do_iter_changes(tree1, tree2))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
571
        self.check_has_changes(False, tree1, tree2)
2012.1.1 by Aaron Bentley
Implement change iterator
572
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
573
    def added(self, tree, path):
574
        entry = self.get_path_entry(tree, path)
7490.120.3 by Jelmer Vernooij
Split out InventoryTreeChange from TreeChange.
575
        return InventoryTreeChange(
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
576
            entry.file_id, (None, path), True, (False, True), (None, entry.parent_id),
7322.1.7 by Jelmer Vernooij
Fix remaining tests.
577
            (None, entry.name), (None, entry.kind),
578
            (None, entry.executable))
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
579
3363.14.7 by Aaron Bentley
Get more tests passing
580
    @staticmethod
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
581
    def get_path_entry(tree, path):
6885.6.1 by Jelmer Vernooij
Support specific_files argument to Tree.iter_entries_by_dir.
582
        iterator = tree.iter_entries_by_dir(specific_files=[path])
6793.5.1 by Jelmer Vernooij
Hardcode fileids in fewer places.
583
        try:
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
584
            return next(iterator)[1]
6793.5.1 by Jelmer Vernooij
Hardcode fileids in fewer places.
585
        except StopIteration:
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
586
            raise KeyError(path)
3363.14.7 by Aaron Bentley
Get more tests passing
587
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
588
    def changed_content(self, tree, path):
589
        entry = self.get_path_entry(tree, path)
7490.120.3 by Jelmer Vernooij
Split out InventoryTreeChange from TreeChange.
590
        return InventoryTreeChange(
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
591
            entry.file_id, (path, path), True, (True, True),
7322.1.7 by Jelmer Vernooij
Fix remaining tests.
592
            (entry.parent_id, entry.parent_id),
593
            (entry.name, entry.name), (entry.kind, entry.kind),
594
            (entry.executable, entry.executable))
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
595
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
596
    def kind_changed(self, from_tree, to_tree, from_path, to_path):
597
        old_entry = self.get_path_entry(from_tree, from_path)
598
        new_entry = self.get_path_entry(to_tree, to_path)
7490.120.3 by Jelmer Vernooij
Split out InventoryTreeChange from TreeChange.
599
        return InventoryTreeChange(
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
600
            new_entry.file_id, (from_path, to_path), True, (True, True),
7322.1.7 by Jelmer Vernooij
Fix remaining tests.
601
            (old_entry.parent_id, new_entry.parent_id),
602
            (old_entry.name, new_entry.name),
603
            (old_entry.kind, new_entry.kind),
604
            (old_entry.executable, new_entry.executable))
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
605
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
606
    def missing(self, file_id, from_path, to_path, parent_id, kind):
607
        _, from_basename = os.path.split(from_path)
608
        _, to_basename = os.path.split(to_path)
609
        # missing files have both paths, but no kind.
7490.120.3 by Jelmer Vernooij
Split out InventoryTreeChange from TreeChange.
610
        return InventoryTreeChange(
7322.1.7 by Jelmer Vernooij
Fix remaining tests.
611
            file_id, (from_path, to_path), True, (True, True),
612
            (parent_id, parent_id),
613
            (from_basename, to_basename), (kind, None), (False, False))
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
614
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
615
    def deleted(self, tree, path):
616
        entry = self.get_path_entry(tree, path)
7490.120.3 by Jelmer Vernooij
Split out InventoryTreeChange from TreeChange.
617
        return InventoryTreeChange(
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
618
            entry.file_id, (path, None), True, (True, False), (entry.parent_id, None),
7322.1.7 by Jelmer Vernooij
Fix remaining tests.
619
            (entry.name, None), (entry.kind, None),
620
            (entry.executable, None))
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
621
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
622
    def renamed(self, from_tree, to_tree, from_path, to_path, content_changed):
623
        from_entry = self.get_path_entry(from_tree, from_path)
624
        to_entry = self.get_path_entry(to_tree, to_path)
7490.120.3 by Jelmer Vernooij
Split out InventoryTreeChange from TreeChange.
625
        return InventoryTreeChange(
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
626
            to_entry.file_id, (from_path, to_path), content_changed, (True, True),
7322.1.7 by Jelmer Vernooij
Fix remaining tests.
627
            (from_entry.parent_id, to_entry.parent_id),
628
            (from_entry.name, to_entry.name),
629
            (from_entry.kind, to_entry.kind),
630
            (from_entry.executable, to_entry.executable))
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
631
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
632
    def unchanged(self, tree, path):
633
        entry = self.get_path_entry(tree, path)
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
634
        parent = entry.parent_id
635
        name = entry.name
636
        kind = entry.kind
637
        executable = entry.executable
7490.120.3 by Jelmer Vernooij
Split out InventoryTreeChange from TreeChange.
638
        return InventoryTreeChange(
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
639
            entry.file_id, (path, path), False, (True, True),
7322.1.7 by Jelmer Vernooij
Fix remaining tests.
640
            (parent, parent), (name, name), (kind, kind),
641
            (executable, executable))
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
642
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
643
    def unversioned(self, tree, path):
644
        """Create an unversioned result."""
645
        _, basename = os.path.split(path)
3363.14.7 by Aaron Bentley
Get more tests passing
646
        kind = tree._comparison_data(None, path)[0]
7490.120.3 by Jelmer Vernooij
Split out InventoryTreeChange from TreeChange.
647
        return InventoryTreeChange(
7322.1.7 by Jelmer Vernooij
Fix remaining tests.
648
            None, (None, path), True, (False, False), (None, None),
649
            (None, basename), (None, kind),
650
            (None, False))
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
651
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
652
    def sorted(self, changes):
7067.6.2 by Jelmer Vernooij
Move key function to top-level.
653
        return sorted(changes, key=_change_key)
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
654
2012.1.1 by Aaron Bentley
Implement change iterator
655
    def test_empty_to_abc_content(self):
656
        tree1 = self.make_branch_and_tree('1')
657
        tree2 = self.make_to_branch_and_tree('2')
658
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
659
        tree2 = self.get_tree_no_parents_abc_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
660
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
661
        expected_results = self.sorted([
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
662
            self.added(tree2, ''),
663
            self.added(tree2, 'a'),
664
            self.added(tree2, 'b'),
665
            self.added(tree2, 'b/c'),
666
            self.deleted(tree1, '')])
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
667
        self.assertEqual(expected_results, self.do_iter_changes(tree1, tree2))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
668
        self.check_has_changes(True, tree1, tree2)
2012.1.1 by Aaron Bentley
Implement change iterator
669
2748.3.1 by Aaron Bentley
Start supporting [] for empty list
670
    def test_empty_specific_files(self):
671
        tree1 = self.make_branch_and_tree('1')
672
        tree2 = self.make_to_branch_and_tree('2')
673
        tree1 = self.get_tree_no_parents_no_content(tree1)
674
        tree2 = self.get_tree_no_parents_abc_content(tree2)
675
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
676
        self.assertEqual([],
7143.15.2 by Jelmer Vernooij
Run autopep8.
677
                         self.do_iter_changes(tree1, tree2, specific_files=[]))
2748.3.1 by Aaron Bentley
Start supporting [] for empty list
678
679
    def test_no_specific_files(self):
680
        tree1 = self.make_branch_and_tree('1')
681
        tree2 = self.make_to_branch_and_tree('2')
682
        tree1 = self.get_tree_no_parents_no_content(tree1)
683
        tree2 = self.get_tree_no_parents_abc_content(tree2)
684
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
685
        expected_results = self.sorted([
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
686
            self.added(tree2, ''),
687
            self.added(tree2, 'a'),
688
            self.added(tree2, 'b'),
689
            self.added(tree2, 'b/c'),
690
            self.deleted(tree1, '')])
2796.1.2 by Aaron Bentley
Harmonize test_no_specific_files with test_empty_to_abc_content
691
        self.assertEqual(expected_results, self.do_iter_changes(tree1, tree2))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
692
        self.check_has_changes(True, tree1, tree2)
2748.3.1 by Aaron Bentley
Start supporting [] for empty list
693
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
694
    def test_empty_to_abc_content_a_only(self):
695
        tree1 = self.make_branch_and_tree('1')
696
        tree2 = self.make_to_branch_and_tree('2')
697
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
698
        tree2 = self.get_tree_no_parents_abc_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
699
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
700
        self.assertEqual(
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
701
            self.sorted([self.added(tree2, ''),
702
                         self.added(tree2, 'a'),
703
                         self.deleted(tree1, '')]),
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
704
            self.do_iter_changes(tree1, tree2, specific_files=['a']))
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
705
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
706
    def test_abc_content_to_empty_a_only(self):
707
        # For deletes we don't need to pickup parents.
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
708
        tree1 = self.make_branch_and_tree('1')
709
        tree2 = self.make_to_branch_and_tree('2')
710
        tree1 = self.get_tree_no_parents_abc_content(tree1)
711
        tree2 = self.get_tree_no_parents_no_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
712
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
713
        self.assertEqual(
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
714
            [self.deleted(tree1, 'a')],
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
715
            self.do_iter_changes(tree1, tree2, specific_files=['a']))
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
716
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
717
    def test_abc_content_to_empty_b_only(self):
718
        # When b stops being a directory we have to pick up b/c as well.
719
        tree1 = self.make_branch_and_tree('1')
720
        tree2 = self.make_to_branch_and_tree('2')
721
        tree1 = self.get_tree_no_parents_abc_content(tree1)
722
        tree2 = self.get_tree_no_parents_no_content(tree2)
723
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
724
        self.assertEqual(
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
725
            [self.deleted(tree1, 'b'), self.deleted(tree1, 'b/c')],
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
726
            self.do_iter_changes(tree1, tree2, specific_files=['b']))
727
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
728
    def test_empty_to_abc_content_a_and_c_only(self):
729
        tree1 = self.make_branch_and_tree('1')
730
        tree2 = self.make_to_branch_and_tree('2')
731
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
732
        tree2 = self.get_tree_no_parents_abc_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
733
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
734
        expected_result = self.sorted([
735
            self.added(tree2, ''),
736
            self.added(tree2, 'a'), self.added(tree2, 'b'),
737
            self.added(tree2, 'b/c'), self.deleted(tree1, '')])
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
738
        self.assertEqual(expected_result,
7143.15.2 by Jelmer Vernooij
Run autopep8.
739
                         self.do_iter_changes(tree1, tree2, specific_files=['a', 'b/c']))
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
740
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
741
    def test_abc_content_to_empty(self):
2012.1.1 by Aaron Bentley
Implement change iterator
742
        tree1 = self.make_branch_and_tree('1')
743
        tree2 = self.make_to_branch_and_tree('2')
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
744
        tree1 = self.get_tree_no_parents_abc_content(tree1)
745
        tree2 = self.get_tree_no_parents_no_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
746
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
747
        expected_results = self.sorted([
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
748
            self.added(tree2, ''),
749
            self.deleted(tree1, ''), self.deleted(tree1, 'a'),
750
            self.deleted(tree1, 'b'), self.deleted(tree1, 'b/c')])
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
751
        self.assertEqual(
752
            expected_results,
753
            self.do_iter_changes(tree1, tree2))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
754
        self.check_has_changes(True, tree1, tree2)
2012.1.1 by Aaron Bentley
Implement change iterator
755
756
    def test_content_modification(self):
757
        tree1 = self.make_branch_and_tree('1')
758
        tree2 = self.make_to_branch_and_tree('2')
759
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
760
        tree2 = self.get_tree_no_parents_abc_content_2(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
761
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
762
        root_id = tree1.path2id('')
6855.3.1 by Jelmer Vernooij
Several more fixes.
763
        self.assertEqual([(b'a-id', ('a', 'a'), True, (True, True),
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
764
                           (root_id, root_id), ('a', 'a'),
7391.3.3 by Jelmer Vernooij
Fix tests.
765
                           ('file', 'file'), (False, False), False)],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
766
                         self.do_iter_changes(tree1, tree2))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
767
        self.check_has_changes(True, tree1, tree2)
2012.1.1 by Aaron Bentley
Implement change iterator
768
769
    def test_meta_modification(self):
770
        tree1 = self.make_branch_and_tree('1')
771
        tree2 = self.make_to_branch_and_tree('2')
772
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
773
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
774
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
6855.3.1 by Jelmer Vernooij
Several more fixes.
775
        self.assertEqual([(b'c-id', ('b/c', 'b/c'), False, (True, True),
776
                           (b'b-id', b'b-id'), ('c', 'c'), ('file', 'file'),
7391.3.3 by Jelmer Vernooij
Fix tests.
777
                           (False, True), False)],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
778
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
779
2255.7.6 by Robert Collins
Test for iterating changes past empty directories.
780
    def test_empty_dir(self):
781
        """an empty dir should not cause glitches to surrounding files."""
782
        tree1 = self.make_branch_and_tree('1')
783
        tree2 = self.make_to_branch_and_tree('2')
784
        tree1 = self.get_tree_no_parents_abc_content(tree1)
785
        tree2 = self.get_tree_no_parents_abc_content(tree2)
786
        # the pathname is chosen to fall between 'a' and 'b'.
787
        self.build_tree(['1/a-empty/', '2/a-empty/'])
6973.11.7 by Jelmer Vernooij
Fix more tests.
788
        tree1.add(['a-empty'], [b'a-empty'])
789
        tree2.add(['a-empty'], [b'a-empty'])
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
790
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.7.6 by Robert Collins
Test for iterating changes past empty directories.
791
        expected = []
792
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
793
2012.1.1 by Aaron Bentley
Implement change iterator
794
    def test_file_rename(self):
795
        tree1 = self.make_branch_and_tree('1')
796
        tree2 = self.make_to_branch_and_tree('2')
797
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
798
        tree2 = self.get_tree_no_parents_abc_content_4(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
799
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
800
        root_id = tree1.path2id('')
6821.2.1 by Jelmer Vernooij
Fix tests.
801
        self.assertEqual([(tree1.path2id('a'), ('a', 'd'), False, (True, True),
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
802
                           (root_id, root_id), ('a', 'd'), ('file', 'file'),
7391.3.3 by Jelmer Vernooij
Fix tests.
803
                           (False, False), False)],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
804
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
805
806
    def test_file_rename_and_modification(self):
807
        tree1 = self.make_branch_and_tree('1')
808
        tree2 = self.make_to_branch_and_tree('2')
809
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
810
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
811
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
812
        root_id = tree1.path2id('')
6855.3.1 by Jelmer Vernooij
Several more fixes.
813
        self.assertEqual([(b'a-id', ('a', 'd'), True, (True, True),
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
814
                           (root_id, root_id), ('a', 'd'), ('file', 'file'),
7391.3.3 by Jelmer Vernooij
Fix tests.
815
                           (False, False), False)],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
816
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
817
4570.2.5 by Robert Collins
Review feedback, including finding a bug with changes at the root.
818
    def test_specific_content_modification_grabs_parents(self):
819
        # WHen the only direct change to a specified file is a content change,
820
        # and its in a reparented subtree, the parents are grabbed.
821
        tree1 = self.make_branch_and_tree('1')
6855.4.1 by Jelmer Vernooij
Yet more bees.
822
        tree1.mkdir('changing', b'parent-id')
823
        tree1.mkdir('changing/unchanging', b'mid-id')
824
        tree1.add(['changing/unchanging/file'], [b'file-id'], ['file'])
6809.4.8 by Jelmer Vernooij
Fix some test failures.
825
        tree1.put_file_bytes_non_atomic(
7206.6.3 by Jelmer Vernooij
Remove file_id argument in a few more places.
826
            'changing/unchanging/file', b'a file')
4570.2.5 by Robert Collins
Review feedback, including finding a bug with changes at the root.
827
        tree2 = self.make_to_branch_and_tree('2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
828
        tree2.set_root_id(tree1.path2id(''))
6855.4.1 by Jelmer Vernooij
Yet more bees.
829
        tree2.mkdir('changed', b'parent-id')
830
        tree2.mkdir('changed/unchanging', b'mid-id')
831
        tree2.add(['changed/unchanging/file'], [b'file-id'], ['file'])
6809.4.8 by Jelmer Vernooij
Fix some test failures.
832
        tree2.put_file_bytes_non_atomic(
7206.6.3 by Jelmer Vernooij
Remove file_id argument in a few more places.
833
            'changed/unchanging/file', b'changed content')
4570.2.5 by Robert Collins
Review feedback, including finding a bug with changes at the root.
834
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
835
        # parent-id has changed, as has file-id
836
        root_id = tree1.path2id('')
837
        self.assertEqualIterChanges(
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
838
            [self.renamed(tree1, tree2, 'changing', 'changed', False),
839
             self.renamed(tree1, tree2, 'changing/unchanging/file', 'changed/unchanging/file', True)],
7143.15.2 by Jelmer Vernooij
Run autopep8.
840
            self.do_iter_changes(tree1, tree2,
841
                                 specific_files=['changed/unchanging/file']))
4570.2.5 by Robert Collins
Review feedback, including finding a bug with changes at the root.
842
843
    def test_specific_content_modification_grabs_parents_root_changes(self):
844
        # WHen the only direct change to a specified file is a content change,
845
        # and its in a reparented subtree, the parents are grabbed, even if
846
        # that includes the root.
847
        tree1 = self.make_branch_and_tree('1')
6855.4.1 by Jelmer Vernooij
Yet more bees.
848
        tree1.set_root_id(b'old')
849
        tree1.mkdir('changed', b'parent-id')
850
        tree1.mkdir('changed/unchanging', b'mid-id')
851
        tree1.add(['changed/unchanging/file'], [b'file-id'], ['file'])
7192.5.2 by Jelmer Vernooij
Fixes.
852
        tree1.put_file_bytes_non_atomic('changed/unchanging/file', b'a file')
4570.2.5 by Robert Collins
Review feedback, including finding a bug with changes at the root.
853
        tree2 = self.make_to_branch_and_tree('2')
6855.4.1 by Jelmer Vernooij
Yet more bees.
854
        tree2.set_root_id(b'new')
855
        tree2.mkdir('changed', b'parent-id')
856
        tree2.mkdir('changed/unchanging', b'mid-id')
857
        tree2.add(['changed/unchanging/file'], [b'file-id'], ['file'])
6809.4.8 by Jelmer Vernooij
Fix some test failures.
858
        tree2.put_file_bytes_non_atomic(
7192.5.2 by Jelmer Vernooij
Fixes.
859
            'changed/unchanging/file', b'changed content')
4570.2.5 by Robert Collins
Review feedback, including finding a bug with changes at the root.
860
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
861
        # old is gone, new is added, parent-id has changed(reparented), as has
862
        # file-id(content)
863
        root_id = tree1.path2id('')
864
        self.assertEqualIterChanges(
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
865
            [self.renamed(tree1, tree2, 'changed', 'changed', False),
866
             self.added(tree2, ''),
867
             self.deleted(tree1, ''),
868
             self.renamed(tree1, tree2, 'changed/unchanging/file', 'changed/unchanging/file', True)],
7143.15.2 by Jelmer Vernooij
Run autopep8.
869
            self.do_iter_changes(tree1, tree2,
870
                                 specific_files=['changed/unchanging/file']))
4570.2.5 by Robert Collins
Review feedback, including finding a bug with changes at the root.
871
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
872
    def test_specific_with_rename_under_new_dir_reports_new_dir(self):
873
        tree1 = self.make_branch_and_tree('1')
874
        tree2 = self.make_to_branch_and_tree('2')
875
        tree1 = self.get_tree_no_parents_abc_content(tree1)
876
        tree2 = self.get_tree_no_parents_abc_content_7(tree2)
877
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
7143.15.2 by Jelmer Vernooij
Run autopep8.
878
        # d(d-id) is new, e is b-id renamed.
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
879
        root_id = tree1.path2id('')
880
        self.assertEqualIterChanges(
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
881
            [self.renamed(tree1, tree2, 'b', 'd/e', False),
882
             self.added(tree2, 'd')],
7143.15.2 by Jelmer Vernooij
Run autopep8.
883
            self.do_iter_changes(tree1, tree2, specific_files=['d/e']))
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
884
885
    def test_specific_with_rename_under_dir_under_new_dir_reports_new_dir(self):
886
        tree1 = self.make_branch_and_tree('1')
887
        tree2 = self.make_to_branch_and_tree('2')
888
        tree1 = self.get_tree_no_parents_abc_content(tree1)
889
        tree2 = self.get_tree_no_parents_abc_content_7(tree2)
890
        tree2.rename_one('a', 'd/e/a')
891
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
7143.15.2 by Jelmer Vernooij
Run autopep8.
892
        # d is new, d/e is b-id renamed, d/e/a is a-id renamed
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
893
        root_id = tree1.path2id('')
894
        self.assertEqualIterChanges(
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
895
            [self.renamed(tree1, tree2, 'b', 'd/e', False),
896
             self.added(tree2, 'd'),
897
             self.renamed(tree1, tree2, 'a', 'd/e/a', False)],
7143.15.2 by Jelmer Vernooij
Run autopep8.
898
            self.do_iter_changes(tree1, tree2, specific_files=['d/e/a']))
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
899
900
    def test_specific_old_parent_same_path_new_parent(self):
901
        # when a parent is new at its path, if the path was used in the source
902
        # it must be emitted as a change.
903
        tree1 = self.make_branch_and_tree('1')
6855.3.1 by Jelmer Vernooij
Several more fixes.
904
        tree1.add(['a'], [b'a-id'], ['file'])
6973.6.3 by Jelmer Vernooij
More fixes.
905
        tree1.put_file_bytes_non_atomic('a', b'a file')
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
906
        tree2 = self.make_to_branch_and_tree('2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
907
        tree2.set_root_id(tree1.path2id(''))
6855.3.1 by Jelmer Vernooij
Several more fixes.
908
        tree2.mkdir('a', b'b-id')
909
        tree2.add(['a/c'], [b'c-id'], ['file'])
6973.6.3 by Jelmer Vernooij
More fixes.
910
        tree2.put_file_bytes_non_atomic('a/c', b'another file')
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
911
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
912
        # a-id is gone, b-id and c-id are added.
913
        self.assertEqualIterChanges(
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
914
            [self.deleted(tree1, 'a'),
915
             self.added(tree2, 'a'),
916
             self.added(tree2, 'a/c')],
7143.15.2 by Jelmer Vernooij
Run autopep8.
917
            self.do_iter_changes(tree1, tree2, specific_files=['a/c']))
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
918
919
    def test_specific_old_parent_becomes_file(self):
920
        # When an old parent included because of a path conflict becomes a
921
        # non-directory, its children have to be all included in the delta.
922
        tree1 = self.make_branch_and_tree('1')
6855.4.1 by Jelmer Vernooij
Yet more bees.
923
        tree1.mkdir('a', b'a-old-id')
924
        tree1.mkdir('a/reparented', b'reparented-id')
925
        tree1.mkdir('a/deleted', b'deleted-id')
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
926
        tree2 = self.make_to_branch_and_tree('2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
927
        tree2.set_root_id(tree1.path2id(''))
6855.4.1 by Jelmer Vernooij
Yet more bees.
928
        tree2.mkdir('a', b'a-new-id')
929
        tree2.mkdir('a/reparented', b'reparented-id')
930
        tree2.add(['b'], [b'a-old-id'], ['file'])
6973.6.3 by Jelmer Vernooij
More fixes.
931
        tree2.put_file_bytes_non_atomic('b', b'')
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
932
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
933
        # a-old-id is kind-changed, a-new-id is added, reparented-id is renamed,
934
        # deleted-id is gone
935
        self.assertEqualIterChanges(
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
936
            [self.kind_changed(tree1, tree2, 'a', 'b'),
937
             self.added(tree2, 'a'),
938
             self.renamed(tree1, tree2, 'a/reparented', 'a/reparented', False),
939
             self.deleted(tree1, 'a/deleted')],
7143.15.2 by Jelmer Vernooij
Run autopep8.
940
            self.do_iter_changes(tree1, tree2,
941
                                 specific_files=['a/reparented']))
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
942
943
    def test_specific_old_parent_is_deleted(self):
944
        # When an old parent included because of a path conflict is removed,
945
        # its children have to be all included in the delta.
946
        tree1 = self.make_branch_and_tree('1')
7045.2.9 by Jelmer Vernooij
Fix some foreign branch tests.
947
        tree1.mkdir('a', b'a-old-id')
6973.13.2 by Jelmer Vernooij
Fix some more tests.
948
        tree1.mkdir('a/reparented', b'reparented-id')
949
        tree1.mkdir('a/deleted', b'deleted-id')
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
950
        tree2 = self.make_to_branch_and_tree('2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
951
        tree2.set_root_id(tree1.path2id(''))
6973.13.2 by Jelmer Vernooij
Fix some more tests.
952
        tree2.mkdir('a', b'a-new-id')
953
        tree2.mkdir('a/reparented', b'reparented-id')
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
954
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
955
        # a-old-id is gone, a-new-id is added, reparented-id is renamed,
956
        # deleted-id is gone
957
        self.assertEqualIterChanges(
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
958
            [self.deleted(tree1, 'a'),
959
             self.added(tree2, 'a'),
960
             self.renamed(tree1, tree2, 'a/reparented', 'a/reparented', False),
961
             self.deleted(tree1, 'a/deleted')],
7143.15.2 by Jelmer Vernooij
Run autopep8.
962
            self.do_iter_changes(tree1, tree2,
963
                                 specific_files=['a/reparented']))
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
964
965
    def test_specific_old_parent_child_collides_with_unselected_new(self):
966
        # When the child of an old parent because of a path conflict becomes a
967
        # path conflict with some unselected item in the source, that item also
968
        # needs to be included (because otherwise the output of applying the
969
        # delta to the source would have two items at that path).
970
        tree1 = self.make_branch_and_tree('1')
6963.1.1 by Jelmer Vernooij
Fix a bunch of tests on python3.
971
        tree1.mkdir('a', b'a-old-id')
972
        tree1.mkdir('a/reparented', b'reparented-id')
973
        tree1.mkdir('collides', b'collides-id')
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
974
        tree2 = self.make_to_branch_and_tree('2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
975
        tree2.set_root_id(tree1.path2id(''))
6963.1.1 by Jelmer Vernooij
Fix a bunch of tests on python3.
976
        tree2.mkdir('a', b'a-new-id')
977
        tree2.mkdir('a/selected', b'selected-id')
978
        tree2.mkdir('collides', b'reparented-id')
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
979
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
980
        # a-old-id is one, a-new-id is added, reparented-id is renamed,
981
        # collides-id is gone, selected-id is new.
982
        self.assertEqualIterChanges(
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
983
            [self.deleted(tree1, 'a'),
984
             self.added(tree2, 'a'),
985
             self.renamed(tree1, tree2, 'a/reparented', 'collides', False),
986
             self.deleted(tree1, 'collides'),
987
             self.added(tree2, 'a/selected')],
7143.15.2 by Jelmer Vernooij
Run autopep8.
988
            self.do_iter_changes(tree1, tree2,
989
                                 specific_files=['a/selected']))
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
990
991
    def test_specific_old_parent_child_dir_stops_being_dir(self):
992
        # When the child of an old parent also stops being a directory, its
993
        # children must also be included. This test checks that downward
994
        # recursion is done appropriately by starting at a child of the root of
995
        # a deleted subtree (a/reparented), and checking that a sibling
996
        # directory (a/deleted) has its children included in the delta.
997
        tree1 = self.make_branch_and_tree('1')
6963.1.1 by Jelmer Vernooij
Fix a bunch of tests on python3.
998
        tree1.mkdir('a', b'a-old-id')
999
        tree1.mkdir('a/reparented', b'reparented-id-1')
1000
        tree1.mkdir('a/deleted', b'deleted-id-1')
1001
        tree1.mkdir('a/deleted/reparented', b'reparented-id-2')
1002
        tree1.mkdir('a/deleted/deleted', b'deleted-id-2')
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
1003
        tree2 = self.make_to_branch_and_tree('2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
1004
        tree2.set_root_id(tree1.path2id(''))
6963.1.1 by Jelmer Vernooij
Fix a bunch of tests on python3.
1005
        tree2.mkdir('a', b'a-new-id')
1006
        tree2.mkdir('a/reparented', b'reparented-id-1')
1007
        tree2.mkdir('reparented', b'reparented-id-2')
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
1008
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1009
        # a-old-id is gone, a-new-id is added, reparented-id-1, -2 are renamed,
1010
        # deleted-id-1 and -2 are gone.
1011
        self.assertEqualIterChanges(
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1012
            [self.deleted(tree1, 'a'),
1013
             self.added(tree2, 'a'),
1014
             self.renamed(tree1, tree2, 'a/reparented', 'a/reparented', False),
1015
             self.renamed(tree1, tree2, 'a/deleted/reparented', 'reparented', False),
1016
             self.deleted(tree1, 'a/deleted'),
1017
             self.deleted(tree1, 'a/deleted/deleted')],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1018
            self.do_iter_changes(tree1, tree2,
1019
                                 specific_files=['a/reparented']))
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
1020
2012.1.1 by Aaron Bentley
Implement change iterator
1021
    def test_file_rename_and_meta_modification(self):
1022
        tree1 = self.make_branch_and_tree('1')
1023
        tree2 = self.make_to_branch_and_tree('2')
1024
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
1025
        tree2 = self.get_tree_no_parents_abc_content_6(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
1026
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
1027
        root_id = tree1.path2id('')
6855.3.1 by Jelmer Vernooij
Several more fixes.
1028
        self.assertEqual([(b'c-id', ('b/c', 'e'), False, (True, True),
1029
                           (b'b-id', root_id), ('c', 'e'), ('file', 'file'),
7391.3.3 by Jelmer Vernooij
Fix tests.
1030
                           (False, True), False)],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
1031
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
1032
4634.58.1 by Robert Collins
Show a sensible error when a previously versionable path becomes a FIFO or other unversionable file.
1033
    def test_file_becomes_unversionable_bug_438569(self):
1034
        # This isn't strictly a intertree problem, but its the intertree code
1035
        # path that triggers all stat cache updates on both xml and dirstate
1036
        # trees.
1037
        # In bug 438569, a file becoming a fifo causes an assert. Fifo's are
1038
        # not versionable or diffable. For now, we simply stop cold when they
7143.15.2 by Jelmer Vernooij
Run autopep8.
1039
        # are detected (because we don't know how far through the code the
1040
        # assumption 'fifo's do not exist' goes). In future we could report
4634.58.1 by Robert Collins
Show a sensible error when a previously versionable path becomes a FIFO or other unversionable file.
1041
        # the kind change and have commit refuse to go futher, or something
1042
        # similar. One particular reason for choosing this approach is that
7143.15.2 by Jelmer Vernooij
Run autopep8.
1043
        # there is no minikind for 'fifo' in dirstate today, so we can't
4634.58.1 by Robert Collins
Show a sensible error when a previously versionable path becomes a FIFO or other unversionable file.
1044
        # actually update records that way.
1045
        # To add confusion, the totally generic code path works - but it
1046
        # doesn't update persistent metadata. So this test permits InterTrees
1047
        # to either work, or fail with BadFileKindError.
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
1048
        self.requireFeature(features.OsFifoFeature)
4634.58.1 by Robert Collins
Show a sensible error when a previously versionable path becomes a FIFO or other unversionable file.
1049
        tree1 = self.make_branch_and_tree('1')
1050
        self.build_tree(['1/a'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
1051
        tree1.set_root_id(b'root-id')
6855.3.1 by Jelmer Vernooij
Several more fixes.
1052
        tree1.add(['a'], [b'a-id'])
4634.58.1 by Robert Collins
Show a sensible error when a previously versionable path becomes a FIFO or other unversionable file.
1053
        tree2 = self.make_branch_and_tree('2')
1054
        os.mkfifo('2/a')
6855.3.1 by Jelmer Vernooij
Several more fixes.
1055
        tree2.add(['a'], [b'a-id'], ['file'])
4634.58.1 by Robert Collins
Show a sensible error when a previously versionable path becomes a FIFO or other unversionable file.
1056
        try:
1057
            tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1058
        except (KeyError,):
1059
            raise tests.TestNotApplicable(
1060
                "Cannot represent a FIFO in this case %s" % self.id())
1061
        try:
1062
            self.do_iter_changes(tree1, tree2)
4634.58.2 by Robert Collins
Review feedback.
1063
        except errors.BadFileKindError:
1064
            pass
4634.58.1 by Robert Collins
Show a sensible error when a previously versionable path becomes a FIFO or other unversionable file.
1065
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
1066
    def test_missing_in_target(self):
1067
        """Test with the target files versioned but absent from disk."""
1068
        tree1 = self.make_branch_and_tree('1')
1069
        tree2 = self.make_to_branch_and_tree('2')
1070
        tree1 = self.get_tree_no_parents_abc_content(tree1)
1071
        tree2 = self.get_tree_no_parents_abc_content(tree2)
1072
        os.unlink('2/a')
1073
        shutil.rmtree('2/b')
1074
        # TODO ? have a symlink here?
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
1075
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1076
        self.not_applicable_if_missing_in('a', tree2)
1077
        self.not_applicable_if_missing_in('b', tree2)
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
1078
        expected = self.sorted([
6855.3.1 by Jelmer Vernooij
Several more fixes.
1079
            self.missing(b'a-id', 'a', 'a', b'root-id', 'file'),
1080
            self.missing(b'b-id', 'b', 'b', b'root-id', 'directory'),
1081
            self.missing(b'c-id', 'b/c', 'b/c', b'b-id', 'file'),
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
1082
            ])
1083
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
1084
1085
    def test_missing_and_renamed(self):
1086
        tree1 = self.make_branch_and_tree('tree1')
1087
        tree2 = self.make_to_branch_and_tree('tree2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
1088
        tree2.set_root_id(tree1.path2id(''))
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
1089
        self.build_tree(['tree1/file'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
1090
        tree1.add(['file'], [b'file-id'])
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
1091
        self.build_tree(['tree2/directory/'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
1092
        tree2.add(['directory'], [b'file-id'])
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
1093
        os.rmdir('tree2/directory')
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1094
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1095
        self.not_applicable_if_missing_in('directory', tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1096
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
1097
        root_id = tree1.path2id('')
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
1098
        expected = self.sorted([
6973.13.2 by Jelmer Vernooij
Fix some more tests.
1099
            self.missing(b'file-id', 'file', 'directory', root_id, 'file'),
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
1100
            ])
1101
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
1102
3619.4.1 by Robert Collins
Improve tests for the behaviour of Tree.iter_changes for missing paths that are only present in one tree, and fix found bugs. (Robert Collins)
1103
    def test_only_in_source_and_missing(self):
1104
        tree1 = self.make_branch_and_tree('tree1')
1105
        tree2 = self.make_to_branch_and_tree('tree2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
1106
        tree2.set_root_id(tree1.path2id(''))
3619.4.1 by Robert Collins
Improve tests for the behaviour of Tree.iter_changes for missing paths that are only present in one tree, and fix found bugs. (Robert Collins)
1107
        self.build_tree(['tree1/file'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
1108
        tree1.add(['file'], [b'file-id'])
3619.4.1 by Robert Collins
Improve tests for the behaviour of Tree.iter_changes for missing paths that are only present in one tree, and fix found bugs. (Robert Collins)
1109
        os.unlink('tree1/file')
1110
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1111
        self.not_applicable_if_missing_in('file', tree1)
3619.4.1 by Robert Collins
Improve tests for the behaviour of Tree.iter_changes for missing paths that are only present in one tree, and fix found bugs. (Robert Collins)
1112
        root_id = tree1.path2id('')
7322.1.7 by Jelmer Vernooij
Fix remaining tests.
1113
        expected = [
7490.120.3 by Jelmer Vernooij
Split out InventoryTreeChange from TreeChange.
1114
            InventoryTreeChange(
1115
                b'file-id', ('file', None), False, (True, False),
1116
                (root_id, None), ('file', None), (None, None), (False, None))]
3619.4.1 by Robert Collins
Improve tests for the behaviour of Tree.iter_changes for missing paths that are only present in one tree, and fix found bugs. (Robert Collins)
1117
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
1118
1119
    def test_only_in_target_and_missing(self):
1120
        tree1 = self.make_branch_and_tree('tree1')
1121
        tree2 = self.make_to_branch_and_tree('tree2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
1122
        tree2.set_root_id(tree1.path2id(''))
3619.4.1 by Robert Collins
Improve tests for the behaviour of Tree.iter_changes for missing paths that are only present in one tree, and fix found bugs. (Robert Collins)
1123
        self.build_tree(['tree2/file'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
1124
        tree2.add(['file'], [b'file-id'])
3619.4.1 by Robert Collins
Improve tests for the behaviour of Tree.iter_changes for missing paths that are only present in one tree, and fix found bugs. (Robert Collins)
1125
        os.unlink('tree2/file')
1126
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1127
        self.not_applicable_if_missing_in('file', tree2)
3619.4.1 by Robert Collins
Improve tests for the behaviour of Tree.iter_changes for missing paths that are only present in one tree, and fix found bugs. (Robert Collins)
1128
        root_id = tree1.path2id('')
7322.1.7 by Jelmer Vernooij
Fix remaining tests.
1129
        expected = [
7490.120.3 by Jelmer Vernooij
Split out InventoryTreeChange from TreeChange.
1130
            InventoryTreeChange(
1131
                b'file-id', (None, 'file'), False, (False, True),
1132
                (None, root_id), (None, 'file'), (None, None), (None, False))]
3619.4.1 by Robert Collins
Improve tests for the behaviour of Tree.iter_changes for missing paths that are only present in one tree, and fix found bugs. (Robert Collins)
1133
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
1134
4544.2.1 by Robert Collins
Add interface enforcement for the behaviour of iter_changes with missing subtrees with explicit paths - the whole subtree is returned.
1135
    def test_only_in_target_missing_subtree_specific_bug_367632(self):
1136
        tree1 = self.make_branch_and_tree('tree1')
1137
        tree2 = self.make_to_branch_and_tree('tree2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
1138
        tree2.set_root_id(tree1.path2id(''))
4544.2.1 by Robert Collins
Add interface enforcement for the behaviour of iter_changes with missing subtrees with explicit paths - the whole subtree is returned.
1139
        self.build_tree(['tree2/a-dir/', 'tree2/a-dir/a-file'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
1140
        tree2.add(['a-dir', 'a-dir/a-file'], [b'dir-id', b'file-id'])
4544.2.1 by Robert Collins
Add interface enforcement for the behaviour of iter_changes with missing subtrees with explicit paths - the whole subtree is returned.
1141
        os.unlink('tree2/a-dir/a-file')
1142
        os.rmdir('tree2/a-dir')
1143
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1144
        self.not_applicable_if_missing_in('a-dir', tree2)
1145
        root_id = tree1.path2id('')
1146
        expected = [
7490.120.3 by Jelmer Vernooij
Split out InventoryTreeChange from TreeChange.
1147
            InventoryTreeChange(
7322.1.7 by Jelmer Vernooij
Fix remaining tests.
1148
                b'dir-id', (None, 'a-dir'), False, (False, True),
1149
                (None, root_id), (None, 'a-dir'), (None, None), (None, False)),
7490.120.3 by Jelmer Vernooij
Split out InventoryTreeChange from TreeChange.
1150
            InventoryTreeChange(
7322.1.7 by Jelmer Vernooij
Fix remaining tests.
1151
                b'file-id', (None, 'a-dir/a-file'), False, (False, True),
1152
                (None, b'dir-id'), (None, 'a-file'), (None, None), (None, False))
4544.2.1 by Robert Collins
Add interface enforcement for the behaviour of iter_changes with missing subtrees with explicit paths - the whole subtree is returned.
1153
            ]
1154
        # bug 367632 showed that specifying the root broke some code paths,
1155
        # so we check this contract with and without it.
1156
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
1157
        self.assertEqual(expected,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1158
                         self.do_iter_changes(tree1, tree2, specific_files=['']))
4544.2.1 by Robert Collins
Add interface enforcement for the behaviour of iter_changes with missing subtrees with explicit paths - the whole subtree is returned.
1159
2012.1.1 by Aaron Bentley
Implement change iterator
1160
    def test_unchanged_with_renames_and_modifications(self):
1161
        """want_unchanged should generate a list of unchanged entries."""
1162
        tree1 = self.make_branch_and_tree('1')
1163
        tree2 = self.make_to_branch_and_tree('2')
1164
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
1165
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1166
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1167
        self.assertEqual(sorted([self.unchanged(tree1, ''),
1168
                                 self.unchanged(tree1, 'b'),
7490.120.3 by Jelmer Vernooij
Split out InventoryTreeChange from TreeChange.
1169
                                 InventoryTreeChange(
7322.1.7 by Jelmer Vernooij
Fix remaining tests.
1170
                                     b'a-id', ('a', 'd'), True, (True, True),
1171
                                     (b'root-id', b'root-id'), ('a', 'd'),
1172
                                     ('file', 'file'),
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1173
                                     (False, False)), self.unchanged(tree1, 'b/c')]),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1174
                         self.do_iter_changes(tree1, tree2, include_unchanged=True))
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
1175
1176
    def test_compare_subtrees(self):
1177
        tree1 = self.make_branch_and_tree('1')
2255.9.2 by Martin Pool
test_compare_subtrees runs against all trees that claim to support
1178
        if not tree1.supports_tree_reference():
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
1179
            return
6855.3.1 by Jelmer Vernooij
Several more fixes.
1180
        tree1.set_root_id(b'root-id')
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
1181
        subtree1 = self.make_branch_and_tree('1/sub')
6855.3.1 by Jelmer Vernooij
Several more fixes.
1182
        subtree1.set_root_id(b'subtree-id')
2255.9.2 by Martin Pool
test_compare_subtrees runs against all trees that claim to support
1183
        tree1.add_reference(subtree1)
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
1184
1185
        tree2 = self.make_to_branch_and_tree('2')
2255.9.2 by Martin Pool
test_compare_subtrees runs against all trees that claim to support
1186
        if not tree2.supports_tree_reference():
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
1187
            return
6855.3.1 by Jelmer Vernooij
Several more fixes.
1188
        tree2.set_root_id(b'root-id')
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
1189
        subtree2 = self.make_to_branch_and_tree('2/sub')
6855.3.1 by Jelmer Vernooij
Several more fixes.
1190
        subtree2.set_root_id(b'subtree-id')
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
1191
        tree2.add_reference(subtree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1192
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1193
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
1194
        self.assertEqual([], list(tree2.iter_changes(tree1)))
6855.3.1 by Jelmer Vernooij
Several more fixes.
1195
        subtree1.commit('commit', rev_id=b'commit-a')
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
1196
        self.assertEqual([
7490.120.3 by Jelmer Vernooij
Split out InventoryTreeChange from TreeChange.
1197
            InventoryTreeChange(
7322.1.7 by Jelmer Vernooij
Fix remaining tests.
1198
                b'root-id',
1199
                (u'', u''),
1200
                False,
1201
                (True, True),
1202
                (None, None),
1203
                (u'', u''),
1204
                ('directory', 'directory'),
1205
                (False, False)),
7490.120.3 by Jelmer Vernooij
Split out InventoryTreeChange from TreeChange.
1206
            InventoryTreeChange(
7322.1.7 by Jelmer Vernooij
Fix remaining tests.
1207
                b'subtree-id',
1208
                ('sub', 'sub',),
1209
                False,
1210
                (True, True),
1211
                (b'root-id', b'root-id'),
1212
                ('sub', 'sub'),
1213
                ('tree-reference', 'tree-reference'),
1214
                (False, False))],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1215
            list(tree2.iter_changes(tree1,
1216
                                    include_unchanged=True)))
2255.2.160 by Martin Pool
(merge) updates from dirstate branch
1217
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
1218
    def test_disk_in_subtrees_skipped(self):
1219
        """subtrees are considered not-in-the-current-tree.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1220
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
1221
        This test tests the trivial case, where the basis has no paths in the
1222
        current trees subtree.
1223
        """
1224
        tree1 = self.make_branch_and_tree('1')
6855.4.1 by Jelmer Vernooij
Yet more bees.
1225
        tree1.set_root_id(b'root-id')
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
1226
        tree2 = self.make_to_branch_and_tree('2')
1227
        if not tree2.supports_tree_reference():
1228
            return
6855.4.1 by Jelmer Vernooij
Yet more bees.
1229
        tree2.set_root_id(b'root-id')
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
1230
        subtree2 = self.make_to_branch_and_tree('2/sub')
6855.4.1 by Jelmer Vernooij
Yet more bees.
1231
        subtree2.set_root_id(b'subtree-id')
4100.2.4 by Aaron Bentley
More support for not autodetecting tree refs
1232
        tree2.add_reference(subtree2)
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
1233
        self.build_tree(['2/sub/file'])
1234
        subtree2.add(['file'])
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1235
1236
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
1237
        # this should filter correctly from above
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1238
        self.assertEqual([self.added(tree2, 'sub')],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1239
                         self.do_iter_changes(tree1, tree2, want_unversioned=True))
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
1240
        # and when the path is named
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1241
        self.assertEqual([self.added(tree2, 'sub')],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1242
                         self.do_iter_changes(tree1, tree2, specific_files=['sub'],
1243
                                              want_unversioned=True))
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
1244
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
1245
    def test_default_ignores_unversioned_files(self):
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
1246
        tree1 = self.make_branch_and_tree('tree1')
1247
        tree2 = self.make_to_branch_and_tree('tree2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
1248
        tree2.set_root_id(tree1.path2id(''))
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
1249
        self.build_tree(['tree1/a', 'tree1/c',
1250
                         'tree2/a', 'tree2/b', 'tree2/c'])
6855.3.1 by Jelmer Vernooij
Several more fixes.
1251
        tree1.add(['a', 'c'], [b'a-id', b'c-id'])
1252
        tree2.add(['a', 'c'], [b'a-id', b'c-id'])
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
1253
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1254
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
1255
1256
        # We should ignore the fact that 'b' exists in tree-2
1257
        # because the want_unversioned parameter was not given.
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
1258
        expected = self.sorted([
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1259
            self.changed_content(tree2, 'a'),
1260
            self.changed_content(tree2, 'c'),
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
1261
            ])
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
1262
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
1263
        self.check_has_changes(True, tree1, tree2)
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
1264
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
1265
    def test_unversioned_paths_in_tree(self):
1266
        tree1 = self.make_branch_and_tree('tree1')
1267
        tree2 = self.make_to_branch_and_tree('tree2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
1268
        tree2.set_root_id(tree1.path2id(''))
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
1269
        self.build_tree(['tree2/file', 'tree2/dir/'])
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
1270
        if has_symlinks():
1271
            os.symlink('target', 'tree2/link')
1272
            links_supported = True
1273
        else:
1274
            links_supported = False
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1275
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1276
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
1277
        expected = [
1278
            self.unversioned(tree2, 'file'),
1279
            self.unversioned(tree2, 'dir'),
1280
            ]
1281
        if links_supported:
1282
            expected.append(self.unversioned(tree2, 'link'))
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
1283
        expected = self.sorted(expected)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
1284
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1285
                                                        want_unversioned=True))
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
1286
1287
    def test_unversioned_paths_in_tree_specific_files(self):
1288
        tree1 = self.make_branch_and_tree('tree1')
1289
        tree2 = self.make_to_branch_and_tree('tree2')
1290
        self.build_tree(['tree2/file', 'tree2/dir/'])
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
1291
        if has_symlinks():
1292
            os.symlink('target', 'tree2/link')
1293
            links_supported = True
1294
        else:
1295
            links_supported = False
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1296
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1297
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
1298
        expected = [
1299
            self.unversioned(tree2, 'file'),
1300
            self.unversioned(tree2, 'dir'),
1301
            ]
7143.15.2 by Jelmer Vernooij
Run autopep8.
1302
        specific_files = ['file', 'dir']
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
1303
        if links_supported:
1304
            expected.append(self.unversioned(tree2, 'link'))
1305
            specific_files.append('link')
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
1306
        expected = self.sorted(expected)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
1307
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1308
                                                        specific_files=specific_files, require_versioned=False,
1309
                                                        want_unversioned=True))
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
1310
1311
    def test_unversioned_paths_in_target_matching_source_old_names(self):
1312
        # its likely that naive implementations of unversioned file support
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1313
        # will fail if the path was versioned, but is not any more,
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
1314
        # due to a rename, not due to unversioning it.
1315
        # That is, if the old tree has a versioned file 'foo', and
1316
        # the new tree has the same file but versioned as 'bar', and also
1317
        # has an unknown file 'foo', we should get back output for
1318
        # both foo and bar.
1319
        tree1 = self.make_branch_and_tree('tree1')
1320
        tree2 = self.make_to_branch_and_tree('tree2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
1321
        tree2.set_root_id(tree1.path2id(''))
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
1322
        self.build_tree(['tree2/file', 'tree2/dir/',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1323
                         'tree1/file', 'tree2/movedfile',
1324
                         'tree1/dir/', 'tree2/moveddir/'])
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
1325
        if has_symlinks():
1326
            os.symlink('target', 'tree1/link')
1327
            os.symlink('target', 'tree2/link')
1328
            os.symlink('target', 'tree2/movedlink')
1329
            links_supported = True
1330
        else:
1331
            links_supported = False
6855.4.1 by Jelmer Vernooij
Yet more bees.
1332
        tree1.add(['file', 'dir'], [b'file-id', b'dir-id'])
1333
        tree2.add(['movedfile', 'moveddir'], [b'file-id', b'dir-id'])
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
1334
        if links_supported:
6855.4.1 by Jelmer Vernooij
Yet more bees.
1335
            tree1.add(['link'], [b'link-id'])
1336
            tree2.add(['movedlink'], [b'link-id'])
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1337
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1338
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
1339
        root_id = tree1.path2id('')
1340
        expected = [
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1341
            self.renamed(tree1, tree2, 'dir', 'moveddir', False),
1342
            self.renamed(tree1, tree2, 'file', 'movedfile', True),
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
1343
            self.unversioned(tree2, 'file'),
1344
            self.unversioned(tree2, 'dir'),
1345
            ]
7143.15.2 by Jelmer Vernooij
Run autopep8.
1346
        specific_files = ['file', 'dir']
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
1347
        if links_supported:
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1348
            expected.append(self.renamed(tree1, tree2, 'link', 'movedlink', False))
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
1349
            expected.append(self.unversioned(tree2, 'link'))
1350
            specific_files.append('link')
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
1351
        expected = self.sorted(expected)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
1352
        # run once with, and once without specific files, to catch
1353
        # potentially different code paths.
1354
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1355
                                                        require_versioned=False,
1356
                                                        want_unversioned=True))
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
1357
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1358
                                                        specific_files=specific_files, require_versioned=False,
1359
                                                        want_unversioned=True))
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
1360
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
1361
    def test_similar_filenames(self):
1362
        """Test when we have a few files with similar names."""
1363
        tree1 = self.make_branch_and_tree('tree1')
1364
        tree2 = self.make_branch_and_tree('tree2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
1365
        tree2.set_root_id(tree1.path2id(''))
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
1366
1367
        # The trees are actually identical, but they happen to contain
1368
        # similarly named files.
1369
        self.build_tree(['tree1/a/',
1370
                         'tree1/a/b/',
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
1371
                         'tree1/a/b/c/',
1372
                         'tree1/a/b/c/d/',
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
1373
                         'tree1/a-c/',
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
1374
                         'tree1/a-c/e/',
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
1375
                         'tree2/a/',
1376
                         'tree2/a/b/',
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
1377
                         'tree2/a/b/c/',
1378
                         'tree2/a/b/c/d/',
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
1379
                         'tree2/a-c/',
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
1380
                         'tree2/a-c/e/',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1381
                         ])
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
1382
        tree1.add(['a', 'a/b', 'a/b/c', 'a/b/c/d', 'a-c', 'a-c/e'],
6973.13.2 by Jelmer Vernooij
Fix some more tests.
1383
                  [b'a-id', b'b-id', b'c-id', b'd-id', b'a-c-id', b'e-id'])
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
1384
        tree2.add(['a', 'a/b', 'a/b/c', 'a/b/c/d', 'a-c', 'a-c/e'],
6973.13.2 by Jelmer Vernooij
Fix some more tests.
1385
                  [b'a-id', b'b-id', b'c-id', b'd-id', b'a-c-id', b'e-id'])
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
1386
1387
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1388
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
1389
1390
        self.assertEqual([], self.do_iter_changes(tree1, tree2,
1391
                                                  want_unversioned=True))
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
1392
        expected = self.sorted([
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1393
            self.unchanged(tree2, ''),
1394
            self.unchanged(tree2, 'a'),
1395
            self.unchanged(tree2, 'a/b'),
1396
            self.unchanged(tree2, 'a/b/c'),
1397
            self.unchanged(tree2, 'a/b/c/d'),
1398
            self.unchanged(tree2, 'a-c'),
1399
            self.unchanged(tree2, 'a-c/e'),
2466.5.2 by John Arbash Meinel
Extend the test a bit to make sure the include_unchanged value is correct.
1400
            ])
1401
        self.assertEqual(expected,
1402
                         self.do_iter_changes(tree1, tree2,
1403
                                              want_unversioned=True,
1404
                                              include_unchanged=True))
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
1405
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
1406
    def test_unversioned_subtree_only_emits_root(self):
1407
        tree1 = self.make_branch_and_tree('tree1')
1408
        tree2 = self.make_to_branch_and_tree('tree2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
1409
        tree2.set_root_id(tree1.path2id(''))
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
1410
        self.build_tree(['tree2/dir/', 'tree2/dir/file'])
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
1411
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1412
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
1413
        expected = [
1414
            self.unversioned(tree2, 'dir'),
1415
            ]
1416
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1417
                                                        want_unversioned=True))
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
1418
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
1419
    def make_trees_with_symlinks(self):
1420
        tree1 = self.make_branch_and_tree('tree1')
1421
        tree2 = self.make_to_branch_and_tree('tree2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
1422
        tree2.set_root_id(tree1.path2id(''))
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
1423
        self.build_tree(['tree1/fromfile', 'tree1/fromdir/'])
1424
        self.build_tree(['tree2/tofile', 'tree2/todir/', 'tree2/unknown'])
1425
        os.symlink('original', 'tree1/changed')
1426
        os.symlink('original', 'tree1/removed')
1427
        os.symlink('original', 'tree1/tofile')
1428
        os.symlink('original', 'tree1/todir')
1429
        # we make the unchanged link point at unknown to catch incorrect
1430
        # symlink-following code in the specified_files test.
1431
        os.symlink('unknown', 'tree1/unchanged')
7143.15.2 by Jelmer Vernooij
Run autopep8.
1432
        os.symlink('new', 'tree2/added')
1433
        os.symlink('new', 'tree2/changed')
1434
        os.symlink('new', 'tree2/fromfile')
1435
        os.symlink('new', 'tree2/fromdir')
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
1436
        os.symlink('unknown', 'tree2/unchanged')
1437
        from_paths_and_ids = [
1438
            'fromdir',
1439
            'fromfile',
1440
            'changed',
1441
            'removed',
1442
            'todir',
1443
            'tofile',
1444
            'unchanged',
1445
            ]
1446
        to_paths_and_ids = [
1447
            'added',
1448
            'fromdir',
1449
            'fromfile',
1450
            'changed',
1451
            'todir',
1452
            'tofile',
1453
            'unchanged',
1454
            ]
7143.15.2 by Jelmer Vernooij
Run autopep8.
1455
        tree1.add(from_paths_and_ids, [p.encode('utf-8')
1456
                                       for p in from_paths_and_ids])
1457
        tree2.add(to_paths_and_ids, [p.encode('utf-8')
1458
                                     for p in to_paths_and_ids])
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1459
        return self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
1460
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
1461
    def test_versioned_symlinks(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
1462
        self.requireFeature(features.SymlinkFeature)
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
1463
        tree1, tree2 = self.make_trees_with_symlinks()
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1464
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
1465
        root_id = tree1.path2id('')
1466
        expected = [
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1467
            self.unchanged(tree1, ''),
1468
            self.added(tree2, 'added'),
1469
            self.changed_content(tree2, 'changed'),
1470
            self.kind_changed(tree1, tree2, 'fromdir', 'fromdir'),
1471
            self.kind_changed(tree1, tree2, 'fromfile', 'fromfile'),
1472
            self.deleted(tree1, 'removed'),
1473
            self.unchanged(tree2, 'unchanged'),
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
1474
            self.unversioned(tree2, 'unknown'),
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1475
            self.kind_changed(tree1, tree2, 'todir', 'todir'),
1476
            self.kind_changed(tree1, tree2, 'tofile', 'tofile'),
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
1477
            ]
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
1478
        expected = self.sorted(expected)
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
1479
        self.assertEqual(expected,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1480
                         self.do_iter_changes(tree1, tree2, include_unchanged=True,
1481
                                              want_unversioned=True))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
1482
        self.check_has_changes(True, tree1, tree2)
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
1483
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
1484
    def test_versioned_symlinks_specific_files(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
1485
        self.requireFeature(features.SymlinkFeature)
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
1486
        tree1, tree2 = self.make_trees_with_symlinks()
1487
        root_id = tree1.path2id('')
1488
        expected = [
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1489
            self.added(tree2, 'added'),
1490
            self.changed_content(tree2, 'changed'),
1491
            self.kind_changed(tree1, tree2, 'fromdir', 'fromdir'),
1492
            self.kind_changed(tree1, tree2, 'fromfile', 'fromfile'),
1493
            self.deleted(tree1, 'removed'),
1494
            self.kind_changed(tree1, tree2, 'todir', 'todir'),
1495
            self.kind_changed(tree1, tree2, 'tofile', 'tofile'),
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
1496
            ]
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
1497
        expected = self.sorted(expected)
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
1498
        # we should get back just the changed links. We pass in 'unchanged' to
1499
        # make sure that it is correctly not returned - and neither is the
1500
        # unknown path 'unknown' which it points at.
1501
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1502
                                                        specific_files=['added', 'changed', 'fromdir', 'fromfile',
1503
                                                                        'removed', 'unchanged', 'todir', 'tofile']))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
1504
        self.check_has_changes(True, tree1, tree2)
2255.7.15 by John Arbash Meinel
Try to create an intertree test that exposes the walkdir vs dirstate mismatch. No luck yet.
1505
2255.7.21 by John Arbash Meinel
Get iter_changes working again, by fixing set_parent_trees to
1506
    def test_tree_with_special_names(self):
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1507
        tree1, tree2, paths = self.make_tree_with_special_names()
1508
        expected = self.sorted(self.added(tree2, p) for p in paths)
2255.7.15 by John Arbash Meinel
Try to create an intertree test that exposes the walkdir vs dirstate mismatch. No luck yet.
1509
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
1510
        self.check_has_changes(True, tree1, tree2)
2255.7.22 by John Arbash Meinel
add a test that shows _iter_changes works when only contents have changed, and nothing is considered newly added.
1511
1512
    def test_trees_with_special_names(self):
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1513
        tree1, tree2, paths = self.make_trees_with_special_names()
1514
        expected = self.sorted(self.changed_content(tree2, p) for p in paths
1515
                               if p.endswith('/f'))
2255.7.22 by John Arbash Meinel
add a test that shows _iter_changes works when only contents have changed, and nothing is considered newly added.
1516
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
1517
        self.check_has_changes(True, tree1, tree2)
2255.7.34 by John Arbash Meinel
Clean up test_bad_files, and fix a bug in _iter_changes when
1518
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
1519
    def test_trees_with_deleted_dir(self):
2255.7.35 by John Arbash Meinel
Handle the case when a directory has been removed, and isn't the last entry.
1520
        tree1 = self.make_branch_and_tree('tree1')
1521
        tree2 = self.make_to_branch_and_tree('tree2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
1522
        tree2.set_root_id(tree1.path2id(''))
2255.7.35 by John Arbash Meinel
Handle the case when a directory has been removed, and isn't the last entry.
1523
        self.build_tree(['tree1/a', 'tree1/b/', 'tree1/b/c',
1524
                         'tree1/b/d/', 'tree1/b/d/e', 'tree1/f/', 'tree1/f/g',
1525
                         'tree2/a', 'tree2/f/', 'tree2/f/g'])
1526
        tree1.add(['a', 'b', 'b/c', 'b/d/', 'b/d/e', 'f', 'f/g'],
6855.4.1 by Jelmer Vernooij
Yet more bees.
1527
                  [b'a-id', b'b-id', b'c-id', b'd-id', b'e-id', b'f-id', b'g-id'])
1528
        tree2.add(['a', 'f', 'f/g'], [b'a-id', b'f-id', b'g-id'])
2255.7.35 by John Arbash Meinel
Handle the case when a directory has been removed, and isn't the last entry.
1529
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1530
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
1531
        # We should notice that 'b' and all its children are deleted
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
1532
        expected = [
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1533
            self.changed_content(tree2, 'a'),
1534
            self.changed_content(tree2, 'f/g'),
1535
            self.deleted(tree1, 'b'),
1536
            self.deleted(tree1, 'b/c'),
1537
            self.deleted(tree1, 'b/d'),
1538
            self.deleted(tree1, 'b/d/e'),
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
1539
            ]
1540
        self.assertEqualIterChanges(expected,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1541
                                    self.do_iter_changes(tree1, tree2))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
1542
        self.check_has_changes(True, tree1, tree2)
2360.1.1 by John Arbash Meinel
Basic implementation test that makes sure _iter_changes handles unknown files.
1543
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1544
    def test_added_unicode(self):
1545
        tree1 = self.make_branch_and_tree('tree1')
1546
        tree2 = self.make_to_branch_and_tree('tree2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
1547
        root_id = tree1.path2id('')
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1548
        tree2.set_root_id(root_id)
1549
1550
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1551
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1552
        a_id = u'\u03b1-id'.encode('utf8')
1553
        added_id = u'\u03c9_added_id'.encode('utf8')
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1554
        added_path = u'\u03b1/\u03c9-added'
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1555
        try:
1556
            self.build_tree([u'tree1/\u03b1/',
1557
                             u'tree2/\u03b1/',
1558
                             u'tree2/\u03b1/\u03c9-added',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1559
                             ])
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1560
        except UnicodeError:
1561
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1562
        tree1.add([u'\u03b1'], [a_id])
1563
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-added'], [a_id, added_id])
1564
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1565
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1566
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1567
        self.assertEqual([self.added(tree2, added_path)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1568
                         self.do_iter_changes(tree1, tree2))
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1569
        self.assertEqual([self.added(tree2, added_path)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1570
                         self.do_iter_changes(tree1, tree2,
1571
                                              specific_files=[u'\u03b1']))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
1572
        self.check_has_changes(True, tree1, tree2)
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1573
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1574
    def test_deleted_unicode(self):
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1575
        tree1 = self.make_branch_and_tree('tree1')
1576
        tree2 = self.make_to_branch_and_tree('tree2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
1577
        root_id = tree1.path2id('')
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1578
        tree2.set_root_id(root_id)
1579
1580
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1581
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1582
        a_id = u'\u03b1-id'.encode('utf8')
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1583
        deleted_id = u'\u03c9_deleted_id'.encode('utf8')
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1584
        deleted_path = u'\u03b1/\u03c9-deleted'
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1585
        try:
1586
            self.build_tree([u'tree1/\u03b1/',
1587
                             u'tree1/\u03b1/\u03c9-deleted',
1588
                             u'tree2/\u03b1/',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1589
                             ])
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1590
        except UnicodeError:
1591
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1592
        tree1.add([u'\u03b1', u'\u03b1/\u03c9-deleted'], [a_id, deleted_id])
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1593
        tree2.add([u'\u03b1'], [a_id])
1594
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1595
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1596
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1597
        self.assertEqual([self.deleted(tree1, deleted_path)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1598
                         self.do_iter_changes(tree1, tree2))
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1599
        self.assertEqual([self.deleted(tree1, deleted_path)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1600
                         self.do_iter_changes(tree1, tree2,
1601
                                              specific_files=[u'\u03b1']))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
1602
        self.check_has_changes(True, tree1, tree2)
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1603
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1604
    def test_modified_unicode(self):
2360.1.1 by John Arbash Meinel
Basic implementation test that makes sure _iter_changes handles unknown files.
1605
        tree1 = self.make_branch_and_tree('tree1')
1606
        tree2 = self.make_to_branch_and_tree('tree2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
1607
        root_id = tree1.path2id('')
2360.1.1 by John Arbash Meinel
Basic implementation test that makes sure _iter_changes handles unknown files.
1608
        tree2.set_root_id(root_id)
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1609
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1610
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1611
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1612
        a_id = u'\u03b1-id'.encode('utf8')
1613
        mod_id = u'\u03c9_mod_id'.encode('utf8')
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1614
        mod_path = u'\u03b1/\u03c9-modified'
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1615
        try:
1616
            self.build_tree([u'tree1/\u03b1/',
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1617
                             u'tree1/' + mod_path,
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1618
                             u'tree2/\u03b1/',
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1619
                             u'tree2/' + mod_path,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1620
                             ])
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1621
        except UnicodeError:
1622
            raise tests.TestSkipped("Could not create Unicode files.")
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1623
        tree1.add([u'\u03b1', mod_path], [a_id, mod_id])
1624
        tree2.add([u'\u03b1', mod_path], [a_id, mod_id])
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1625
1626
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1627
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1628
        self.assertEqual([self.changed_content(tree1, mod_path)],
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1629
                         self.do_iter_changes(tree1, tree2))
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1630
        self.assertEqual([self.changed_content(tree1, mod_path)],
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1631
                         self.do_iter_changes(tree1, tree2,
1632
                                              specific_files=[u'\u03b1']))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
1633
        self.check_has_changes(True, tree1, tree2)
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1634
1635
    def test_renamed_unicode(self):
1636
        tree1 = self.make_branch_and_tree('tree1')
1637
        tree2 = self.make_to_branch_and_tree('tree2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
1638
        root_id = tree1.path2id('')
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1639
        tree2.set_root_id(root_id)
1640
1641
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1642
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1643
        a_id = u'\u03b1-id'.encode('utf8')
1644
        rename_id = u'\u03c9_rename_id'.encode('utf8')
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1645
        try:
1646
            self.build_tree([u'tree1/\u03b1/',
1647
                             u'tree2/\u03b1/',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1648
                             ])
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1649
        except UnicodeError:
1650
            raise tests.TestSkipped("Could not create Unicode files.")
6855.4.1 by Jelmer Vernooij
Yet more bees.
1651
        self.build_tree_contents([(u'tree1/\u03c9-source', b'contents\n'),
1652
                                  (u'tree2/\u03b1/\u03c9-target', b'contents\n'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1653
                                  ])
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1654
        tree1.add([u'\u03b1', u'\u03c9-source'], [a_id, rename_id])
1655
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-target'], [a_id, rename_id])
1656
1657
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1658
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1659
        self.assertEqual([self.renamed(tree1, tree2, u'\u03c9-source', u'\u03b1/\u03c9-target', False)],
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1660
                         self.do_iter_changes(tree1, tree2))
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
1661
        self.assertEqualIterChanges(
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1662
            [self.renamed(tree1, tree2, u'\u03c9-source', u'\u03b1/\u03c9-target', False)],
4570.2.3 by Robert Collins
Change the way iter_changes treats specific files to prevent InconsistentDeltas.
1663
            self.do_iter_changes(tree1, tree2, specific_files=[u'\u03b1']))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
1664
        self.check_has_changes(True, tree1, tree2)
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1665
1666
    def test_unchanged_unicode(self):
1667
        tree1 = self.make_branch_and_tree('tree1')
1668
        tree2 = self.make_to_branch_and_tree('tree2')
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1669
        tree2.set_root_id(tree1.path2id(''))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1670
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1671
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1672
        a_id = u'\u03b1-id'.encode('utf8')
1673
        subfile_id = u'\u03c9-subfile-id'.encode('utf8')
1674
        rootfile_id = u'\u03c9-root-id'.encode('utf8')
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1675
        try:
1676
            self.build_tree([u'tree1/\u03b1/',
1677
                             u'tree2/\u03b1/',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1678
                             ])
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1679
        except UnicodeError:
1680
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1681
        self.build_tree_contents([
6855.4.1 by Jelmer Vernooij
Yet more bees.
1682
            (u'tree1/\u03b1/\u03c9-subfile', b'sub contents\n'),
1683
            (u'tree2/\u03b1/\u03c9-subfile', b'sub contents\n'),
1684
            (u'tree1/\u03c9-rootfile', b'root contents\n'),
1685
            (u'tree2/\u03c9-rootfile', b'root contents\n'),
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1686
            ])
1687
        tree1.add([u'\u03b1', u'\u03b1/\u03c9-subfile', u'\u03c9-rootfile'],
1688
                  [a_id, subfile_id, rootfile_id])
1689
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-subfile', u'\u03c9-rootfile'],
1690
                  [a_id, subfile_id, rootfile_id])
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1691
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1692
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1693
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
1694
        expected = self.sorted([
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1695
            self.unchanged(tree1, ''),
1696
            self.unchanged(tree1, u'\u03b1'),
1697
            self.unchanged(tree1, u'\u03b1/\u03c9-subfile'),
1698
            self.unchanged(tree1, u'\u03c9-rootfile'),
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1699
            ])
1700
        self.assertEqual(expected,
1701
                         self.do_iter_changes(tree1, tree2,
1702
                                              include_unchanged=True))
1703
1704
        # We should also be able to select just a subset
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
1705
        expected = self.sorted([
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1706
            self.unchanged(tree1, u'\u03b1'),
1707
            self.unchanged(tree1, u'\u03b1/\u03c9-subfile'),
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1708
            ])
1709
        self.assertEqual(expected,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1710
                         self.do_iter_changes(tree1, tree2, specific_files=[u'\u03b1'],
1711
                                              include_unchanged=True))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1712
1713
    def test_unknown_unicode(self):
1714
        tree1 = self.make_branch_and_tree('tree1')
1715
        tree2 = self.make_to_branch_and_tree('tree2')
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1716
        tree2.set_root_id(tree1.path2id(''))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1717
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1718
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1719
        a_id = u'\u03b1-id'.encode('utf8')
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1720
        try:
1721
            self.build_tree([u'tree1/\u03b1/',
1722
                             u'tree2/\u03b1/',
1723
                             u'tree2/\u03b1/unknown_dir/',
1724
                             u'tree2/\u03b1/unknown_file',
1725
                             u'tree2/\u03b1/unknown_dir/file',
1726
                             u'tree2/\u03c9-unknown_root_file',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1727
                             ])
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1728
        except UnicodeError:
1729
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1730
        tree1.add([u'\u03b1'], [a_id])
1731
        tree2.add([u'\u03b1'], [a_id])
1732
1733
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1734
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1735
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
1736
        expected = self.sorted([
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1737
            self.unversioned(tree2, u'\u03b1/unknown_dir'),
1738
            self.unversioned(tree2, u'\u03b1/unknown_file'),
1739
            self.unversioned(tree2, u'\u03c9-unknown_root_file'),
2360.1.1 by John Arbash Meinel
Basic implementation test that makes sure _iter_changes handles unknown files.
1740
            # a/unknown_dir/file should not be included because we should not
1741
            # recurse into unknown_dir
1742
            # self.unversioned(tree2, 'a/unknown_dir/file'),
1743
            ])
1744
        self.assertEqual(expected,
1745
                         self.do_iter_changes(tree1, tree2,
1746
                                              require_versioned=False,
1747
                                              want_unversioned=True))
7143.15.2 by Jelmer Vernooij
Run autopep8.
1748
        self.assertEqual([],  # Without want_unversioned we should get nothing
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1749
                         self.do_iter_changes(tree1, tree2))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
1750
        self.check_has_changes(False, tree1, tree2)
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1751
1752
        # We should also be able to select just a subset
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
1753
        expected = self.sorted([
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1754
            self.unversioned(tree2, u'\u03b1/unknown_dir'),
1755
            self.unversioned(tree2, u'\u03b1/unknown_file'),
1756
            ])
1757
        self.assertEqual(expected,
1758
                         self.do_iter_changes(tree1, tree2,
1759
                                              specific_files=[u'\u03b1'],
1760
                                              require_versioned=False,
1761
                                              want_unversioned=True))
7143.15.2 by Jelmer Vernooij
Run autopep8.
1762
        self.assertEqual([],  # Without want_unversioned we should get nothing
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1763
                         self.do_iter_changes(tree1, tree2,
1764
                                              specific_files=[u'\u03b1']))
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1765
1766
    def test_unknown_empty_dir(self):
1767
        tree1 = self.make_branch_and_tree('tree1')
1768
        tree2 = self.make_to_branch_and_tree('tree2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
1769
        root_id = tree1.path2id('')
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1770
        tree2.set_root_id(root_id)
1771
2402.2.4 by John Arbash Meinel
Clean up the setup for clarity (suggested by Robert)
1772
        # Start with 2 identical trees
1773
        self.build_tree(['tree1/a/', 'tree1/b/',
1774
                         'tree2/a/', 'tree2/b/'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
1775
        self.build_tree_contents([('tree1/b/file', b'contents\n'),
1776
                                  ('tree2/b/file', b'contents\n')])
1777
        tree1.add(['a', 'b', 'b/file'], [b'a-id', b'b-id', b'b-file-id'])
1778
        tree2.add(['a', 'b', 'b/file'], [b'a-id', b'b-id', b'b-file-id'])
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1779
2402.2.2 by John Arbash Meinel
Fix _iter_changes to properly handle versioned (but empty) directories
1780
        # Now create some unknowns in tree2
1781
        # We should find both a/file and a/dir as unknown, but we shouldn't
1782
        # recurse into a/dir to find that a/dir/subfile is also unknown.
7143.15.2 by Jelmer Vernooij
Run autopep8.
1783
        self.build_tree(
1784
            ['tree2/a/file', 'tree2/a/dir/', 'tree2/a/dir/subfile'])
2402.2.2 by John Arbash Meinel
Fix _iter_changes to properly handle versioned (but empty) directories
1785
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1786
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1787
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1788
7199.3.1 by Jelmer Vernooij
Don't report empty directories as changes.
1789
        if tree2.has_versioned_directories():
1790
            expected = self.sorted([
1791
                self.unversioned(tree2, u'a/file'),
1792
                self.unversioned(tree2, u'a/dir'),
1793
                ])
1794
            self.assertEqual(expected,
1795
                             self.do_iter_changes(tree1, tree2,
1796
                                                  require_versioned=False,
1797
                                                  want_unversioned=True))
1798
        else:
1799
            expected = self.sorted([
1800
                self.unversioned(tree2, u'a/file'),
1801
                self.unversioned(tree2, u'a/dir/subfile'),
1802
                ])
1803
            self.assertEqual(expected,
1804
                             self.do_iter_changes(tree1, tree2,
1805
                                                  require_versioned=False,
1806
                                                  want_unversioned=True))
2456.2.1 by John Arbash Meinel
(broken) Add a (failing) test that _iter_changes works correctly
1807
1808
    def test_rename_over_deleted(self):
1809
        tree1 = self.make_branch_and_tree('tree1')
1810
        tree2 = self.make_to_branch_and_tree('tree2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
1811
        root_id = tree1.path2id('')
2456.2.1 by John Arbash Meinel
(broken) Add a (failing) test that _iter_changes works correctly
1812
        tree2.set_root_id(root_id)
1813
1814
        # The final changes should be:
1815
        #   touch a b c d
1816
        #   add a b c d
1817
        #   commit
1818
        #   rm a d
1819
        #   mv b a
1820
        #   mv c d
1821
        self.build_tree_contents([
6855.4.1 by Jelmer Vernooij
Yet more bees.
1822
            ('tree1/a', b'a contents\n'),
1823
            ('tree1/b', b'b contents\n'),
1824
            ('tree1/c', b'c contents\n'),
1825
            ('tree1/d', b'd contents\n'),
1826
            ('tree2/a', b'b contents\n'),
1827
            ('tree2/d', b'c contents\n'),
2456.2.1 by John Arbash Meinel
(broken) Add a (failing) test that _iter_changes works correctly
1828
            ])
6855.4.1 by Jelmer Vernooij
Yet more bees.
1829
        tree1.add(['a', 'b', 'c', 'd'], [b'a-id', b'b-id', b'c-id', b'd-id'])
1830
        tree2.add(['a', 'd'], [b'b-id', b'c-id'])
2456.2.1 by John Arbash Meinel
(broken) Add a (failing) test that _iter_changes works correctly
1831
1832
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1833
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
1834
        expected = self.sorted([
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1835
            self.deleted(tree1, 'a'),
1836
            self.deleted(tree1, 'd'),
1837
            self.renamed(tree1, tree2, 'b', 'a', False),
1838
            self.renamed(tree1, tree2, 'c', 'd', False),
2456.2.1 by John Arbash Meinel
(broken) Add a (failing) test that _iter_changes works correctly
1839
            ])
1840
        self.assertEqual(expected,
1841
                         self.do_iter_changes(tree1, tree2))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
1842
        self.check_has_changes(True, tree1, tree2)
2456.2.2 by John Arbash Meinel
Add another (failing) test case.
1843
1844
    def test_deleted_and_unknown(self):
1845
        """Test a file marked removed, but still present on disk."""
1846
        tree1 = self.make_branch_and_tree('tree1')
1847
        tree2 = self.make_to_branch_and_tree('tree2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
1848
        root_id = tree1.path2id('')
2456.2.2 by John Arbash Meinel
Add another (failing) test case.
1849
        tree2.set_root_id(root_id)
1850
1851
        # The final changes should be:
1852
        # bzr add a b c
1853
        # bzr rm --keep b
1854
        self.build_tree_contents([
6855.4.1 by Jelmer Vernooij
Yet more bees.
1855
            ('tree1/a', b'a contents\n'),
1856
            ('tree1/b', b'b contents\n'),
1857
            ('tree1/c', b'c contents\n'),
1858
            ('tree2/a', b'a contents\n'),
1859
            ('tree2/b', b'b contents\n'),
1860
            ('tree2/c', b'c contents\n'),
2456.2.2 by John Arbash Meinel
Add another (failing) test case.
1861
            ])
6855.3.1 by Jelmer Vernooij
Several more fixes.
1862
        tree1.add(['a', 'b', 'c'], [b'a-id', b'b-id', b'c-id'])
1863
        tree2.add(['a', 'c'], [b'a-id', b'c-id'])
2456.2.2 by John Arbash Meinel
Add another (failing) test case.
1864
1865
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1866
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2456.2.2 by John Arbash Meinel
Add another (failing) test case.
1867
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
1868
        expected = self.sorted([
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1869
            self.deleted(tree1, 'b'),
2456.2.2 by John Arbash Meinel
Add another (failing) test case.
1870
            self.unversioned(tree2, 'b'),
1871
            ])
1872
        self.assertEqual(expected,
1873
                         self.do_iter_changes(tree1, tree2,
1874
                                              want_unversioned=True))
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
1875
        expected = self.sorted([
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1876
            self.deleted(tree1, 'b'),
2456.2.5 by John Arbash Meinel
Make sure the output with want_unversioned=False is reasonable.
1877
            ])
1878
        self.assertEqual(expected,
1879
                         self.do_iter_changes(tree1, tree2,
1880
                                              want_unversioned=False))
2465.1.1 by John Arbash Meinel
Add a (failing) test exposing the bug in _iter_changes
1881
1882
    def test_renamed_and_added(self):
1883
        """Test when we have renamed a file, and put another in its place."""
1884
        tree1 = self.make_branch_and_tree('tree1')
1885
        tree2 = self.make_to_branch_and_tree('tree2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
1886
        root_id = tree1.path2id('')
2465.1.1 by John Arbash Meinel
Add a (failing) test exposing the bug in _iter_changes
1887
        tree2.set_root_id(root_id)
1888
1889
        # The final changes are:
1890
        # bzr add b c
1891
        # bzr mv b a
1892
        # bzr mv c d
1893
        # bzr add b c
1894
1895
        self.build_tree_contents([
6855.3.1 by Jelmer Vernooij
Several more fixes.
1896
            ('tree1/b', b'b contents\n'),
1897
            ('tree1/c', b'c contents\n'),
1898
            ('tree2/a', b'b contents\n'),
1899
            ('tree2/b', b'new b contents\n'),
1900
            ('tree2/c', b'new c contents\n'),
1901
            ('tree2/d', b'c contents\n'),
2465.1.1 by John Arbash Meinel
Add a (failing) test exposing the bug in _iter_changes
1902
            ])
6855.3.1 by Jelmer Vernooij
Several more fixes.
1903
        tree1.add(['b', 'c'], [b'b1-id', b'c1-id'])
7143.15.2 by Jelmer Vernooij
Run autopep8.
1904
        tree2.add(['a', 'b', 'c', 'd'], [
1905
                  b'b1-id', b'b2-id', b'c2-id', b'c1-id'])
2465.1.1 by John Arbash Meinel
Add a (failing) test exposing the bug in _iter_changes
1906
1907
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1908
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
1909
        expected = self.sorted([
7391.3.1 by Jelmer Vernooij
Use id2path in fewer places.
1910
            self.renamed(tree1, tree2, 'b', 'a', False),
1911
            self.renamed(tree1, tree2, 'c', 'd', False),
1912
            self.added(tree2, 'b'),
1913
            self.added(tree2, 'c'),
2465.1.1 by John Arbash Meinel
Add a (failing) test exposing the bug in _iter_changes
1914
            ])
1915
        self.assertEqual(expected,
1916
                         self.do_iter_changes(tree1, tree2,
1917
                                              want_unversioned=True))
2472.3.1 by John Arbash Meinel
Fix bug #111288. When we don't have a match
1918
1919
    def test_renamed_and_unknown(self):
1920
        """A file was moved on the filesystem, but not in bzr."""
1921
        tree1 = self.make_branch_and_tree('tree1')
1922
        tree2 = self.make_to_branch_and_tree('tree2')
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
1923
        root_id = tree1.path2id('')
2472.3.1 by John Arbash Meinel
Fix bug #111288. When we don't have a match
1924
        tree2.set_root_id(root_id)
1925
1926
        # The final changes are:
1927
        # bzr add a b
1928
        # mv a a2
1929
1930
        self.build_tree_contents([
6855.3.1 by Jelmer Vernooij
Several more fixes.
1931
            ('tree1/a', b'a contents\n'),
1932
            ('tree1/b', b'b contents\n'),
1933
            ('tree2/a', b'a contents\n'),
1934
            ('tree2/b', b'b contents\n'),
2472.3.1 by John Arbash Meinel
Fix bug #111288. When we don't have a match
1935
            ])
6855.3.1 by Jelmer Vernooij
Several more fixes.
1936
        tree1.add(['a', 'b'], [b'a-id', b'b-id'])
1937
        tree2.add(['a', 'b'], [b'a-id', b'b-id'])
2472.3.1 by John Arbash Meinel
Fix bug #111288. When we don't have a match
1938
        os.rename('tree2/a', 'tree2/a2')
1939
1940
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1941
        self.not_applicable_if_missing_in('a', tree2)
2472.3.1 by John Arbash Meinel
Fix bug #111288. When we don't have a match
1942
7067.6.1 by Jelmer Vernooij
Fix sorting of iter_changes results.
1943
        expected = self.sorted([
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
1944
            self.missing(b'a-id', 'a', 'a', tree2.path2id(''), 'file'),
2472.3.1 by John Arbash Meinel
Fix bug #111288. When we don't have a match
1945
            self.unversioned(tree2, 'a2'),
1946
            ])
1947
        self.assertEqual(expected,
1948
                         self.do_iter_changes(tree1, tree2,
1949
                                              want_unversioned=True))