/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
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
22
from bzrlib import (
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
    workingtree_4,
27
    )
2321.3.4 by Alexander Belchenko
test intertree_implementations: skip tests with symlinks on platforms that don't have symlinks support
28
from bzrlib.osutils import file_kind, has_symlinks
3619.4.4 by Robert Collins
Review feedback.
29
from bzrlib.tests import TestNotApplicable
4523.1.4 by Martin Pool
Rename remaining *_implementations tests
30
from bzrlib.tests.per_intertree import TestCaseWithTwoTrees
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
31
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
32
# TODO: test the include_root option.
33
# TODO: test that renaming a directory x->y does not emit a rename for the
34
#       child x/a->y/a.
35
# TODO: test that renaming a directory x-> does not emit a rename for the child
36
#        x/a -> y/a when a supplied_files argument gives either 'x/' or 'y/a'
37
#        -> that is, when the renamed parent is not processed by the function.
38
# TODO: test items are only emitted once when a specific_files list names a dir
39
#       whose parent is now a child.
2255.2.151 by Robert Collins
Handle specific_files natively for WorkingTreeFormat4._iter_changes.
40
# TODO: test specific_files when the target tree has a file and the source a
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
41
#       dir with children, same id and same path.
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
50
class TestCompare(TestCaseWithTwoTrees):
51
52
    def test_compare_empty_trees(self):
53
        tree1 = self.make_branch_and_tree('1')
54
        tree2 = self.make_to_branch_and_tree('2')
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
55
        tree2.set_root_id(tree1.get_root_id())
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
56
        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.
57
        tree2 = self.get_tree_no_parents_no_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
58
        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.
59
        d = self.intertree_class(tree1, tree2).compare()
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
60
        self.assertEqual([], d.added)
61
        self.assertEqual([], d.modified)
62
        self.assertEqual([], d.removed)
63
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
64
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
65
66
    def test_empty_to_abc_content(self):
67
        tree1 = self.make_branch_and_tree('1')
68
        tree2 = self.make_to_branch_and_tree('2')
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
69
        tree2.set_root_id(tree1.get_root_id())
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
70
        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.
71
        tree2 = self.get_tree_no_parents_abc_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
72
        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.
73
        d = self.intertree_class(tree1, tree2).compare()
74
        self.assertEqual([('a', 'a-id', 'file'),
75
                          ('b', 'b-id', 'directory'),
76
                          ('b/c', 'c-id', 'file'),
77
                         ], d.added)
78
        self.assertEqual([], d.modified)
79
        self.assertEqual([], d.removed)
80
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
81
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
82
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
83
    def test_dangling(self):
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
84
        # This test depends on the ability for some trees to have a difference
85
        # between a 'versioned present' and 'versioned not present' (aka
86
        # dangling) file. In this test there are two trees each with a separate
87
        # dangling file, and the dangling files should be considered absent for
88
        # the test.
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
89
        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.
90
        tree2 = self.make_to_branch_and_tree('2')
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
91
        tree2.set_root_id(tree1.get_root_id())
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
92
        self.build_tree(['2/a'])
93
        tree2.add('a')
94
        os.unlink('2/a')
95
        self.build_tree(['1/b'])
96
        tree1.add('b')
97
        os.unlink('1/b')
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
98
        # the conversion to test trees here will leave the trees intact for the
99
        # default intertree, but may perform a commit for other tree types,
100
        # which may reduce the validity of the test. XXX: Think about how to
101
        # address this.
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
102
        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
103
        d = self.intertree_class(tree1, tree2).compare()
104
        self.assertEqual([], d.added)
105
        self.assertEqual([], d.modified)
106
        self.assertEqual([], d.removed)
107
        self.assertEqual([], d.renamed)
108
        self.assertEqual([], d.unchanged)
109
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
110
    def test_abc_content_to_empty(self):
111
        tree1 = self.make_branch_and_tree('1')
112
        tree2 = self.make_to_branch_and_tree('2')
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
113
        tree2.set_root_id(tree1.get_root_id())
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
114
        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.
115
        tree2 = self.get_tree_no_parents_no_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
116
        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.
117
        d = self.intertree_class(tree1, tree2).compare()
118
        self.assertEqual([], d.added)
119
        self.assertEqual([], d.modified)
120
        self.assertEqual([('a', 'a-id', 'file'),
121
                          ('b', 'b-id', 'directory'),
122
                          ('b/c', 'c-id', 'file'),
123
                         ], d.removed)
124
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
125
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
126
127
    def test_content_modification(self):
128
        tree1 = self.make_branch_and_tree('1')
129
        tree2 = self.make_to_branch_and_tree('2')
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
130
        tree2.set_root_id(tree1.get_root_id())
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
131
        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.
