/brz/remove-bazaar

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