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