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