132
        tree2 = self.get_tree_no_parents_abc_content_2(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
133
        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.
134
        d = self.intertree_class(tree1, tree2).compare()
135
        self.assertEqual([], d.added)
136
        self.assertEqual([('a', 'a-id', 'file', True, False)], d.modified)
137
        self.assertEqual([], d.removed)
138
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
139
        self.assertEqual([], d.unchanged)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
140
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
141
    def test_meta_modification(self):
142
        tree1 = self.make_branch_and_tree('1')
143
        tree2 = self.make_to_branch_and_tree('2')
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
144
        tree2.set_root_id(tree1.get_root_id())
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
145
        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.
146
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
147
        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.
148
        d = self.intertree_class(tree1, tree2).compare()
149
        self.assertEqual([], d.added)
150
        self.assertEqual([('b/c', 'c-id', 'file', False, True)], d.modified)
151
        self.assertEqual([], d.removed)
152
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
153
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
154
155
    def test_file_rename(self):
156
        tree1 = self.make_branch_and_tree('1')
157
        tree2 = self.make_to_branch_and_tree('2')
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
158
        tree2.set_root_id(tree1.get_root_id())
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
159
        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.
160
        tree2 = self.get_tree_no_parents_abc_content_4(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
161
        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.
162
        d = self.intertree_class(tree1, tree2).compare()
163
        self.assertEqual([], d.added)
164
        self.assertEqual([], d.modified)
165
        self.assertEqual([], d.removed)
166
        self.assertEqual([('a', 'd', 'a-id', 'file', False, False)], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
167
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
168
169
    def test_file_rename_and_modification(self):
170
        tree1 = self.make_branch_and_tree('1')
171
        tree2 = self.make_to_branch_and_tree('2')
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
172
        tree2.set_root_id(tree1.get_root_id())
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
173
        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.
174
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
175
        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.
176
        d = self.intertree_class(tree1, tree2).compare()
177
        self.assertEqual([], d.added)
178
        self.assertEqual([], d.modified)
179
        self.assertEqual([], d.removed)
180
        self.assertEqual([('a', 'd', 'a-id', 'file', True, False)], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
181
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
182
183
    def test_file_rename_and_meta_modification(self):
184
        tree1 = self.make_branch_and_tree('1')
185
        tree2 = self.make_to_branch_and_tree('2')
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
186
        tree2.set_root_id(tree1.get_root_id())
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
187
        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.
188
        tree2 = self.get_tree_no_parents_abc_content_6(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
189
        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.
190
        d = self.intertree_class(tree1, tree2).compare()
191
        self.assertEqual([], d.added)
192
        self.assertEqual([], d.modified)
193
        self.assertEqual([], d.removed)
194
        self.assertEqual([('b/c', 'e', 'c-id', 'file', False, True)], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
195
        self.assertEqual([], d.unchanged)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
196
197
    def test_empty_to_abc_content_a_only(self):
198
        tree1 = self.make_branch_and_tree('1')
199
        tree2 = self.make_to_branch_and_tree('2')
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
200
        tree2.set_root_id(tree1.get_root_id())
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
201
        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.
202
        tree2 = self.get_tree_no_parents_abc_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
203
        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.
204
        d = self.intertree_class(tree1, tree2).compare(specific_files=['a'])
205
        self.assertEqual([('a', 'a-id', 'file')], d.added)
206
        self.assertEqual([], d.modified)
207
        self.assertEqual([], d.removed)
208
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
209
        self.assertEqual([], d.unchanged)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
210
211
    def test_empty_to_abc_content_a_and_c_only(self):
212
        tree1 = self.make_branch_and_tree('1')
213
        tree2 = self.make_to_branch_and_tree('2')
214
        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.
215
        tree2 = self.get_tree_no_parents_abc_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
216
        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.
217
        d = self.intertree_class(tree1, tree2).compare(
218
            specific_files=['a', 'b/c'])
219
        self.assertEqual(
220
            [('a', 'a-id', 'file'), ('b/c', 'c-id', 'file')],
221
            d.added)
222
        self.assertEqual([], d.modified)
223
        self.assertEqual([], d.removed)
224
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
225
        self.assertEqual([], d.unchanged)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
226
227
    def test_empty_to_abc_content_b_only(self):
228
        """Restricting to a dir matches the children of the dir."""
229
        tree1 = self.make_branch_and_tree('1')
230
        tree2 = self.make_to_branch_and_tree('2')
231
        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.
232
        tree2 = self.get_tree_no_parents_abc_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
233
        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.
234
        d = self.intertree_class(tree1, tree2).compare(specific_files=['b'])
235
        self.assertEqual(
236
            [('b', 'b-id', 'directory'),('b/c', 'c-id', 'file')],
237
            d.added)
238
        self.assertEqual([], d.modified)
239
        self.assertEqual([], d.removed)
240
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
241
        self.assertEqual([], d.unchanged)
242
243
    def test_unchanged_with_renames_and_modifications(self):
244
        """want_unchanged should generate a list of unchanged entries."""
245
        tree1 = self.make_branch_and_tree('1')
246
        tree2 = self.make_to_branch_and_tree('2')
247
        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.
248
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
249
        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=...).
250
        d = self.intertree_class(tree1, tree2).compare(want_unchanged=True)
251
        self.assertEqual([], d.added)
252
        self.assertEqual([], d.modified)
253
        self.assertEqual([], d.removed)
254
        self.assertEqual([('a', 'd', 'a-id', 'file', True, False)], d.renamed)
255
        self.assertEqual(
256
            [(u'b', 'b-id', 'directory'), (u'b/c', 'c-id', 'file')],
257
            d.unchanged)
258
259
    def test_extra_trees_finds_ids(self):
260
        """Ask for a delta between two trees with a path present in a third."""
261
        tree1 = self.make_branch_and_tree('1')
262
        tree2 = self.make_to_branch_and_tree('2')
263
        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.
264
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
265
        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.
266
        d = self.intertree_class(tree1, tree2).compare(specific_files=['b'])
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
267
        # 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.
268
        # a dispatch. XXX: For dirstate it does speak to the optimisability of
269
        # the lookup, in merged trees it can be fast-pathed. We probably want
270
        # 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=...).
271
        tree3 = self.make_branch_and_tree('3')
272
        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.
273
        tree3.lock_read()
274
        self.addCleanup(tree3.unlock)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
275
        # tree 3 has 'e' which is 'c-id'. Tree 1 has c-id at b/c, and Tree 2
276
        # has c-id at b/c with its exec flag toggled.
277
        # without extra_trees, we should get no modifications from this
278
        # so do one, to be sure the test is valid.
279
        d = self.intertree_class(tree1, tree2).compare(
280
            specific_files=['e'])
281
        self.assertEqual([], d.modified)
282
        # now give it an additional lookup:
283
        d = self.intertree_class(tree1, tree2).compare(
284
            specific_files=['e'], extra_trees=[tree3])
285
        self.assertEqual([], d.added)
286
        self.assertEqual([('b/c', 'c-id', 'file', False, True)], d.modified)
287
        self.assertEqual([], d.removed)
288
        self.assertEqual([], d.renamed)
289
        self.assertEqual([], d.unchanged)
1852.9.5 by Robert Collins
Add tests for require_versioned to the InterTree.compare() test suite.
290
291
    def test_require_versioned(self):
292
        # this does not quite robustly test, as it is passing in missing paths
293
        # 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
294
        # 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.
295
        # get present-but-not-versioned files for trees that can do that.
296
        tree1 = self.make_branch_and_tree('1')
297
        tree2 = self.make_to_branch_and_tree('2')
298
        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.
299
        tree2 = self.get_tree_no_parents_abc_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
300
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
301
        self.assertRaises(errors.PathsNotVersionedError,
1852.9.5 by Robert Collins
Add tests for require_versioned to the InterTree.compare() test suite.
302
            self.intertree_class(tree1, tree2).compare,
303
            specific_files=['d'],
304
            require_versioned=True)
2012.1.1 by Aaron Bentley
Implement change iterator
305
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
306
    def test_default_ignores_unversioned_files(self):
307
        tree1 = self.make_branch_and_tree('tree1')
308
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.184 by Martin Pool
Fixes for some comparison tests; repr of DirStateRevisionTree
309
        tree2.set_root_id(tree1.get_root_id())
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
310
        self.build_tree(['tree1/a', 'tree1/c',
311
                         'tree2/a', 'tree2/b', 'tree2/c'])
312
        tree1.add(['a', 'c'], ['a-id', 'c-id'])
313
        tree2.add(['a', 'c'], ['a-id', 'c-id'])
314
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
315
        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.
316
        d = self.intertree_class(tree1, tree2).compare()
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
317
        self.assertEqual([], d.added)
318
        self.assertEqual([(u'a', 'a-id', 'file', True, False),
319
            (u'c', 'c-id', 'file', True, False)], d.modified)
320
        self.assertEqual([], d.removed)
321
        self.assertEqual([], d.renamed)
322
        self.assertEqual([], d.unchanged)
323
        self.assertEqual([], d.unversioned)
324
325
    def test_unversioned_paths_in_tree(self):
326
        tree1 = self.make_branch_and_tree('tree1')
327
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.184 by Martin Pool
Fixes for some comparison tests; repr of DirStateRevisionTree
328
        tree2.set_root_id(tree1.get_root_id())
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
329
        self.build_tree(['tree2/file', 'tree2/dir/'])
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
330
        if has_symlinks():
331
            os.symlink('target', 'tree2/link')
332
            links_supported = True
333
        else:
334
            links_supported = False
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
335
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
336
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
337
        d = self.intertree_class(tree1, tree2).compare(want_unversioned=True)
338
        self.assertEqual([], d.added)
339
        self.assertEqual([], d.modified)
340
        self.assertEqual([], d.removed)
341
        self.assertEqual([], d.renamed)
342
        self.assertEqual([], d.unchanged)
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
343
        expected_unversioned = [(u'dir', None, 'directory'),
344
                                (u'file', None, 'file')]
345
        if links_supported:
346
            expected_unversioned.append((u'link', None, 'symlink'))
347
        self.assertEqual(expected_unversioned, d.unversioned)
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
348
2012.1.1 by Aaron Bentley
Implement change iterator
349
2012.1.3 by Aaron Bentley
Always generate tuples (because kind is always used, even when not different)
350
class TestIterChanges(TestCaseWithTwoTrees):
2012.1.1 by Aaron Bentley
Implement change iterator
351
    """Test the comparison iterator"""
352
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
353
    def do_iter_changes(self, tree1, tree2, **extra_args):
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
354
        """Helper to run iter_changes from tree1 to tree2.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
355
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
356
        :param tree1, tree2:  The source and target trees. These will be locked
357
            automatically.
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
358
        :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.
359
            inspected by this test helper.
360
        """
361
        tree1.lock_read()
362
        tree2.lock_read()
363
        try:
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
364
            # sort order of output is not strictly defined
365
            return sorted(self.intertree_class(tree1, tree2)
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
366
                .iter_changes(**extra_args))
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
367
        finally:
368
            tree1.unlock()
369
            tree2.unlock()
370
4503.1.3 by Vincent Ladeuil
Take review comments into account.
371
    def check_has_changes(self, expected, tree1, tree2):
372
        # has_changes is defined for mutable trees only
373
        if not isinstance(tree2, mutabletree.MutableTree):
374
            if isinstance(tree1, mutabletree.MutableTree):
375
                # Let's switch the trees since has_changes() is commutative
376
                # (where we can apply it)
377
                tree2, tree1 = tree1, tree2
378
            else:
379
                # Neither tree can be used
380
                return
4503.1.1 by Vincent Ladeuil
Add tree.has_changes() to quickly check iter_changes().
381
        tree1.lock_read()
382
        tree2.lock_read()
383
        try:
4503.1.3 by Vincent Ladeuil
Take review comments into account.
384
            return tree2.has_changes(tree1)
4503.1.1 by Vincent Ladeuil
Add tree.has_changes() to quickly check iter_changes().
385
        finally:
386
            tree1.unlock()
387
            tree2.unlock()
388
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
389
    def mutable_trees_to_locked_test_trees(self, tree1, tree2):
390
        """Convert the working trees into test trees.
391
392
        Read lock them, and add the unlock to the cleanup.
393
        """
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
394
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
395
        tree1.lock_read()
396
        self.addCleanup(tree1.unlock)
397
        tree2.lock_read()
398
        self.addCleanup(tree2.unlock)
399
        return tree1, tree2
400
2255.7.15 by John Arbash Meinel
Try to create an intertree test that exposes the walkdir vs dirstate mismatch. No luck yet.
401
    def make_tree_with_special_names(self):
402
        """Create a tree with filenames chosen to exercise the walk order."""
403
        tree1 = self.make_branch_and_tree('tree1')
404
        tree2 = self.make_to_branch_and_tree('tree2')
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
405
        tree2.set_root_id(tree1.get_root_id())
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.
406
        paths, path_ids = self._create_special_names(tree2, 'tree2')
2255.7.15 by John Arbash Meinel
Try to create an intertree test that exposes the walkdir vs dirstate mismatch. No luck yet.
407
        tree2.commit('initial', rev_id='rev-1')
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
408
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(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.
409
        return (tree1, tree2, paths, path_ids)
410
411
    def make_trees_with_special_names(self):
412
        """Both trees will use the special names.
413
414
        But the contents will differ for each file.
415
        """
416
        tree1 = self.make_branch_and_tree('tree1')
417
        tree2 = self.make_to_branch_and_tree('tree2')
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
418
        tree2.set_root_id(tree1.get_root_id())
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.
419
        paths, path_ids = self._create_special_names(tree1, 'tree1')
420
        paths, path_ids = self._create_special_names(tree2, 'tree2')
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
421
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(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.
422
        return (tree1, tree2, paths, path_ids)
423
424
    def _create_special_names(self, tree, base_path):
425
        """Create a tree with paths that expose differences in sort orders."""
426
        # Each directory will have a single file named 'f' inside
427
        dirs = ['a',
428
                'a-a',
429
                'a/a',
430
                'a/a-a',
431
                'a/a/a',
432
                'a/a/a-a',
433
                'a/a/a/a',
434
                'a/a/a/a-a',
435
                'a/a/a/a/a',
436
               ]
437
        with_slashes = []
438
        paths = []
439
        path_ids = []
440
        for d in dirs:
441
            with_slashes.append(base_path + '/' + d + '/')
442
            with_slashes.append(base_path + '/' + d + '/f')
443
            paths.append(d)
444
            paths.append(d+'/f')
445
            path_ids.append(d.replace('/', '_') + '-id')
446
            path_ids.append(d.replace('/', '_') + '_f-id')
447
        self.build_tree(with_slashes)
448
        tree.add(paths, path_ids)
449
        return paths, path_ids
2255.7.15 by John Arbash Meinel
Try to create an intertree test that exposes the walkdir vs dirstate mismatch. No luck yet.
450
2012.1.1 by Aaron Bentley
Implement change iterator
451
    def test_compare_empty_trees(self):
452
        tree1 = self.make_branch_and_tree('1')
453
        tree2 = self.make_to_branch_and_tree('2')
454
        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.
455
        tree2 = self.get_tree_no_parents_no_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
456
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
3254.1.2 by Aaron Bentley
Fix doiter_changes
457
        self.assertEqual([], self.do_iter_changes(tree1, tree2))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
458
        self.check_has_changes(False, tree1, tree2)
2012.1.1 by Aaron Bentley
Implement change iterator
459
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
460
    def added(self, tree, file_id):
3363.14.7 by Aaron Bentley
Get more tests passing
461
        path, entry = self.get_path_entry(tree, file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
462
        return (file_id, (None, path), True, (False, True), (None, entry.parent_id),
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
463
                (None, entry.name), (None, entry.kind),
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
464
                (None, entry.executable))
465
3363.14.7 by Aaron Bentley
Get more tests passing
466
    @staticmethod
467
    def get_path_entry(tree, file_id):
468
        iterator = tree.iter_entries_by_dir(specific_file_ids=[file_id])
469
        return iterator.next()
470
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.
471
    def content_changed(self, tree, file_id):
3363.14.7 by Aaron Bentley
Get more tests passing
472
        path, entry = self.get_path_entry(tree, file_id)
473
        return (file_id, (path, path), True, (True, True),
474
                (entry.parent_id, entry.parent_id),
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.
475
                (entry.name, entry.name), (entry.kind, entry.kind),
476
                (entry.executable, entry.executable))
477
478
    def kind_changed(self, from_tree, to_tree, file_id):
3363.14.7 by Aaron Bentley
Get more tests passing
479
        from_path, old_entry = self.get_path_entry(from_tree, file_id)
480
        path, new_entry = self.get_path_entry(to_tree, file_id)
481
        return (file_id, (from_path, path), True, (True, True),
482
                (old_entry.parent_id, new_entry.parent_id),
483
                (old_entry.name, new_entry.name),
484
                (old_entry.kind, new_entry.kind),
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.
485
                (old_entry.executable, new_entry.executable))
486
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
487
    def missing(self, file_id, from_path, to_path, parent_id, kind):
488
        _, from_basename = os.path.split(from_path)
489
        _, to_basename = os.path.split(to_path)
490
        # missing files have both paths, but no kind.
491
        return (file_id, (from_path, to_path), True, (True, True),
492
            (parent_id, parent_id),
493
            (from_basename, to_basename), (kind, None), (False, False))
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
494
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
495
    def deleted(self, tree, file_id):
496
        entry = tree.inventory[file_id]
497
        path = tree.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
498
        return (file_id, (path, None), True, (True, False), (entry.parent_id, None),
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
499
                (entry.name, None), (entry.kind, None),
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
500
                (entry.executable, None))
501
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
502
    def renamed(self, from_tree, to_tree, file_id, content_changed):
3363.14.8 by Aaron Bentley
Fix more tests
503
        from_path, from_entry = self.get_path_entry(from_tree, file_id)
504
        to_path, to_entry = self.get_path_entry(to_tree, file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
505
        return (file_id, (from_path, to_path), content_changed, (True, True),
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
506
            (from_entry.parent_id, to_entry.parent_id),
507
            (from_entry.name, to_entry.name),
508
            (from_entry.kind, to_entry.kind),
509
            (from_entry.executable, to_entry.executable))
510
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.
511
    def unchanged(self, tree, file_id):
3363.14.8 by Aaron Bentley
Fix more tests
512
        path, entry = self.get_path_entry(tree, file_id)
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.
513
        parent = entry.parent_id
514
        name = entry.name
515
        kind = entry.kind
516
        executable = entry.executable
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
517
        return (file_id, (path, path), False, (True, 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.
518
               (parent, parent), (name, name), (kind, kind),
519
               (executable, executable))
520
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
521
    def unversioned(self, tree, path):
522
        """Create an unversioned result."""
523
        _, basename = os.path.split(path)
3363.14.7 by Aaron Bentley
Get more tests passing
524
        kind = tree._comparison_data(None, path)[0]
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
525
        return (None, (None, path), True, (False, False), (None, None),
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
526
                (None, basename), (None, kind),
527
                (None, False))
528
2012.1.1 by Aaron Bentley
Implement change iterator
529
    def test_empty_to_abc_content(self):
530
        tree1 = self.make_branch_and_tree('1')
531
        tree2 = self.make_to_branch_and_tree('2')
532
        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.
533
        tree2 = self.get_tree_no_parents_abc_content(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)
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
535
        expected_results = sorted([
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
536
            self.added(tree2, 'root-id'),
537
            self.added(tree2, 'a-id'),
538
            self.added(tree2, 'b-id'),
539
            self.added(tree2, 'c-id'),
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
540
            self.deleted(tree1, 'empty-root-id')])
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
541
        self.assertEqual(expected_results, self.do_iter_changes(tree1, tree2))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
542
        self.check_has_changes(True, tree1, tree2)
2012.1.1 by Aaron Bentley
Implement change iterator
543
2748.3.1 by Aaron Bentley
Start supporting [] for empty list
544
    def test_empty_specific_files(self):
545
        tree1 = self.make_branch_and_tree('1')
546
        tree2 = self.make_to_branch_and_tree('2')
547
        tree1 = self.get_tree_no_parents_no_content(tree1)
548
        tree2 = self.get_tree_no_parents_abc_content(tree2)
549
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
550
        self.assertEqual([],
551
            self.do_iter_changes(tree1, tree2, specific_files=[]))
552
553
    def test_no_specific_files(self):
554
        tree1 = self.make_branch_and_tree('1')
555
        tree2 = self.make_to_branch_and_tree('2')
556
        tree1 = self.get_tree_no_parents_no_content(tree1)
557
        tree2 = self.get_tree_no_parents_abc_content(tree2)
558
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2796.1.2 by Aaron Bentley
Harmonize test_no_specific_files with test_empty_to_abc_content
559
        expected_results = sorted([
560
            self.added(tree2, 'root-id'),
561
            self.added(tree2, 'a-id'),
562
            self.added(tree2, 'b-id'),
563
            self.added(tree2, 'c-id'),
564
            self.deleted(tree1, 'empty-root-id')])
565
        self.assertEqual(expected_results, self.do_iter_changes(tree1, tree2))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
566
        self.check_has_changes(True, tree1, tree2)
2748.3.1 by Aaron Bentley
Start supporting [] for empty list
567
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
568
    def test_empty_to_abc_content_a_only(self):
569
        tree1 = self.make_branch_and_tree('1')
570
        tree2 = self.make_to_branch_and_tree('2')
571
        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.
572
        tree2 = self.get_tree_no_parents_abc_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
573
        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.
574
        self.assertEqual(
575
            [self.added(tree2, 'a-id')],
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
576
            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.
577
578
    def test_abc_content_to_empty_to_abc_content_a_only(self):
579
        tree1 = self.make_branch_and_tree('1')
580
        tree2 = self.make_to_branch_and_tree('2')
581
        tree1 = self.get_tree_no_parents_abc_content(tree1)
582
        tree2 = self.get_tree_no_parents_no_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
583
        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.
584
        self.assertEqual(
585
            [self.deleted(tree1, 'a-id')],
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
586
            self.do_iter_changes(tree1, tree2, specific_files=['a']))
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
587
588
    def test_empty_to_abc_content_a_and_c_only(self):
589
        tree1 = self.make_branch_and_tree('1')
590
        tree2 = self.make_to_branch_and_tree('2')
591
        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.
592
        tree2 = self.get_tree_no_parents_abc_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
593
        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.
594
        expected_result = [self.added(tree2, 'a-id'), self.added(tree2, 'c-id')]
595
        self.assertEqual(expected_result,
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
596
            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
597
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
598
    def test_abc_content_to_empty(self):
2012.1.1 by Aaron Bentley
Implement change iterator
599
        tree1 = self.make_branch_and_tree('1')
600
        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.
601
        tree1 = self.get_tree_no_parents_abc_content(tree1)
602
        tree2 = self.get_tree_no_parents_no_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
603
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2012.1.1 by Aaron Bentley
Implement change iterator
604
        def deleted(file_id):
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
605
            entry = tree1.inventory[file_id]
606
            path = tree1.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
607
            return (file_id, (path, None), True, (True, False),
2012.1.1 by Aaron Bentley
Implement change iterator
608
                    (entry.parent_id, None),
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
609
                    (entry.name, None), (entry.kind, None),
2012.1.1 by Aaron Bentley
Implement change iterator
610
                    (entry.executable, None))
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
611
        expected_results = sorted([
612
            self.added(tree2, 'empty-root-id'),
613
            deleted('root-id'), deleted('a-id'),
614
            deleted('b-id'), deleted('c-id')])
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
615
        self.assertEqual(
616
            expected_results,
617
            self.do_iter_changes(tree1, tree2))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
618
        self.check_has_changes(True, tree1, tree2)
2012.1.1 by Aaron Bentley
Implement change iterator
619
620
    def test_content_modification(self):
621
        tree1 = self.make_branch_and_tree('1')
622
        tree2 = self.make_to_branch_and_tree('2')
623
        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.
624
        tree2 = self.get_tree_no_parents_abc_content_2(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
625
        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.
626
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
627
        self.assertEqual([('a-id', ('a', 'a'), True, (True, True),
628
                           (root_id, root_id), ('a', 'a'),
629
                           ('file', 'file'), (False, False))],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
630
                         self.do_iter_changes(tree1, tree2))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
631
        self.check_has_changes(True, tree1, tree2)
2012.1.1 by Aaron Bentley
Implement change iterator
632
633
    def test_meta_modification(self):
634
        tree1 = self.make_branch_and_tree('1')
635
        tree2 = self.make_to_branch_and_tree('2')
636
        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.
637
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
638
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
639
        self.assertEqual([('c-id', ('b/c', 'b/c'), False, (True, True),
640
                           ('b-id', 'b-id'), ('c', 'c'), ('file', 'file'),
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
641
                          (False, True))],
642
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
643
2255.7.6 by Robert Collins
Test for iterating changes past empty directories.
644
    def test_empty_dir(self):
645
        """an empty dir should not cause glitches to surrounding files."""
646
        tree1 = self.make_branch_and_tree('1')
647
        tree2 = self.make_to_branch_and_tree('2')
648
        tree1 = self.get_tree_no_parents_abc_content(tree1)
649
        tree2 = self.get_tree_no_parents_abc_content(tree2)
650
        # the pathname is chosen to fall between 'a' and 'b'.
651
        self.build_tree(['1/a-empty/', '2/a-empty/'])
652
        tree1.add(['a-empty'], ['a-empty'])
653
        tree2.add(['a-empty'], ['a-empty'])
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
654
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.7.6 by Robert Collins
Test for iterating changes past empty directories.
655
        expected = []
656
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
657
2012.1.1 by Aaron Bentley
Implement change iterator
658
    def test_file_rename(self):
659
        tree1 = self.make_branch_and_tree('1')
660
        tree2 = self.make_to_branch_and_tree('2')
661
        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.
662
        tree2 = self.get_tree_no_parents_abc_content_4(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
663
        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.
664
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
665
        self.assertEqual([('a-id', ('a', 'd'), False, (True, True),
666
                           (root_id, root_id), ('a', 'd'), ('file', 'file'),
667
                           (False, False))],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
668
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
669
670
    def test_file_rename_and_modification(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_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
674
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
675
        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.
676
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
677
        self.assertEqual([('a-id', ('a', 'd'), True, (True, True),
678
                           (root_id, root_id), ('a', 'd'), ('file', 'file'),
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
679
                           (False, False))],
680
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
681
682
    def test_file_rename_and_meta_modification(self):
683
        tree1 = self.make_branch_and_tree('1')
684
        tree2 = self.make_to_branch_and_tree('2')
685
        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.
686
        tree2 = self.get_tree_no_parents_abc_content_6(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
687
        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.
688
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
689
        self.assertEqual([('c-id', ('b/c', 'e'), False, (True, True),
690
                           ('b-id', root_id), ('c', 'e'), ('file', 'file'),
691
                           (False, True))],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
692
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
693
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
694
    def test_missing_in_target(self):
695
        """Test with the target files versioned but absent from disk."""
696
        tree1 = self.make_branch_and_tree('1')
697
        tree2 = self.make_to_branch_and_tree('2')
698
        tree1 = self.get_tree_no_parents_abc_content(tree1)
699
        tree2 = self.get_tree_no_parents_abc_content(tree2)
700
        os.unlink('2/a')
701
        shutil.rmtree('2/b')
702
        # TODO ? have a symlink here?
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
703
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
704
        self.not_applicable_if_missing_in('a', tree2)
705
        self.not_applicable_if_missing_in('b', tree2)
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
706
        root_id = tree1.path2id('')
707
        expected = sorted([
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
708
            self.missing('a-id', 'a', 'a', root_id, 'file'),
709
            self.missing('b-id', 'b', 'b', root_id, 'directory'),
710
            self.missing('c-id', 'b/c', 'b/c', 'b-id', 'file'),
711
            ])
712
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
713
714
    def test_missing_and_renamed(self):
715
        tree1 = self.make_branch_and_tree('tree1')
716
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.186 by Martin Pool
Fix up root id for some more comparison tests
717
        tree2.set_root_id(tree1.get_root_id())
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
718
        self.build_tree(['tree1/file'])
719
        tree1.add(['file'], ['file-id'])
720
        self.build_tree(['tree2/directory/'])
721
        tree2.add(['directory'], ['file-id'])
722
        os.rmdir('tree2/directory')
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
723
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
724
        self.not_applicable_if_missing_in('directory', tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
725
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
726
        root_id = tree1.path2id('')
727
        expected = sorted([
728
            self.missing('file-id', 'file', 'directory', root_id, 'file'),
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
729
            ])
730
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
731
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)
732
    def test_only_in_source_and_missing(self):
733
        tree1 = self.make_branch_and_tree('tree1')
734
        tree2 = self.make_to_branch_and_tree('tree2')
735
        tree2.set_root_id(tree1.get_root_id())
736
        self.build_tree(['tree1/file'])
737
        tree1.add(['file'], ['file-id'])
738
        os.unlink('tree1/file')
739
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
740
        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)
741
        root_id = tree1.path2id('')
742
        expected = [('file-id', ('file', None), False, (True, False),
743
            (root_id, None), ('file', None), (None, None), (False, None))]
744
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
745
746
    def test_only_in_target_and_missing(self):
747
        tree1 = self.make_branch_and_tree('tree1')
748
        tree2 = self.make_to_branch_and_tree('tree2')
749
        tree2.set_root_id(tree1.get_root_id())
750
        self.build_tree(['tree2/file'])
751
        tree2.add(['file'], ['file-id'])
752
        os.unlink('tree2/file')
753
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
754
        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)
755
        root_id = tree1.path2id('')
756
        expected = [('file-id', (None, 'file'), False, (False, True),
757
            (None, root_id), (None, 'file'), (None, None), (None, False))]
758
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
759
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.
760
    def test_only_in_target_missing_subtree_specific_bug_367632(self):
761
        tree1 = self.make_branch_and_tree('tree1')
762
        tree2 = self.make_to_branch_and_tree('tree2')
763
        tree2.set_root_id(tree1.get_root_id())
764
        self.build_tree(['tree2/a-dir/', 'tree2/a-dir/a-file'])
765
        tree2.add(['a-dir', 'a-dir/a-file'], ['dir-id', 'file-id'])
766
        os.unlink('tree2/a-dir/a-file')
767
        os.rmdir('tree2/a-dir')
768
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
769
        self.not_applicable_if_missing_in('a-dir', tree2)
770
        root_id = tree1.path2id('')
771
        expected = [
772
            ('dir-id', (None, 'a-dir'), False, (False, True),
773
            (None, root_id), (None, 'a-dir'), (None, None), (None, False)),
774
            ('file-id', (None, 'a-dir/a-file'), False, (False, True),
775
            (None, 'dir-id'), (None, 'a-file'), (None, None), (None, False))
776
            ]
777
        # bug 367632 showed that specifying the root broke some code paths,
778
        # so we check this contract with and without it.
779
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
780
        self.assertEqual(expected,
781
            self.do_iter_changes(tree1, tree2, specific_files=['']))
782
2012.1.1 by Aaron Bentley
Implement change iterator
783
    def test_unchanged_with_renames_and_modifications(self):
784
        """want_unchanged should generate a list of unchanged entries."""
785
        tree1 = self.make_branch_and_tree('1')
786
        tree2 = self.make_to_branch_and_tree('2')
787
        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.
788
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
789
        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.
790
        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.
791
        self.assertEqual(sorted([self.unchanged(tree1, root_id),
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
792
            self.unchanged(tree1, 'b-id'),
793
            ('a-id', ('a', 'd'), True, (True, True),
794
             (root_id, root_id), ('a', 'd'), ('file', 'file'),
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
795
            (False, False)), self.unchanged(tree1, 'c-id')]),
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.
796
            self.do_iter_changes(tree1, tree2, include_unchanged=True))
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
797
798
    def test_compare_subtrees(self):
799
        tree1 = self.make_branch_and_tree('1')
2255.9.2 by Martin Pool
test_compare_subtrees runs against all trees that claim to support
800
        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.
801
            return
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
802
        tree1.set_root_id('root-id')
803
        subtree1 = self.make_branch_and_tree('1/sub')
804
        subtree1.set_root_id('subtree-id')
2255.9.2 by Martin Pool
test_compare_subtrees runs against all trees that claim to support
805
        tree1.add_reference(subtree1)
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
806
807
        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
808
        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.
809
            return
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
810
        tree2.set_root_id('root-id')
811
        subtree2 = self.make_to_branch_and_tree('2/sub')
812
        subtree2.set_root_id('subtree-id')
813
        tree2.add_reference(subtree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
814
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
815
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
816
        self.assertEqual([], list(tree2.iter_changes(tree1)))
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
817
        subtree1.commit('commit', rev_id='commit-a')
818
        self.assertEqual([
819
            ('root-id',
820
             (u'', u''),
821
             False,
822
             (True, True),
823
             (None, None),
824
             (u'', u''),
825
             ('directory', 'directory'),
826
             (False, False)),
827
            ('subtree-id',
828
             ('sub', 'sub',),
829
             False,
830
             (True, True),
831
             ('root-id', 'root-id'),
832
             ('sub', 'sub'),
833
             ('tree-reference', 'tree-reference'),
834
             (False, False))],
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
835
                         list(tree2.iter_changes(tree1,
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
836
                             include_unchanged=True)))
2255.2.160 by Martin Pool
(merge) updates from dirstate branch
837
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
838
    def test_disk_in_subtrees_skipped(self):
839
        """subtrees are considered not-in-the-current-tree.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
840
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
841
        This test tests the trivial case, where the basis has no paths in the
842
        current trees subtree.
843
        """
844
        tree1 = self.make_branch_and_tree('1')
845
        tree1.set_root_id('root-id')
846
        tree2 = self.make_to_branch_and_tree('2')
847
        if not tree2.supports_tree_reference():
848
            return
849
        tree2.set_root_id('root-id')
850
        subtree2 = self.make_to_branch_and_tree('2/sub')
851
        subtree2.set_root_id('subtree-id')
4100.2.4 by Aaron Bentley
More support for not autodetecting tree refs
852
        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.
853
        self.build_tree(['2/sub/file'])
854
        subtree2.add(['file'])
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
855
856
        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.
857
        # this should filter correctly from above
858
        self.assertEqual([self.added(tree2, 'subtree-id')],
859
            self.do_iter_changes(tree1, tree2, want_unversioned=True))
860
        # and when the path is named
861
        self.assertEqual([self.added(tree2, 'subtree-id')],
862
            self.do_iter_changes(tree1, tree2, specific_files=['sub'],
863
                want_unversioned=True))
864
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
865
    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.
866
        tree1 = self.make_branch_and_tree('tree1')
867
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.186 by Martin Pool
Fix up root id for some more comparison tests
868
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
869
        self.build_tree(['tree1/a', 'tree1/c',
870
                         'tree2/a', 'tree2/b', 'tree2/c'])
871
        tree1.add(['a', 'c'], ['a-id', 'c-id'])
872
        tree2.add(['a', 'c'], ['a-id', 'c-id'])
873
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
874
        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.
875
876
        # We should ignore the fact that 'b' exists in tree-2
877
        # because the want_unversioned parameter was not given.
878
        expected = sorted([
879
            self.content_changed(tree2, 'a-id'),
880
            self.content_changed(tree2, 'c-id'),
881
            ])
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
882
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
883
        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.
884
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
885
    def test_unversioned_paths_in_tree(self):
886
        tree1 = self.make_branch_and_tree('tree1')
887
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.184 by Martin Pool
Fixes for some comparison tests; repr of DirStateRevisionTree
888
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
889
        self.build_tree(['tree2/file', 'tree2/dir/'])
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
890
        if has_symlinks():
891
            os.symlink('target', 'tree2/link')
892
            links_supported = True
893
        else:
894
            links_supported = False
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
895
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
896
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
897
        expected = [
898
            self.unversioned(tree2, 'file'),
899
            self.unversioned(tree2, 'dir'),
900
            ]
901
        if links_supported:
902
            expected.append(self.unversioned(tree2, 'link'))
903
        expected = sorted(expected)
904
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
905
            want_unversioned=True))
906
907
    def test_unversioned_paths_in_tree_specific_files(self):
908
        tree1 = self.make_branch_and_tree('tree1')
909
        tree2 = self.make_to_branch_and_tree('tree2')
910
        self.build_tree(['tree2/file', 'tree2/dir/'])
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
911
        if has_symlinks():
912
            os.symlink('target', 'tree2/link')
913
            links_supported = True
914
        else:
915
            links_supported = False
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
916
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
917
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
918
        expected = [
919
            self.unversioned(tree2, 'file'),
920
            self.unversioned(tree2, 'dir'),
921
            ]
922
        specific_files=['file', 'dir']
923
        if links_supported:
924
            expected.append(self.unversioned(tree2, 'link'))
925
            specific_files.append('link')
926
        expected = sorted(expected)
927
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
928
            specific_files=specific_files, require_versioned=False,
929
            want_unversioned=True))
930
931
    def test_unversioned_paths_in_target_matching_source_old_names(self):
932
        # its likely that naive implementations of unversioned file support
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
933
        # 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.
934
        # due to a rename, not due to unversioning it.
935
        # That is, if the old tree has a versioned file 'foo', and
936
        # the new tree has the same file but versioned as 'bar', and also
937
        # has an unknown file 'foo', we should get back output for
938
        # both foo and bar.
939
        tree1 = self.make_branch_and_tree('tree1')
940
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.187 by Martin Pool
set common root ids in more tests
941
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
942
        self.build_tree(['tree2/file', 'tree2/dir/',
943
            'tree1/file', 'tree2/movedfile',
944
            'tree1/dir/', 'tree2/moveddir/'])
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
945
        if has_symlinks():
946
            os.symlink('target', 'tree1/link')
947
            os.symlink('target', 'tree2/link')
948
            os.symlink('target', 'tree2/movedlink')
949
            links_supported = True
950
        else:
951
            links_supported = False
952
        tree1.add(['file', 'dir'], ['file-id', 'dir-id'])
953
        tree2.add(['movedfile', 'moveddir'], ['file-id', 'dir-id'])
954
        if links_supported:
955
            tree1.add(['link'], ['link-id'])
956
            tree2.add(['movedlink'], ['link-id'])
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
957
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
958
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
959
        root_id = tree1.path2id('')
960
        expected = [
961
            self.renamed(tree1, tree2, 'dir-id', False),
962
            self.renamed(tree1, tree2, 'file-id', True),
963
            self.unversioned(tree2, 'file'),
964
            self.unversioned(tree2, 'dir'),
965
            ]
966
        specific_files=['file', 'dir']
967
        if links_supported:
968
            expected.append(self.renamed(tree1, tree2, 'link-id', False))
969
            expected.append(self.unversioned(tree2, 'link'))
970
            specific_files.append('link')
971
        expected = sorted(expected)
972
        # run once with, and once without specific files, to catch
973
        # potentially different code paths.
974
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
975
            require_versioned=False,
976
            want_unversioned=True))
977
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
978
            specific_files=specific_files, require_versioned=False,
979
            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.
980
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
981
    def test_similar_filenames(self):
982
        """Test when we have a few files with similar names."""
983
        tree1 = self.make_branch_and_tree('tree1')
984
        tree2 = self.make_branch_and_tree('tree2')
985
        tree2.set_root_id(tree1.get_root_id())
986
987
        # The trees are actually identical, but they happen to contain
988
        # similarly named files.
989
        self.build_tree(['tree1/a/',
990
                         'tree1/a/b/',
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
991
                         'tree1/a/b/c/',
992
                         'tree1/a/b/c/d/',
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
993
                         'tree1/a-c/',
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
994
                         'tree1/a-c/e/',
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
995
                         'tree2/a/',
996
                         'tree2/a/b/',
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
997
                         'tree2/a/b/c/',
998
                         'tree2/a/b/c/d/',
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
999
                         'tree2/a-c/',
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
1000
                         'tree2/a-c/e/',
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
1001
                        ])
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
1002
        tree1.add(['a', 'a/b', 'a/b/c', 'a/b/c/d', 'a-c', 'a-c/e'],
1003
                  ['a-id', 'b-id', 'c-id', 'd-id', 'a-c-id', 'e-id'])
1004
        tree2.add(['a', 'a/b', 'a/b/c', 'a/b/c/d', 'a-c', 'a-c/e'],
1005
                  ['a-id', 'b-id', 'c-id', 'd-id', 'a-c-id', 'e-id'])
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
1006
1007
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1008
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
1009
1010
        self.assertEqual([], self.do_iter_changes(tree1, tree2,
1011
                                                  want_unversioned=True))
2466.5.2 by John Arbash Meinel
Extend the test a bit to make sure the include_unchanged value is correct.
1012
        expected = sorted([
1013
            self.unchanged(tree2, tree2.get_root_id()),
1014
            self.unchanged(tree2, 'a-id'),
1015
            self.unchanged(tree2, 'b-id'),
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
1016
            self.unchanged(tree2, 'c-id'),
1017
            self.unchanged(tree2, 'd-id'),
2466.5.2 by John Arbash Meinel
Extend the test a bit to make sure the include_unchanged value is correct.
1018
            self.unchanged(tree2, 'a-c-id'),
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
1019
            self.unchanged(tree2, 'e-id'),
2466.5.2 by John Arbash Meinel
Extend the test a bit to make sure the include_unchanged value is correct.
1020
            ])
1021
        self.assertEqual(expected,
1022
                         self.do_iter_changes(tree1, tree2,
1023
                                              want_unversioned=True,
1024
                                              include_unchanged=True))
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
1025
1026
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
1027
    def test_unversioned_subtree_only_emits_root(self):
1028
        tree1 = self.make_branch_and_tree('tree1')
1029
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.188 by Martin Pool
Set common root id in comparison tests
1030
        tree2.set_root_id(tree1.get_root_id())
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
1031
        self.build_tree(['tree2/dir/', 'tree2/dir/file'])
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
1032
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1033
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
1034
        expected = [
1035
            self.unversioned(tree2, 'dir'),
1036
            ]
1037
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
1038
            want_unversioned=True))
1039
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.
1040
    def make_trees_with_symlinks(self):
1041
        tree1 = self.make_branch_and_tree('tree1')
1042
        tree2 = self.make_to_branch_and_tree('tree2')
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
1043
        tree2.set_root_id(tree1.get_root_id())
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.
1044
        self.build_tree(['tree1/fromfile', 'tree1/fromdir/'])
1045
        self.build_tree(['tree2/tofile', 'tree2/todir/', 'tree2/unknown'])
1046
        os.symlink('original', 'tree1/changed')
1047
        os.symlink('original', 'tree1/removed')
1048
        os.symlink('original', 'tree1/tofile')
1049
        os.symlink('original', 'tree1/todir')
1050
        # we make the unchanged link point at unknown to catch incorrect
1051
        # symlink-following code in the specified_files test.
1052
        os.symlink('unknown', 'tree1/unchanged')
1053
        os.symlink('new',      'tree2/added')
1054
        os.symlink('new',      'tree2/changed')
1055
        os.symlink('new',      'tree2/fromfile')
1056
        os.symlink('new',      'tree2/fromdir')
1057
        os.symlink('unknown', 'tree2/unchanged')
1058
        from_paths_and_ids = [
1059
            'fromdir',
1060
            'fromfile',
1061
            'changed',
1062
            'removed',
1063
            'todir',
1064
            'tofile',
1065
            'unchanged',
1066
            ]
1067
        to_paths_and_ids = [
1068
            'added',
1069
            'fromdir',
1070
            'fromfile',
1071
            'changed',
1072
            'todir',
1073
            'tofile',
1074
            'unchanged',
1075
            ]
1076
        tree1.add(from_paths_and_ids, from_paths_and_ids)
1077
        tree2.add(to_paths_and_ids, to_paths_and_ids)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1078
        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.
1079
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
1080
    def test_versioned_symlinks(self):
2949.5.1 by Alexander Belchenko
selftest: use SymlinkFeature instead of TestSkipped where appropriate
1081
        self.requireFeature(tests.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.
1082
        tree1, tree2 = self.make_trees_with_symlinks()
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1083
        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.
1084
        root_id = tree1.path2id('')
1085
        expected = [
1086
            self.unchanged(tree1, tree1.path2id('')),
1087
            self.added(tree2, 'added'),
1088
            self.content_changed(tree2, 'changed'),
1089
            self.kind_changed(tree1, tree2, 'fromdir'),
1090
            self.kind_changed(tree1, tree2, 'fromfile'),
1091
            self.deleted(tree1, 'removed'),
1092
            self.unchanged(tree2, 'unchanged'),
1093
            self.unversioned(tree2, 'unknown'),
1094
            self.kind_changed(tree1, tree2, 'todir'),
1095
            self.kind_changed(tree1, tree2, 'tofile'),
1096
            ]
1097
        expected = sorted(expected)
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
1098
        self.assertEqual(expected,
1099
            self.do_iter_changes(tree1, tree2, include_unchanged=True,
1100
                want_unversioned=True))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
1101
        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.
1102
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
1103
    def test_versioned_symlinks_specific_files(self):
2949.5.1 by Alexander Belchenko
selftest: use SymlinkFeature instead of TestSkipped where appropriate
1104
        self.requireFeature(tests.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.
1105
        tree1, tree2 = self.make_trees_with_symlinks()
1106
        root_id = tree1.path2id('')
1107
        expected = [
1108
            self.added(tree2, 'added'),
1109
            self.content_changed(tree2, 'changed'),
1110
            self.kind_changed(tree1, tree2, 'fromdir'),
1111
            self.kind_changed(tree1, tree2, 'fromfile'),
1112
            self.deleted(tree1, 'removed'),
1113
            self.kind_changed(tree1, tree2, 'todir'),
1114
            self.kind_changed(tree1, tree2, 'tofile'),
1115
            ]
1116
        expected = sorted(expected)
1117
        # we should get back just the changed links. We pass in 'unchanged' to
1118
        # make sure that it is correctly not returned - and neither is the
1119
        # unknown path 'unknown' which it points at.
1120
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
1121
            specific_files=['added', 'changed', 'fromdir', 'fromfile',
1122
            'removed', 'unchanged', 'todir', 'tofile']))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
1123
        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.
1124
2255.7.21 by John Arbash Meinel
Get iter_changes working again, by fixing set_parent_trees to
1125
    def test_tree_with_special_names(self):
2255.7.15 by John Arbash Meinel
Try to create an intertree test that exposes the walkdir vs dirstate mismatch. No luck yet.
1126
        tree1, tree2, paths, path_ids = self.make_tree_with_special_names()
1127
        expected = sorted(self.added(tree2, f_id) for f_id in path_ids)
1128
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
1129
        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.
1130
1131
    def test_trees_with_special_names(self):
1132
        tree1, tree2, paths, path_ids = self.make_trees_with_special_names()
1133
        expected = sorted(self.content_changed(tree2, f_id) for f_id in path_ids
1134
                          if f_id.endswith('_f-id'))
1135
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
1136
        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
1137
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
1138
    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.
1139
        tree1 = self.make_branch_and_tree('tree1')
1140
        tree2 = self.make_to_branch_and_tree('tree2')
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
1141
        tree2.set_root_id(tree1.get_root_id())
2255.7.35 by John Arbash Meinel
Handle the case when a directory has been removed, and isn't the last entry.
1142
        self.build_tree(['tree1/a', 'tree1/b/', 'tree1/b/c',
1143
                         'tree1/b/d/', 'tree1/b/d/e', 'tree1/f/', 'tree1/f/g',
1144
                         'tree2/a', 'tree2/f/', 'tree2/f/g'])
1145
        tree1.add(['a', 'b', 'b/c', 'b/d/', 'b/d/e', 'f', 'f/g'],
1146
                  ['a-id', 'b-id', 'c-id', 'd-id', 'e-id', 'f-id', 'g-id'])
1147
        tree2.add(['a', 'f', 'f/g'], ['a-id', 'f-id', 'g-id'])
1148
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1149
        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.
1150
        # We should notice that 'b' and all its children are deleted
2255.7.35 by John Arbash Meinel
Handle the case when a directory has been removed, and isn't the last entry.
1151
        expected = sorted([
1152
            self.content_changed(tree2, 'a-id'),
1153
            self.content_changed(tree2, 'g-id'),
1154
            self.deleted(tree1, 'b-id'),
1155
            self.deleted(tree1, 'c-id'),
1156
            self.deleted(tree1, 'd-id'),
1157
            self.deleted(tree1, 'e-id'),
1158
            ])
1159
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
1160
        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.
1161
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1162
    def test_added_unicode(self):
1163
        tree1 = self.make_branch_and_tree('tree1')
1164
        tree2 = self.make_to_branch_and_tree('tree2')
1165
        root_id = tree1.get_root_id()
1166
        tree2.set_root_id(root_id)
1167
1168
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1169
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1170
        a_id = u'\u03b1-id'.encode('utf8')
1171
        added_id = u'\u03c9_added_id'.encode('utf8')
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1172
        try:
1173
            self.build_tree([u'tree1/\u03b1/',
1174
                             u'tree2/\u03b1/',
1175
                             u'tree2/\u03b1/\u03c9-added',
1176
                            ])
1177
        except UnicodeError:
1178
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1179
        tree1.add([u'\u03b1'], [a_id])
1180
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-added'], [a_id, added_id])
1181
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1182
        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.
1183
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1184
        self.assertEqual([self.added(tree2, added_id)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1185
                         self.do_iter_changes(tree1, tree2))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1186
        self.assertEqual([self.added(tree2, added_id)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1187
                         self.do_iter_changes(tree1, tree2,
1188
                                              specific_files=[u'\u03b1']))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
1189
        self.check_has_changes(True, tree1, tree2)
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1190
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1191
    def test_deleted_unicode(self):
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1192
        tree1 = self.make_branch_and_tree('tree1')
1193
        tree2 = self.make_to_branch_and_tree('tree2')
1194
        root_id = tree1.get_root_id()
1195
        tree2.set_root_id(root_id)
1196
1197
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1198
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1199
        a_id = u'\u03b1-id'.encode('utf8')
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1200
        deleted_id = u'\u03c9_deleted_id'.encode('utf8')
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1201
        try:
1202
            self.build_tree([u'tree1/\u03b1/',
1203
                             u'tree1/\u03b1/\u03c9-deleted',
1204
                             u'tree2/\u03b1/',
1205
                            ])
1206
        except UnicodeError:
1207
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1208
        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.
1209
        tree2.add([u'\u03b1'], [a_id])
1210
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1211
        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.
1212
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1213
        self.assertEqual([self.deleted(tree1, deleted_id)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1214
                         self.do_iter_changes(tree1, tree2))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1215
        self.assertEqual([self.deleted(tree1, deleted_id)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1216
                         self.do_iter_changes(tree1, tree2,
1217
                                              specific_files=[u'\u03b1']))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
1218
        self.check_has_changes(True, tree1, tree2)
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1219
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1220
    def test_modified_unicode(self):
2360.1.1 by John Arbash Meinel
Basic implementation test that makes sure _iter_changes handles unknown files.
1221
        tree1 = self.make_branch_and_tree('tree1')
1222
        tree2 = self.make_to_branch_and_tree('tree2')
1223
        root_id = tree1.get_root_id()
1224
        tree2.set_root_id(root_id)
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1225
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1226
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1227
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1228
        a_id = u'\u03b1-id'.encode('utf8')
1229
        mod_id = u'\u03c9_mod_id'.encode('utf8')
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1230
        try:
1231
            self.build_tree([u'tree1/\u03b1/',
1232
                             u'tree1/\u03b1/\u03c9-modified',
1233
                             u'tree2/\u03b1/',
1234
                             u'tree2/\u03b1/\u03c9-modified',
1235
                            ])
1236
        except UnicodeError:
1237
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1238
        tree1.add([u'\u03b1', u'\u03b1/\u03c9-modified'], [a_id, mod_id])
1239
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-modified'], [a_id, mod_id])
1240
1241
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1242
1243
        self.assertEqual([self.content_changed(tree1, mod_id)],
1244
                         self.do_iter_changes(tree1, tree2))
1245
        self.assertEqual([self.content_changed(tree1, mod_id)],
1246
                         self.do_iter_changes(tree1, tree2,
1247
                                              specific_files=[u'\u03b1']))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
1248
        self.check_has_changes(True, tree1, tree2)
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1249
1250
    def test_renamed_unicode(self):
1251
        tree1 = self.make_branch_and_tree('tree1')
1252
        tree2 = self.make_to_branch_and_tree('tree2')
1253
        root_id = tree1.get_root_id()
1254
        tree2.set_root_id(root_id)
1255
1256
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1257
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1258
        a_id = u'\u03b1-id'.encode('utf8')
1259
        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.
1260
        try:
1261
            self.build_tree([u'tree1/\u03b1/',
1262
                             u'tree2/\u03b1/',
1263
                            ])
1264
        except UnicodeError:
1265
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1266
        self.build_tree_contents([(u'tree1/\u03c9-source', 'contents\n'),
1267
                                  (u'tree2/\u03b1/\u03c9-target', 'contents\n'),
1268
                                 ])
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1269
        tree1.add([u'\u03b1', u'\u03c9-source'], [a_id, rename_id])
1270
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-target'], [a_id, rename_id])
1271
1272
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1273
1274
        self.assertEqual([self.renamed(tree1, tree2, rename_id, False)],
1275
                         self.do_iter_changes(tree1, tree2))
1276
        self.assertEqual([self.renamed(tree1, tree2, rename_id, False)],
1277
                         self.do_iter_changes(tree1, tree2,
1278
                                              specific_files=[u'\u03b1']))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
1279
        self.check_has_changes(True, tree1, tree2)
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1280
1281
    def test_unchanged_unicode(self):
1282
        tree1 = self.make_branch_and_tree('tree1')
1283
        tree2 = self.make_to_branch_and_tree('tree2')
1284
        root_id = tree1.get_root_id()
1285
        tree2.set_root_id(root_id)
1286
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1287
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1288
        a_id = u'\u03b1-id'.encode('utf8')
1289
        subfile_id = u'\u03c9-subfile-id'.encode('utf8')
1290
        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.
1291
        try:
1292
            self.build_tree([u'tree1/\u03b1/',
1293
                             u'tree2/\u03b1/',
1294
                            ])
1295
        except UnicodeError:
1296
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1297
        self.build_tree_contents([
1298
            (u'tree1/\u03b1/\u03c9-subfile', 'sub contents\n'),
1299
            (u'tree2/\u03b1/\u03c9-subfile', 'sub contents\n'),
1300
            (u'tree1/\u03c9-rootfile', 'root contents\n'),
1301
            (u'tree2/\u03c9-rootfile', 'root contents\n'),
1302
            ])
1303
        tree1.add([u'\u03b1', u'\u03b1/\u03c9-subfile', u'\u03c9-rootfile'],
1304
                  [a_id, subfile_id, rootfile_id])
1305
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-subfile', u'\u03c9-rootfile'],
1306
                  [a_id, subfile_id, rootfile_id])
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1307
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1308
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1309
2360.1.1 by John Arbash Meinel
Basic implementation test that makes sure _iter_changes handles unknown files.
1310
        expected = sorted([
1311
            self.unchanged(tree1, root_id),
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1312
            self.unchanged(tree1, a_id),
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1313
            self.unchanged(tree1, subfile_id),
1314
            self.unchanged(tree1, rootfile_id),
1315
            ])
1316
        self.assertEqual(expected,
1317
                         self.do_iter_changes(tree1, tree2,
1318
                                              include_unchanged=True))
1319
1320
        # We should also be able to select just a subset
1321
        expected = sorted([
1322
            self.unchanged(tree1, a_id),
1323
            self.unchanged(tree1, subfile_id),
1324
            ])
1325
        self.assertEqual(expected,
1326
                         self.do_iter_changes(tree1, tree2,
1327
                                              specific_files=[u'\u03b1'],
1328
                                              include_unchanged=True))
1329
1330
    def test_unknown_unicode(self):
1331
        tree1 = self.make_branch_and_tree('tree1')
1332
        tree2 = self.make_to_branch_and_tree('tree2')
1333
        root_id = tree1.get_root_id()
1334
        tree2.set_root_id(root_id)
1335
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1336
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1337
        a_id = u'\u03b1-id'.encode('utf8')
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1338
        try:
1339
            self.build_tree([u'tree1/\u03b1/',
1340
                             u'tree2/\u03b1/',
1341
                             u'tree2/\u03b1/unknown_dir/',
1342
                             u'tree2/\u03b1/unknown_file',
1343
                             u'tree2/\u03b1/unknown_dir/file',
1344
                             u'tree2/\u03c9-unknown_root_file',
1345
                            ])
1346
        except UnicodeError:
1347
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1348
        tree1.add([u'\u03b1'], [a_id])
1349
        tree2.add([u'\u03b1'], [a_id])
1350
1351
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1352
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1353
1354
        expected = sorted([
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1355
            self.unversioned(tree2, u'\u03b1/unknown_dir'),
1356
            self.unversioned(tree2, u'\u03b1/unknown_file'),
1357
            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.
1358
            # a/unknown_dir/file should not be included because we should not
1359
            # recurse into unknown_dir
1360
            # self.unversioned(tree2, 'a/unknown_dir/file'),
1361
            ])
1362
        self.assertEqual(expected,
1363
                         self.do_iter_changes(tree1, tree2,
1364
                                              require_versioned=False,
1365
                                              want_unversioned=True))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1366
        self.assertEqual([], # Without want_unversioned we should get nothing
1367
                         self.do_iter_changes(tree1, tree2))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
1368
        self.check_has_changes(False, tree1, tree2)
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1369
1370
        # We should also be able to select just a subset
1371
        expected = sorted([
1372
            self.unversioned(tree2, u'\u03b1/unknown_dir'),
1373
            self.unversioned(tree2, u'\u03b1/unknown_file'),
1374
            ])
1375
        self.assertEqual(expected,
1376
                         self.do_iter_changes(tree1, tree2,
1377
                                              specific_files=[u'\u03b1'],
1378
                                              require_versioned=False,
1379
                                              want_unversioned=True))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1380
        self.assertEqual([], # Without want_unversioned we should get nothing
1381
                         self.do_iter_changes(tree1, tree2,
1382
                                              specific_files=[u'\u03b1']))
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1383
1384
    def test_unknown_empty_dir(self):
1385
        tree1 = self.make_branch_and_tree('tree1')
1386
        tree2 = self.make_to_branch_and_tree('tree2')
1387
        root_id = tree1.get_root_id()
1388
        tree2.set_root_id(root_id)
1389
2402.2.4 by John Arbash Meinel
Clean up the setup for clarity (suggested by Robert)
1390
        # Start with 2 identical trees
1391
        self.build_tree(['tree1/a/', 'tree1/b/',
1392
                         'tree2/a/', 'tree2/b/'])
1393
        self.build_tree_contents([('tree1/b/file', 'contents\n'),
1394
                                  ('tree2/b/file', 'contents\n')])
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1395
        tree1.add(['a', 'b', 'b/file'], ['a-id', 'b-id', 'b-file-id'])
1396
        tree2.add(['a', 'b', 'b/file'], ['a-id', 'b-id', 'b-file-id'])
1397
2402.2.2 by John Arbash Meinel
Fix _iter_changes to properly handle versioned (but empty) directories
1398
        # Now create some unknowns in tree2
1399
        # We should find both a/file and a/dir as unknown, but we shouldn't
1400
        # recurse into a/dir to find that a/dir/subfile is also unknown.
1401
        self.build_tree(['tree2/a/file', 'tree2/a/dir/', 'tree2/a/dir/subfile'])
1402
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1403
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1404
        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()
1405
1406
        expected = sorted([
1407
            self.unversioned(tree2, u'a/file'),
2402.2.2 by John Arbash Meinel
Fix _iter_changes to properly handle versioned (but empty) directories
1408
            self.unversioned(tree2, u'a/dir'),
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1409
            ])
1410
        self.assertEqual(expected,
1411
                         self.do_iter_changes(tree1, tree2,
1412
                                              require_versioned=False,
1413
                                              want_unversioned=True))
2456.2.1 by John Arbash Meinel
(broken) Add a (failing) test that _iter_changes works correctly
1414
1415
    def test_rename_over_deleted(self):
1416
        tree1 = self.make_branch_and_tree('tree1')
1417
        tree2 = self.make_to_branch_and_tree('tree2')
1418
        root_id = tree1.get_root_id()
1419
        tree2.set_root_id(root_id)
1420
1421
        # The final changes should be:
1422
        #   touch a b c d
1423
        #   add a b c d
1424
        #   commit
1425
        #   rm a d
1426
        #   mv b a
1427
        #   mv c d
1428
        self.build_tree_contents([
1429
            ('tree1/a', 'a contents\n'),
1430
            ('tree1/b', 'b contents\n'),
1431
            ('tree1/c', 'c contents\n'),
1432
            ('tree1/d', 'd contents\n'),
1433
            ('tree2/a', 'b contents\n'),
1434
            ('tree2/d', 'c contents\n'),
1435
            ])
1436
        tree1.add(['a', 'b', 'c', 'd'], ['a-id', 'b-id', 'c-id', 'd-id'])
1437
        tree2.add(['a', 'd'], ['b-id', 'c-id'])
1438
1439
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1440
1441
        expected = sorted([
1442
            self.deleted(tree1, 'a-id'),
1443
            self.deleted(tree1, 'd-id'),
1444
            self.renamed(tree1, tree2, 'b-id', False),
1445
            self.renamed(tree1, tree2, 'c-id', False),
1446
            ])
1447
        self.assertEqual(expected,
1448
                         self.do_iter_changes(tree1, tree2))
4503.1.3 by Vincent Ladeuil
Take review comments into account.
1449
        self.check_has_changes(True, tree1, tree2)
2456.2.2 by John Arbash Meinel
Add another (failing) test case.
1450
1451
    def test_deleted_and_unknown(self):
1452
        """Test a file marked removed, but still present on disk."""
1453
        tree1 = self.make_branch_and_tree('tree1')
1454
        tree2 = self.make_to_branch_and_tree('tree2')
1455
        root_id = tree1.get_root_id()
1456
        tree2.set_root_id(root_id)
1457
1458
        # The final changes should be:
1459
        # bzr add a b c
1460
        # bzr rm --keep b
1461
        self.build_tree_contents([
1462
            ('tree1/a', 'a contents\n'),
1463
            ('tree1/b', 'b contents\n'),
1464
            ('tree1/c', 'c contents\n'),
1465
            ('tree2/a', 'a contents\n'),
1466
            ('tree2/b', 'b contents\n'),
1467
            ('tree2/c', 'c contents\n'),
1468
            ])
1469
        tree1.add(['a', 'b', 'c'], ['a-id', 'b-id', 'c-id'])
1470
        tree2.add(['a', 'c'], ['a-id', 'c-id'])
1471
1472
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1473
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2456.2.2 by John Arbash Meinel
Add another (failing) test case.
1474
1475
        expected = sorted([
1476
            self.deleted(tree1, 'b-id'),
1477
            self.unversioned(tree2, 'b'),
1478
            ])
1479
        self.assertEqual(expected,
1480
                         self.do_iter_changes(tree1, tree2,
1481
                                              want_unversioned=True))
2456.2.5 by John Arbash Meinel
Make sure the output with want_unversioned=False is reasonable.
1482
        expected = sorted([
1483
            self.deleted(tree1, 'b-id'),
1484
            ])
1485
        self.assertEqual(expected,
1486
                         self.do_iter_changes(tree1, tree2,
1487
                                              want_unversioned=False))
2465.1.1 by John Arbash Meinel
Add a (failing) test exposing the bug in _iter_changes
1488
1489
    def test_renamed_and_added(self):
1490
        """Test when we have renamed a file, and put another in its place."""
1491
        tree1 = self.make_branch_and_tree('tree1')
1492
        tree2 = self.make_to_branch_and_tree('tree2')
1493
        root_id = tree1.get_root_id()
1494
        tree2.set_root_id(root_id)
1495
1496
        # The final changes are:
1497
        # bzr add b c
1498
        # bzr mv b a
1499
        # bzr mv c d
1500
        # bzr add b c
1501
1502
        self.build_tree_contents([
1503
            ('tree1/b', 'b contents\n'),
1504
            ('tree1/c', 'c contents\n'),
1505
            ('tree2/a', 'b contents\n'),
1506
            ('tree2/b', 'new b contents\n'),
1507
            ('tree2/c', 'new c contents\n'),
1508
            ('tree2/d', 'c contents\n'),
1509
            ])
1510
        tree1.add(['b', 'c'], ['b1-id', 'c1-id'])
1511
        tree2.add(['a', 'b', 'c', 'd'], ['b1-id', 'b2-id', 'c2-id', 'c1-id'])
1512
1513
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1514
1515
        expected = sorted([
1516
            self.renamed(tree1, tree2, 'b1-id', False),
1517
            self.renamed(tree1, tree2, 'c1-id', False),
1518
            self.added(tree2, 'b2-id'),
1519
            self.added(tree2, 'c2-id'),
1520
            ])
1521
        self.assertEqual(expected,
1522
                         self.do_iter_changes(tree1, tree2,
1523
                                              want_unversioned=True))
2472.3.1 by John Arbash Meinel
Fix bug #111288. When we don't have a match
1524
1525
    def test_renamed_and_unknown(self):
1526
        """A file was moved on the filesystem, but not in bzr."""
1527
        tree1 = self.make_branch_and_tree('tree1')
1528
        tree2 = self.make_to_branch_and_tree('tree2')
1529
        root_id = tree1.get_root_id()
1530
        tree2.set_root_id(root_id)
1531
1532
        # The final changes are:
1533
        # bzr add a b
1534
        # mv a a2
1535
1536
        self.build_tree_contents([
1537
            ('tree1/a', 'a contents\n'),
1538
            ('tree1/b', 'b contents\n'),
1539
            ('tree2/a', 'a contents\n'),
1540
            ('tree2/b', 'b contents\n'),
1541
            ])
1542
        tree1.add(['a', 'b'], ['a-id', 'b-id'])
1543
        tree2.add(['a', 'b'], ['a-id', 'b-id'])
1544
        os.rename('tree2/a', 'tree2/a2')
1545
1546
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1547
        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
1548
1549
        expected = sorted([
1550
            self.missing('a-id', 'a', 'a', tree2.get_root_id(), 'file'),
1551
            self.unversioned(tree2, 'a2'),
1552
            ])
1553
        self.assertEqual(expected,
1554
                         self.do_iter_changes(tree1, tree2,
1555
                                              want_unversioned=True))