/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2052.3.2 by John Arbash Meinel
Change Copyright .. by Canonical to Copyright ... Canonical
1
# Copyright (C) 2006 Canonical Ltd
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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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
1852.9.5 by Robert Collins
Add tests for require_versioned to the InterTree.compare() test suite.
22
from bzrlib import errors
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
23
from bzrlib.osutils import file_kind
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
24
from bzrlib.tests.intertree_implementations import TestCaseWithTwoTrees
25
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
26
# TODO: test diff unversioned dir that exists
27
# TODO: test the include_root option.
28
# TODO: test that renaming a directory x->y does not emit a rename for the
29
#       child x/a->y/a.
30
# TODO: test that renaming a directory x-> does not emit a rename for the child
31
#        x/a -> y/a when a supplied_files argument gives either 'x/' or 'y/a'
32
#        -> that is, when the renamed parent is not processed by the function.
33
# TODO: include dangling in the diff output.
34
# TODO: test items are only emitted once when a specific_files list names a dir
35
#       whose parent is now a child.
36
# TODO: test require_versioned
2255.2.151 by Robert Collins
Handle specific_files natively for WorkingTreeFormat4._iter_changes.
37
# TODO: explicitly test specific_files listing a non-dir, and listing a symlink
38
#       (it should not follow the link)
39
# TODO: test specific_files when the target tree has a file and the source a
40
#       dir with children, same id and same path. 
41
# TODO: test specific_files with a new unversioned path.
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
42
43
class TestCompare(TestCaseWithTwoTrees):
44
45
    def test_compare_empty_trees(self):
46
        tree1 = self.make_branch_and_tree('1')
47
        tree2 = self.make_to_branch_and_tree('2')
48
        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.
49
        tree2 = self.get_tree_no_parents_no_content(tree2)
50
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
51
        d = self.intertree_class(tree1, tree2).compare()
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
52
        self.assertEqual([], d.added)
53
        self.assertEqual([], d.modified)
54
        self.assertEqual([], d.removed)
55
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
56
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
57
58
    def test_empty_to_abc_content(self):
59
        tree1 = self.make_branch_and_tree('1')
60
        tree2 = self.make_to_branch_and_tree('2')
61
        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.
62
        tree2 = self.get_tree_no_parents_abc_content(tree2)
63
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
64
        d = self.intertree_class(tree1, tree2).compare()
65
        self.assertEqual([('a', 'a-id', 'file'),
66
                          ('b', 'b-id', 'directory'),
67
                          ('b/c', 'c-id', 'file'),
68
                         ], d.added)
69
        self.assertEqual([], d.modified)
70
        self.assertEqual([], d.removed)
71
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
72
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
73
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
74
    def test_dangling(self):
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
75
        # This test depends on the ability for some trees to have a difference
76
        # between a 'versioned present' and 'versioned not present' (aka
77
        # dangling) file. In this test there are two trees each with a separate
78
        # dangling file, and the dangling files should be considered absent for
79
        # the test.
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
80
        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.
81
        tree2 = self.make_to_branch_and_tree('2')
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
82
        self.build_tree(['2/a'])
83
        tree2.add('a')
84
        os.unlink('2/a')
85
        self.build_tree(['1/b'])
86
        tree1.add('b')
87
        os.unlink('1/b')
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
88
        # the conversion to test trees here will leave the trees intact for the
89
        # default intertree, but may perform a commit for other tree types,
90
        # which may reduce the validity of the test. XXX: Think about how to
91
        # address this.
92
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
93
        d = self.intertree_class(tree1, tree2).compare()
94
        self.assertEqual([], d.added)
95
        self.assertEqual([], d.modified)
96
        self.assertEqual([], d.removed)
97
        self.assertEqual([], d.renamed)
98
        self.assertEqual([], d.unchanged)
99
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
100
    def test_abc_content_to_empty(self):
101
        tree1 = self.make_branch_and_tree('1')
102
        tree2 = self.make_to_branch_and_tree('2')
103
        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.
104
        tree2 = self.get_tree_no_parents_no_content(tree2)
105
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
106
        d = self.intertree_class(tree1, tree2).compare()
107
        self.assertEqual([], d.added)
108
        self.assertEqual([], d.modified)
109
        self.assertEqual([('a', 'a-id', 'file'),
110
                          ('b', 'b-id', 'directory'),
111
                          ('b/c', 'c-id', 'file'),
112
                         ], d.removed)
