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