/brz/remove-bazaar

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