113
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
114
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
115
116
    def test_content_modification(self):
117
        tree1 = self.make_branch_and_tree('1')
118
        tree2 = self.make_to_branch_and_tree('2')
119
        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.
120
        tree2 = self.get_tree_no_parents_abc_content_2(tree2)
121
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
122
        d = self.intertree_class(tree1, tree2).compare()
123
        self.assertEqual([], d.added)
124
        self.assertEqual([('a', 'a-id', 'file', True, False)], d.modified)
125
        self.assertEqual([], d.removed)
126
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
127
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
128
        
129
    def test_meta_modification(self):
130
        tree1 = self.make_branch_and_tree('1')
131
        tree2 = self.make_to_branch_and_tree('2')
132
        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.
133
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
134
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
135
        d = self.intertree_class(tree1, tree2).compare()
136
        self.assertEqual([], d.added)
137
        self.assertEqual([('b/c', 'c-id', 'file', False, True)], d.modified)
138
        self.assertEqual([], d.removed)
139
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
140
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
141
142
    def test_file_rename(self):
143
        tree1 = self.make_branch_and_tree('1')
144
        tree2 = self.make_to_branch_and_tree('2')
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_4(tree2)
147
        tree1, tree2 = self.mutable_trees_to_test_trees(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([], d.modified)
151
        self.assertEqual([], d.removed)
152
        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=...).
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_and_modification(self):
156
        tree1 = self.make_branch_and_tree('1')
157
        tree2 = self.make_to_branch_and_tree('2')
158
        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.
159
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
160
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
161
        d = self.intertree_class(tree1, tree2).compare()
162
        self.assertEqual([], d.added)
163
        self.assertEqual([], d.modified)
164
        self.assertEqual([], d.removed)
165
        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=...).
166
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
167
168
    def test_file_rename_and_meta_modification(self):
169
        tree1 = self.make_branch_and_tree('1')
170
        tree2 = self.make_to_branch_and_tree('2')
171
        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.
172
        tree2 = self.get_tree_no_parents_abc_content_6(tree2)
173
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
174
        d = self.intertree_class(tree1, tree2).compare()
175
        self.assertEqual([], d.added)
176
        self.assertEqual([], d.modified)
177
        self.assertEqual([], d.removed)
178
        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=...).
179
        self.assertEqual([], d.unchanged)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
180
181
    def test_empty_to_abc_content_a_only(self):
182
        tree1 = self.make_branch_and_tree('1')
183
        tree2 = self.make_to_branch_and_tree('2')
184
        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.
185
        tree2 = self.get_tree_no_parents_abc_content(tree2)
186
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
187
        d = self.intertree_class(tree1, tree2).compare(specific_files=['a'])
188
        self.assertEqual([('a', 'a-id', 'file')], d.added)
189
        self.assertEqual([], d.modified)
190
        self.assertEqual([], d.removed)
191
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
192
        self.assertEqual([], d.unchanged)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
193
194
    def test_empty_to_abc_content_a_and_c_only(self):
195
        tree1 = self.make_branch_and_tree('1')
196
        tree2 = self.make_to_branch_and_tree('2')
197
        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.
198
        tree2 = self.get_tree_no_parents_abc_content(tree2)
199
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
200
        d = self.intertree_class(tree1, tree2).compare(
201
            specific_files=['a', 'b/c'])
202
        self.assertEqual(
203
            [('a', 'a-id', 'file'), ('b/c', 'c-id', 'file')],
204
            d.added)
205
        self.assertEqual([], d.modified)
206
        self.assertEqual([], d.removed)
207
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
208
        self.assertEqual([], d.unchanged)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
209
210
    def test_empty_to_abc_content_b_only(self):
211
        """Restricting to a dir matches the children of the dir."""
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)
216
        tree1, tree2 = self.mutable_trees_to_test_trees(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(specific_files=['b'])
218
        self.assertEqual(
219
            [('b', 'b-id', 'directory'),('b/c', 'c-id', 'file')],
220
            d.added)
221
        self.assertEqual([], d.modified)
222
        self.assertEqual([], d.removed)
223
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
224
        self.assertEqual([], d.unchanged)
225
226
    def test_unchanged_with_renames_and_modifications(self):
227
        """want_unchanged should generate a list of unchanged entries."""
228
        tree1 = self.make_branch_and_tree('1')
229
        tree2 = self.make_to_branch_and_tree('2')
230
        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.
231
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
232
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
233
        d = self.intertree_class(tree1, tree2).compare(want_unchanged=True)
234
        self.assertEqual([], d.added)
235
        self.assertEqual([], d.modified)
236
        self.assertEqual([], d.removed)
237
        self.assertEqual([('a', 'd', 'a-id', 'file', True, False)], d.renamed)
238
        self.assertEqual(
239
            [(u'b', 'b-id', 'directory'), (u'b/c', 'c-id', 'file')],
240
            d.unchanged)
241
242
    def test_extra_trees_finds_ids(self):
243
        """Ask for a delta between two trees with a path present in a third."""
244
        tree1 = self.make_branch_and_tree('1')
245
        tree2 = self.make_to_branch_and_tree('2')
246
        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.
247
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
248
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
249
        d = self.intertree_class(tree1, tree2).compare(specific_files=['b'])
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
250
        # 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.
251
        # a dispatch. XXX: For dirstate it does speak to the optimisability of
252
        # the lookup, in merged trees it can be fast-pathed. We probably want
253
        # 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=...).
254
        tree3 = self.make_branch_and_tree('3')
255
        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.
256
        tree3.lock_read()
257
        self.addCleanup(tree3.unlock)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
258
        # tree 3 has 'e' which is 'c-id'. Tree 1 has c-id at b/c, and Tree 2
259
        # has c-id at b/c with its exec flag toggled.
260
        # without extra_trees, we should get no modifications from this
261
        # so do one, to be sure the test is valid.
262
        d = self.intertree_class(tree1, tree2).compare(
263
            specific_files=['e'])
264
        self.assertEqual([], d.modified)
265
        # now give it an additional lookup:
266
        d = self.intertree_class(tree1, tree2).compare(
267
            specific_files=['e'], extra_trees=[tree3])
268
        self.assertEqual([], d.added)
269
        self.assertEqual([('b/c', 'c-id', 'file', False, True)], d.modified)
270
        self.assertEqual([], d.removed)
271
        self.assertEqual([], d.renamed)
272
        self.assertEqual([], d.unchanged)
1852.9.5 by Robert Collins
Add tests for require_versioned to the InterTree.compare() test suite.
273
274
    def test_require_versioned(self):
275
        # this does not quite robustly test, as it is passing in missing paths
276
        # rather than present-but-not-versioned paths. At the moment there is
277
        # no mechanism for managing the test trees (which are readonly) to 
278
        # get present-but-not-versioned files for trees that can do that.
279
        tree1 = self.make_branch_and_tree('1')
280
        tree2 = self.make_to_branch_and_tree('2')
281
        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.
282
        tree2 = self.get_tree_no_parents_abc_content(tree2)
283
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
1852.9.5 by Robert Collins
Add tests for require_versioned to the InterTree.compare() test suite.
284
        self.assertRaises(errors.PathsNotVersionedError, 
285
            self.intertree_class(tree1, tree2).compare,
286
            specific_files=['d'],
287
            require_versioned=True)
2012.1.1 by Aaron Bentley
Implement change iterator
288
289
2012.1.3 by Aaron Bentley
Always generate tuples (because kind is always used, even when not different)
290
class TestIterChanges(TestCaseWithTwoTrees):
2012.1.1 by Aaron Bentley
Implement change iterator
291
    """Test the comparison iterator"""
292
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
293
    def do_iter_changes(self, tree1, tree2, **extra_args):
294
        """Helper to run _iter_changes from tree1 to tree2.
295
        
296
        :param tree1, tree2:  The source and target trees. These will be locked
297
            automatically.
298
        :param **extra_args: Extra args to pass to _iter_changes. This is not
299
            inspected by this test helper.
300
        """
301
        tree1.lock_read()
302
        tree2.lock_read()
303
        try:
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
304
            # sort order of output is not strictly defined
305
            return sorted(self.intertree_class(tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
306
                ._iter_changes(**extra_args))
307
        finally:
308
            tree1.unlock()
309
            tree2.unlock()
310
2012.1.1 by Aaron Bentley
Implement change iterator
311
    def test_compare_empty_trees(self):
312
        tree1 = self.make_branch_and_tree('1')
313
        tree2 = self.make_to_branch_and_tree('2')
314
        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.
315
        tree2 = self.get_tree_no_parents_no_content(tree2)
316
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
317
        self.assertEqual([], self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
318
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
319
    def added(self, tree, file_id):
320
        entry = tree.inventory[file_id]
321
        path = tree.id2path(file_id)
322
        return (file_id, 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.
323
                (None, entry.name), (None, entry.kind),
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
324
                (None, entry.executable))
325
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.
326
    def content_changed(self, tree, file_id):
327
        entry = tree.inventory[file_id]
328
        path = tree.id2path(file_id)
329
        return (file_id, path, True, (True, True), (entry.parent_id, entry.parent_id),
330
                (entry.name, entry.name), (entry.kind, entry.kind),
331
                (entry.executable, entry.executable))
332
333
    def kind_changed(self, from_tree, to_tree, file_id):
334
        old_entry = from_tree.inventory[file_id]
335
        new_entry = to_tree.inventory[file_id]
336
        path = to_tree.id2path(file_id)
337
        return (file_id, path, True, (True, True), (old_entry.parent_id, new_entry.parent_id),
338
                (old_entry.name, new_entry.name), (old_entry.kind, new_entry.kind),
339
                (old_entry.executable, new_entry.executable))
340
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
341
    def missing(self, file_id, path, parent_id, kind):
342
        _, basename = os.path.split(path)
343
        return (file_id, path, True, (True, True), (parent_id, parent_id),
344
            (basename, basename), (kind, None), (False, False))
345
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
346
    def deleted(self, tree, file_id):
347
        entry = tree.inventory[file_id]
348
        path = tree.id2path(file_id)
349
        return (file_id, path, 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.
350
                (entry.name, None), (entry.kind, None),
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
351
                (entry.executable, None))
352
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.
353
    def unchanged(self, tree, file_id):
354
        entry = tree.inventory[file_id]
355
        parent = entry.parent_id
356
        name = entry.name
357
        kind = entry.kind
358
        executable = entry.executable
359
        return (file_id, tree.id2path(file_id), False, (True, True),
360
               (parent, parent), (name, name), (kind, kind),
361
               (executable, executable))
362
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
363
    def unversioned(self, tree, path):
364
        """Create an unversioned result."""
365
        _, basename = os.path.split(path)
366
        kind = file_kind(tree.abspath(path))
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
367
        return (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.
368
                (None, basename), (None, kind),
369
                (None, False))
370
2012.1.1 by Aaron Bentley
Implement change iterator
371
    def test_empty_to_abc_content(self):
372
        tree1 = self.make_branch_and_tree('1')
373
        tree2 = self.make_to_branch_and_tree('2')
374
        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.
375
        tree2 = self.get_tree_no_parents_abc_content(tree2)
376
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
2255.2.118 by Robert Collins
Change _iter_changes tests to lock the tested trees - its an iterator interface so implicit locks dont ensure the tree is locked - callers need to lock and thus so do our tests.
377
        tree1.lock_read()
378
        tree2.lock_read()
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
379
        expected_results = sorted([
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
380
            self.added(tree2, 'root-id'),
381
            self.added(tree2, 'a-id'),
382
            self.added(tree2, 'b-id'),
383
            self.added(tree2, 'c-id'),
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
384
            self.deleted(tree1, 'empty-root-id')])
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
385
        tree1.unlock()
386
        tree2.unlock()
387
        self.assertEqual(expected_results, self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
388
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
389
    def test_empty_to_abc_content_a_only(self):
390
        tree1 = self.make_branch_and_tree('1')
391
        tree2 = self.make_to_branch_and_tree('2')
392
        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.
393
        tree2 = self.get_tree_no_parents_abc_content(tree2)
394
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
395
        tree1.lock_read()
396
        tree2.lock_read()
397
        self.assertEqual(
398
            [self.added(tree2, 'a-id')],
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
399
            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.
400
        tree1.unlock()
401
        tree2.unlock()
402
403
    def test_abc_content_to_empty_to_abc_content_a_only(self):
404
        tree1 = self.make_branch_and_tree('1')
405
        tree2 = self.make_to_branch_and_tree('2')
406
        tree1 = self.get_tree_no_parents_abc_content(tree1)
407
        tree2 = self.get_tree_no_parents_no_content(tree2)
408
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
409
        tree1.lock_read()
410
        tree2.lock_read()
411
        self.assertEqual(
412
            [self.deleted(tree1, 'a-id')],
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
413
            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.
414
        tree1.unlock()
415
        tree2.unlock()
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
416
417
    def test_empty_to_abc_content_a_and_c_only(self):
418
        tree1 = self.make_branch_and_tree('1')
419
        tree2 = self.make_to_branch_and_tree('2')
420
        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.
421
        tree2 = self.get_tree_no_parents_abc_content(tree2)
422
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
2255.2.118 by Robert Collins
Change _iter_changes tests to lock the tested trees - its an iterator interface so implicit locks dont ensure the tree is locked - callers need to lock and thus so do our tests.
423
        tree1.lock_read()
424
        tree2.lock_read()
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
425
        expected_result = [self.added(tree2, 'a-id'), self.added(tree2, 'c-id')]
426
        tree1.unlock()
427
        tree2.unlock()
428
        self.assertEqual(expected_result,
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
429
            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
430
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
431
    def test_abc_content_to_empty(self):
2012.1.1 by Aaron Bentley
Implement change iterator
432
        tree1 = self.make_branch_and_tree('1')
433
        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.
434
        tree1 = self.get_tree_no_parents_abc_content(tree1)
435
        tree2 = self.get_tree_no_parents_no_content(tree2)
436
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
437
        tree1.lock_read()
438
        tree2.lock_read()
2012.1.1 by Aaron Bentley
Implement change iterator
439
        def deleted(file_id):
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
440
            entry = tree1.inventory[file_id]
441
            path = tree1.id2path(file_id)
442
            return (file_id, path, True, (True, False),
2012.1.1 by Aaron Bentley
Implement change iterator
443
                    (entry.parent_id, None),
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
444
                    (entry.name, None), (entry.kind, None),
2012.1.1 by Aaron Bentley
Implement change iterator
445
                    (entry.executable, None))
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
446
        expected_results = sorted([self.added(tree2, 'empty-root-id'),
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
447
                          deleted('root-id'), deleted('a-id'),
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
448
                          deleted('b-id'), deleted('c-id')])
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
449
        tree1.unlock()
450
        tree2.unlock()
451
        self.assertEqual(
452
            expected_results,
453
            self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
454
455
    def test_content_modification(self):
456
        tree1 = self.make_branch_and_tree('1')
457
        tree2 = self.make_to_branch_and_tree('2')
458
        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.
459
        tree2 = self.get_tree_no_parents_abc_content_2(tree2)
460
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
461
        root_id = tree1.path2id('')
462
        self.assertEqual([('a-id', 'a', True, (True, True),
463
                          (root_id, root_id), ('a', 'a'),
464
                          ('file', 'file'), (False, False))],
465
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
466
467
    def test_meta_modification(self):
468
        tree1 = self.make_branch_and_tree('1')
469
        tree2 = self.make_to_branch_and_tree('2')
470
        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.
471
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
472
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
473
        self.assertEqual([('c-id', 'b/c', False, (True, True),
474
                          ('b-id', 'b-id'), ('c', 'c'), ('file', 'file'),
475
                          (False, True))],
476
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
477
2255.7.6 by Robert Collins
Test for iterating changes past empty directories.
478
    def test_empty_dir(self):
479
        """an empty dir should not cause glitches to surrounding files."""
480
        tree1 = self.make_branch_and_tree('1')
481
        tree2 = self.make_to_branch_and_tree('2')
482
        tree1 = self.get_tree_no_parents_abc_content(tree1)
483
        tree2 = self.get_tree_no_parents_abc_content(tree2)
484
        # the pathname is chosen to fall between 'a' and 'b'.
485
        self.build_tree(['1/a-empty/', '2/a-empty/'])
486
        tree1.add(['a-empty'], ['a-empty'])
487
        tree2.add(['a-empty'], ['a-empty'])
488
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
489
        expected = []
490
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
491
2012.1.1 by Aaron Bentley
Implement change iterator
492
    def test_file_rename(self):
493
        tree1 = self.make_branch_and_tree('1')
494
        tree2 = self.make_to_branch_and_tree('2')
495
        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.
496
        tree2 = self.get_tree_no_parents_abc_content_4(tree2)
497
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
498
        root_id = tree1.path2id('')
499
        self.assertEqual([('a-id', 'd', False, (True, True),
2012.1.3 by Aaron Bentley
Always generate tuples (because kind is always used, even when not different)
500
                          (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.
501
                          (False, False))],
502
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
503
504
    def test_file_rename_and_modification(self):
505
        tree1 = self.make_branch_and_tree('1')
506
        tree2 = self.make_to_branch_and_tree('2')
507
        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.
508
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
509
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
510
        root_id = tree1.path2id('')
511
        self.assertEqual([('a-id', 'd', True, (True, True),
2012.1.3 by Aaron Bentley
Always generate tuples (because kind is always used, even when not different)
512
                          (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.
513
                           (False, False))],
514
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
515
516
    def test_file_rename_and_meta_modification(self):
517
        tree1 = self.make_branch_and_tree('1')
518
        tree2 = self.make_to_branch_and_tree('2')
519
        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.
520
        tree2 = self.get_tree_no_parents_abc_content_6(tree2)
521
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
522
        root_id = tree1.path2id('')
523
        self.assertEqual([('c-id', 'e', False, (True, True),
524
                          ('b-id', root_id), ('c', 'e'), ('file', 'file'),
525
                          (False, True))],
526
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
527
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
528
    def test_missing_in_target(self):
529
        """Test with the target files versioned but absent from disk."""
530
        tree1 = self.make_branch_and_tree('1')
531
        tree2 = self.make_to_branch_and_tree('2')
532
        tree1 = self.get_tree_no_parents_abc_content(tree1)
533
        tree2 = self.get_tree_no_parents_abc_content(tree2)
534
        os.unlink('2/a')
535
        shutil.rmtree('2/b')
536
        # TODO ? have a symlink here?
537
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
538
        root_id = tree1.path2id('')
539
        expected = sorted([
540
            self.missing('a-id', 'a', root_id, 'file'),
541
            self.missing('b-id', 'b', root_id, 'directory'),
542
            self.missing('c-id', 'b/c', 'b-id', 'file'),
543
            ])
544
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
545
2012.1.1 by Aaron Bentley
Implement change iterator
546
    def test_unchanged_with_renames_and_modifications(self):
547
        """want_unchanged should generate a list of unchanged entries."""
548
        tree1 = self.make_branch_and_tree('1')
549
        tree2 = self.make_to_branch_and_tree('2')
550
        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.
551
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
552
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
553
        root_id = tree1.path2id('')
2255.2.118 by Robert Collins
Change _iter_changes tests to lock the tested trees - its an iterator interface so implicit locks dont ensure the tree is locked - callers need to lock and thus so do our tests.
554
        tree1.lock_read()
555
        self.addCleanup(tree1.unlock)
556
        tree2.lock_read()
557
        self.addCleanup(tree2.unlock)
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.
558
        self.assertEqual(sorted([self.unchanged(tree1, root_id),
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
559
            self.unchanged(tree1, 'b-id'), ('a-id', 'd', True, (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.
560
            (root_id, root_id), ('a', 'd'), ('file', 'file'),
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
561
            (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.
562
            self.do_iter_changes(tree1, tree2, include_unchanged=True))
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
563
564
    def _todo_test_unversioned_paths_in_tree(self):
565
        tree1 = self.make_branch_and_tree('tree1')
566
        tree2 = self.make_to_branch_and_tree('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.
567
        self.build_tree(['tree2/file', 'tree2/dir/'])
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
568
        # try:
569
        os.symlink('target', 'tree2/link')
570
        links_supported = True
571
        # except ???:
572
        #   links_supported = False
573
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
574
        root_id = tree1.path2id('')
575
        tree1.lock_read()
576
        self.addCleanup(tree1.unlock)
577
        tree2.lock_read()
578
        self.addCleanup(tree2.unlock)
579
        expected = [
580
            self.unversioned(tree2, 'file'),
581
            self.unversioned(tree2, 'dir'),
582
            ]
583
        if links_supported:
584
            expected.append(self.unversioned(tree2, 'link'))
585
        expected = sorted(expected)
586
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
587
588
    def _todo_test_unversioned_paths_in_tree_specific_files(self):
589
        tree1 = self.make_branch_and_tree('tree1')
590
        tree2 = self.make_to_branch_and_tree('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.
591
        self.build_tree(['tree2/file', 'tree2/dir/'])
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
592
        # try:
593
        os.symlink('target', 'tree2/link')
594
        links_supported = True
595
        # except ???:
596
        #   links_supported = False
597
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
598
        root_id = tree1.path2id('')
599
        tree1.lock_read()
600
        self.addCleanup(tree1.unlock)
601
        tree2.lock_read()
602
        self.addCleanup(tree2.unlock)
603
        expected = [
604
            self.unversioned(tree2, 'file'),
605
            self.unversioned(tree2, 'dir'),
606
            ]
607
        specific_files=['file', 'dir']
608
        if links_supported:
609
            expected.append(self.unversioned(tree2, 'link'))
610
            specific_files.append('link')
611
        expected = sorted(expected)
612
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
613
            specific_files=specific_files))
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.
614
615
    def make_trees_with_symlinks(self):
616
        tree1 = self.make_branch_and_tree('tree1')
617
        tree2 = self.make_to_branch_and_tree('tree2')
618
        self.build_tree(['tree1/fromfile', 'tree1/fromdir/'])
619
        self.build_tree(['tree2/tofile', 'tree2/todir/', 'tree2/unknown'])
620
        # try:
621
        os.symlink('original', 'tree1/changed')
622
        os.symlink('original', 'tree1/removed')
623
        os.symlink('original', 'tree1/tofile')
624
        os.symlink('original', 'tree1/todir')
625
        # we make the unchanged link point at unknown to catch incorrect
626
        # symlink-following code in the specified_files test.
627
        os.symlink('unknown', 'tree1/unchanged')
628
        os.symlink('new',      'tree2/added')
629
        os.symlink('new',      'tree2/changed')
630
        os.symlink('new',      'tree2/fromfile')
631
        os.symlink('new',      'tree2/fromdir')
632
        os.symlink('unknown', 'tree2/unchanged')
633
        from_paths_and_ids = [
634
            'fromdir',
635
            'fromfile',
636
            'changed',
637
            'removed',
638
            'todir',
639
            'tofile',
640
            'unchanged',
641
            ]
642
        to_paths_and_ids = [
643
            'added',
644
            'fromdir',
645
            'fromfile',
646
            'changed',
647
            'todir',
648
            'tofile',
649
            'unchanged',
650
            ]
651
        tree1.add(from_paths_and_ids, from_paths_and_ids)
652
        tree2.add(to_paths_and_ids, to_paths_and_ids)
653
        # except ???:
654
        #   raise TestSkipped('OS does not support symlinks')
655
        #   links_supported = False
656
        return self.mutable_trees_to_test_trees(tree1, tree2)
657
658
    def _disabled_test_versioned_symlinks(self):
659
        tree1, tree2 = self.make_trees_with_symlinks()
660
        root_id = tree1.path2id('')
661
        tree1.lock_read()
662
        self.addCleanup(tree1.unlock)
663
        tree2.lock_read()
664
        self.addCleanup(tree2.unlock)
665
        expected = [
666
            self.unchanged(tree1, tree1.path2id('')),
667
            self.added(tree2, 'added'),
668
            self.content_changed(tree2, 'changed'),
669
            self.kind_changed(tree1, tree2, 'fromdir'),
670
            self.kind_changed(tree1, tree2, 'fromfile'),
671
            self.deleted(tree1, 'removed'),
672
            self.unchanged(tree2, 'unchanged'),
673
            self.unversioned(tree2, 'unknown'),
674
            self.kind_changed(tree1, tree2, 'todir'),
675
            self.kind_changed(tree1, tree2, 'tofile'),
676
            ]
677
        expected = sorted(expected)
678
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2, include_unchanged=True))
679
680
    def _disabled_test_versioned_symlinks_specific_files(self):
681
        tree1, tree2 = self.make_trees_with_symlinks()
682
        root_id = tree1.path2id('')
683
        tree1.lock_read()
684
        self.addCleanup(tree1.unlock)
685
        tree2.lock_read()
686
        self.addCleanup(tree2.unlock)
687
        expected = [
688
            self.added(tree2, 'added'),
689
            self.content_changed(tree2, 'changed'),
690
            self.kind_changed(tree1, tree2, 'fromdir'),
691
            self.kind_changed(tree1, tree2, 'fromfile'),
692
            self.deleted(tree1, 'removed'),
693
            self.kind_changed(tree1, tree2, 'todir'),
694
            self.kind_changed(tree1, tree2, 'tofile'),
695
            ]
696
        expected = sorted(expected)
697
        # we should get back just the changed links. We pass in 'unchanged' to
698
        # make sure that it is correctly not returned - and neither is the
699
        # unknown path 'unknown' which it points at.
700
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
701
            specific_files=['added', 'changed', 'fromdir', 'fromfile',
702
            'removed', 'unchanged', 'todir', 'tofile']))