/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/intertree_implementations/test_compare.py

merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""Tests for the InterTree.compare() function."""
18
18
 
19
19
import os
20
20
import shutil
21
21
 
22
 
from bzrlib import errors, tests, workingtree_4
 
22
from bzrlib import (
 
23
    errors,
 
24
    tests,
 
25
    workingtree_4,
 
26
    )
23
27
from bzrlib.osutils import file_kind, has_symlinks
 
28
from bzrlib.tests import TestNotApplicable
24
29
from bzrlib.tests.intertree_implementations import TestCaseWithTwoTrees
25
30
 
26
31
# TODO: test the include_root option.
32
37
# TODO: test items are only emitted once when a specific_files list names a dir
33
38
#       whose parent is now a child.
34
39
# TODO: test specific_files when the target tree has a file and the source a
35
 
#       dir with children, same id and same path. 
 
40
#       dir with children, same id and same path.
36
41
# TODO: test comparisons between trees with different root ids. mbp 20070301
37
42
#
38
43
# TODO: More comparisons between trees with subtrees in different states.
49
54
        tree2.set_root_id(tree1.get_root_id())
50
55
        tree1 = self.get_tree_no_parents_no_content(tree1)
51
56
        tree2 = self.get_tree_no_parents_no_content(tree2)
52
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
57
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
53
58
        d = self.intertree_class(tree1, tree2).compare()
54
59
        self.assertEqual([], d.added)
55
60
        self.assertEqual([], d.modified)
63
68
        tree2.set_root_id(tree1.get_root_id())
64
69
        tree1 = self.get_tree_no_parents_no_content(tree1)
65
70
        tree2 = self.get_tree_no_parents_abc_content(tree2)
66
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
71
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
67
72
        d = self.intertree_class(tree1, tree2).compare()
68
73
        self.assertEqual([('a', 'a-id', 'file'),
69
74
                          ('b', 'b-id', 'directory'),
93
98
        # default intertree, but may perform a commit for other tree types,
94
99
        # which may reduce the validity of the test. XXX: Think about how to
95
100
        # address this.
96
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
101
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
97
102
        d = self.intertree_class(tree1, tree2).compare()
98
103
        self.assertEqual([], d.added)
99
104
        self.assertEqual([], d.modified)
107
112
        tree2.set_root_id(tree1.get_root_id())
108
113
        tree1 = self.get_tree_no_parents_abc_content(tree1)
109
114
        tree2 = self.get_tree_no_parents_no_content(tree2)
110
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
115
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
111
116
        d = self.intertree_class(tree1, tree2).compare()
112
117
        self.assertEqual([], d.added)
113
118
        self.assertEqual([], d.modified)
124
129
        tree2.set_root_id(tree1.get_root_id())
125
130
        tree1 = self.get_tree_no_parents_abc_content(tree1)
126
131
        tree2 = self.get_tree_no_parents_abc_content_2(tree2)
127
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
132
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
128
133
        d = self.intertree_class(tree1, tree2).compare()
129
134
        self.assertEqual([], d.added)
130
135
        self.assertEqual([('a', 'a-id', 'file', True, False)], d.modified)
131
136
        self.assertEqual([], d.removed)
132
137
        self.assertEqual([], d.renamed)
133
138
        self.assertEqual([], d.unchanged)
134
 
        
 
139
 
135
140
    def test_meta_modification(self):
136
141
        tree1 = self.make_branch_and_tree('1')
137
142
        tree2 = self.make_to_branch_and_tree('2')
138
143
        tree2.set_root_id(tree1.get_root_id())
139
144
        tree1 = self.get_tree_no_parents_abc_content(tree1)
140
145
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
141
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
146
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
142
147
        d = self.intertree_class(tree1, tree2).compare()
143
148
        self.assertEqual([], d.added)
144
149
        self.assertEqual([('b/c', 'c-id', 'file', False, True)], d.modified)
152
157
        tree2.set_root_id(tree1.get_root_id())
153
158
        tree1 = self.get_tree_no_parents_abc_content(tree1)
154
159
        tree2 = self.get_tree_no_parents_abc_content_4(tree2)
155
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
160
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
156
161
        d = self.intertree_class(tree1, tree2).compare()
157
162
        self.assertEqual([], d.added)
158
163
        self.assertEqual([], d.modified)
166
171
        tree2.set_root_id(tree1.get_root_id())
167
172
        tree1 = self.get_tree_no_parents_abc_content(tree1)
168
173
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
169
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
174
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
170
175
        d = self.intertree_class(tree1, tree2).compare()
171
176
        self.assertEqual([], d.added)
172
177
        self.assertEqual([], d.modified)
180
185
        tree2.set_root_id(tree1.get_root_id())
181
186
        tree1 = self.get_tree_no_parents_abc_content(tree1)
182
187
        tree2 = self.get_tree_no_parents_abc_content_6(tree2)
183
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
188
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
184
189
        d = self.intertree_class(tree1, tree2).compare()
185
190
        self.assertEqual([], d.added)
186
191
        self.assertEqual([], d.modified)
194
199
        tree2.set_root_id(tree1.get_root_id())
195
200
        tree1 = self.get_tree_no_parents_no_content(tree1)
196
201
        tree2 = self.get_tree_no_parents_abc_content(tree2)
197
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
202
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
198
203
        d = self.intertree_class(tree1, tree2).compare(specific_files=['a'])
199
204
        self.assertEqual([('a', 'a-id', 'file')], d.added)
200
205
        self.assertEqual([], d.modified)
207
212
        tree2 = self.make_to_branch_and_tree('2')
208
213
        tree1 = self.get_tree_no_parents_no_content(tree1)
209
214
        tree2 = self.get_tree_no_parents_abc_content(tree2)
210
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
215
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
211
216
        d = self.intertree_class(tree1, tree2).compare(
212
217
            specific_files=['a', 'b/c'])
213
218
        self.assertEqual(
224
229
        tree2 = self.make_to_branch_and_tree('2')
225
230
        tree1 = self.get_tree_no_parents_no_content(tree1)
226
231
        tree2 = self.get_tree_no_parents_abc_content(tree2)
227
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
232
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
228
233
        d = self.intertree_class(tree1, tree2).compare(specific_files=['b'])
229
234
        self.assertEqual(
230
235
            [('b', 'b-id', 'directory'),('b/c', 'c-id', 'file')],
240
245
        tree2 = self.make_to_branch_and_tree('2')
241
246
        tree1 = self.get_tree_no_parents_abc_content(tree1)
242
247
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
243
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
248
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
244
249
        d = self.intertree_class(tree1, tree2).compare(want_unchanged=True)
245
250
        self.assertEqual([], d.added)
246
251
        self.assertEqual([], d.modified)
256
261
        tree2 = self.make_to_branch_and_tree('2')
257
262
        tree1 = self.get_tree_no_parents_abc_content(tree1)
258
263
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
259
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
264
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
260
265
        d = self.intertree_class(tree1, tree2).compare(specific_files=['b'])
261
266
        # the type of tree-3 does not matter - it is used as a lookup, not
262
267
        # a dispatch. XXX: For dirstate it does speak to the optimisability of
285
290
    def test_require_versioned(self):
286
291
        # this does not quite robustly test, as it is passing in missing paths
287
292
        # rather than present-but-not-versioned paths. At the moment there is
288
 
        # no mechanism for managing the test trees (which are readonly) to 
 
293
        # no mechanism for managing the test trees (which are readonly) to
289
294
        # get present-but-not-versioned files for trees that can do that.
290
295
        tree1 = self.make_branch_and_tree('1')
291
296
        tree2 = self.make_to_branch_and_tree('2')
292
297
        tree1 = self.get_tree_no_parents_no_content(tree1)
293
298
        tree2 = self.get_tree_no_parents_abc_content(tree2)
294
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
295
 
        self.assertRaises(errors.PathsNotVersionedError, 
 
299
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
 
300
        self.assertRaises(errors.PathsNotVersionedError,
296
301
            self.intertree_class(tree1, tree2).compare,
297
302
            specific_files=['d'],
298
303
            require_versioned=True)
306
311
        tree1.add(['a', 'c'], ['a-id', 'c-id'])
307
312
        tree2.add(['a', 'c'], ['a-id', 'c-id'])
308
313
 
309
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
314
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
310
315
        d = self.intertree_class(tree1, tree2).compare()
311
316
        self.assertEqual([], d.added)
312
317
        self.assertEqual([(u'a', 'a-id', 'file', True, False),
326
331
            links_supported = True
327
332
        else:
328
333
            links_supported = False
329
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
334
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
 
335
        self.not_applicable_if_cannot_represent_unversioned(tree2)
330
336
        d = self.intertree_class(tree1, tree2).compare(want_unversioned=True)
331
337
        self.assertEqual([], d.added)
332
338
        self.assertEqual([], d.modified)
344
350
    """Test the comparison iterator"""
345
351
 
346
352
    def do_iter_changes(self, tree1, tree2, **extra_args):
347
 
        """Helper to run _iter_changes from tree1 to tree2.
348
 
        
 
353
        """Helper to run iter_changes from tree1 to tree2.
 
354
 
349
355
        :param tree1, tree2:  The source and target trees. These will be locked
350
356
            automatically.
351
 
        :param **extra_args: Extra args to pass to _iter_changes. This is not
 
357
        :param **extra_args: Extra args to pass to iter_changes. This is not
352
358
            inspected by this test helper.
353
359
        """
354
360
        tree1.lock_read()
356
362
        try:
357
363
            # sort order of output is not strictly defined
358
364
            return sorted(self.intertree_class(tree1, tree2)
359
 
                ._iter_changes(**extra_args))
 
365
                .iter_changes(**extra_args))
360
366
        finally:
361
367
            tree1.unlock()
362
368
            tree2.unlock()
366
372
 
367
373
        Read lock them, and add the unlock to the cleanup.
368
374
        """
369
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
375
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
370
376
        tree1.lock_read()
371
377
        self.addCleanup(tree1.unlock)
372
378
        tree2.lock_read()
428
434
        tree2 = self.make_to_branch_and_tree('2')
429
435
        tree1 = self.get_tree_no_parents_no_content(tree1)
430
436
        tree2 = self.get_tree_no_parents_no_content(tree2)
431
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
437
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
432
438
        self.assertEqual([], self.do_iter_changes(tree1, tree2))
433
439
 
434
440
    def added(self, tree, file_id):
435
 
        entry = tree.inventory[file_id]
436
 
        path = tree.id2path(file_id)
 
441
        path, entry = self.get_path_entry(tree, file_id)
437
442
        return (file_id, (None, path), True, (False, True), (None, entry.parent_id),
438
443
                (None, entry.name), (None, entry.kind),
439
444
                (None, entry.executable))
440
445
 
 
446
    @staticmethod
 
447
    def get_path_entry(tree, file_id):
 
448
        iterator = tree.iter_entries_by_dir(specific_file_ids=[file_id])
 
449
        return iterator.next()
 
450
 
441
451
    def content_changed(self, tree, file_id):
442
 
        entry = tree.inventory[file_id]
443
 
        path = tree.id2path(file_id)
444
 
        return (file_id, (path, path), True, (True, True), (entry.parent_id, entry.parent_id),
 
452
        path, entry = self.get_path_entry(tree, file_id)
 
453
        return (file_id, (path, path), True, (True, True),
 
454
                (entry.parent_id, entry.parent_id),
445
455
                (entry.name, entry.name), (entry.kind, entry.kind),
446
456
                (entry.executable, entry.executable))
447
457
 
448
458
    def kind_changed(self, from_tree, to_tree, file_id):
449
 
        old_entry = from_tree.inventory[file_id]
450
 
        new_entry = to_tree.inventory[file_id]
451
 
        path = to_tree.id2path(file_id)
452
 
        from_path = from_tree.id2path(file_id)
453
 
        return (file_id, (from_path, path), True, (True, True), (old_entry.parent_id, new_entry.parent_id),
454
 
                (old_entry.name, new_entry.name), (old_entry.kind, new_entry.kind),
 
459
        from_path, old_entry = self.get_path_entry(from_tree, file_id)
 
460
        path, new_entry = self.get_path_entry(to_tree, file_id)
 
461
        return (file_id, (from_path, path), True, (True, True),
 
462
                (old_entry.parent_id, new_entry.parent_id),
 
463
                (old_entry.name, new_entry.name),
 
464
                (old_entry.kind, new_entry.kind),
455
465
                (old_entry.executable, new_entry.executable))
456
466
 
457
467
    def missing(self, file_id, from_path, to_path, parent_id, kind):
470
480
                (entry.executable, None))
471
481
 
472
482
    def renamed(self, from_tree, to_tree, file_id, content_changed):
473
 
        from_entry = from_tree.inventory[file_id]
474
 
        to_entry = to_tree.inventory[file_id]
475
 
        from_path = from_tree.id2path(file_id)
476
 
        to_path = to_tree.id2path(file_id)
 
483
        from_path, from_entry = self.get_path_entry(from_tree, file_id)
 
484
        to_path, to_entry = self.get_path_entry(to_tree, file_id)
477
485
        return (file_id, (from_path, to_path), content_changed, (True, True),
478
486
            (from_entry.parent_id, to_entry.parent_id),
479
487
            (from_entry.name, to_entry.name),
481
489
            (from_entry.executable, to_entry.executable))
482
490
 
483
491
    def unchanged(self, tree, file_id):
484
 
        entry = tree.inventory[file_id]
 
492
        path, entry = self.get_path_entry(tree, file_id)
485
493
        parent = entry.parent_id
486
494
        name = entry.name
487
495
        kind = entry.kind
488
496
        executable = entry.executable
489
 
        path = tree.id2path(file_id)
490
497
        return (file_id, (path, path), False, (True, True),
491
498
               (parent, parent), (name, name), (kind, kind),
492
499
               (executable, executable))
494
501
    def unversioned(self, tree, path):
495
502
        """Create an unversioned result."""
496
503
        _, basename = os.path.split(path)
497
 
        kind = file_kind(tree.abspath(path))
 
504
        kind = tree._comparison_data(None, path)[0]
498
505
        return (None, (None, path), True, (False, False), (None, None),
499
506
                (None, basename), (None, kind),
500
507
                (None, False))
513
520
            self.deleted(tree1, 'empty-root-id')])
514
521
        self.assertEqual(expected_results, self.do_iter_changes(tree1, tree2))
515
522
 
 
523
    def test_empty_specific_files(self):
 
524
        tree1 = self.make_branch_and_tree('1')
 
525
        tree2 = self.make_to_branch_and_tree('2')
 
526
        tree1 = self.get_tree_no_parents_no_content(tree1)
 
527
        tree2 = self.get_tree_no_parents_abc_content(tree2)
 
528
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
 
529
        self.assertEqual([],
 
530
            self.do_iter_changes(tree1, tree2, specific_files=[]))
 
531
 
 
532
    def test_no_specific_files(self):
 
533
        tree1 = self.make_branch_and_tree('1')
 
534
        tree2 = self.make_to_branch_and_tree('2')
 
535
        tree1 = self.get_tree_no_parents_no_content(tree1)
 
536
        tree2 = self.get_tree_no_parents_abc_content(tree2)
 
537
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
 
538
        expected_results = sorted([
 
539
            self.added(tree2, 'root-id'),
 
540
            self.added(tree2, 'a-id'),
 
541
            self.added(tree2, 'b-id'),
 
542
            self.added(tree2, 'c-id'),
 
543
            self.deleted(tree1, 'empty-root-id')])
 
544
        self.assertEqual(expected_results, self.do_iter_changes(tree1, tree2))
 
545
 
516
546
    def test_empty_to_abc_content_a_only(self):
517
547
        tree1 = self.make_branch_and_tree('1')
518
548
        tree2 = self.make_to_branch_and_tree('2')
569
599
        tree2 = self.make_to_branch_and_tree('2')
570
600
        tree1 = self.get_tree_no_parents_abc_content(tree1)
571
601
        tree2 = self.get_tree_no_parents_abc_content_2(tree2)
572
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
602
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
573
603
        root_id = tree1.path2id('')
574
604
        self.assertEqual([('a-id', ('a', 'a'), True, (True, True),
575
605
                           (root_id, root_id), ('a', 'a'),
581
611
        tree2 = self.make_to_branch_and_tree('2')
582
612
        tree1 = self.get_tree_no_parents_abc_content(tree1)
583
613
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
584
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
614
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
585
615
        self.assertEqual([('c-id', ('b/c', 'b/c'), False, (True, True),
586
616
                           ('b-id', 'b-id'), ('c', 'c'), ('file', 'file'),
587
617
                          (False, True))],
597
627
        self.build_tree(['1/a-empty/', '2/a-empty/'])
598
628
        tree1.add(['a-empty'], ['a-empty'])
599
629
        tree2.add(['a-empty'], ['a-empty'])
600
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
630
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
601
631
        expected = []
602
632
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
603
633
 
606
636
        tree2 = self.make_to_branch_and_tree('2')
607
637
        tree1 = self.get_tree_no_parents_abc_content(tree1)
608
638
        tree2 = self.get_tree_no_parents_abc_content_4(tree2)
609
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
639
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
610
640
        root_id = tree1.path2id('')
611
641
        self.assertEqual([('a-id', ('a', 'd'), False, (True, True),
612
642
                           (root_id, root_id), ('a', 'd'), ('file', 'file'),
618
648
        tree2 = self.make_to_branch_and_tree('2')
619
649
        tree1 = self.get_tree_no_parents_abc_content(tree1)
620
650
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
621
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
651
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
622
652
        root_id = tree1.path2id('')
623
653
        self.assertEqual([('a-id', ('a', 'd'), True, (True, True),
624
654
                           (root_id, root_id), ('a', 'd'), ('file', 'file'),
630
660
        tree2 = self.make_to_branch_and_tree('2')
631
661
        tree1 = self.get_tree_no_parents_abc_content(tree1)
632
662
        tree2 = self.get_tree_no_parents_abc_content_6(tree2)
633
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
663
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
634
664
        root_id = tree1.path2id('')
635
665
        self.assertEqual([('c-id', ('b/c', 'e'), False, (True, True),
636
666
                           ('b-id', root_id), ('c', 'e'), ('file', 'file'),
646
676
        os.unlink('2/a')
647
677
        shutil.rmtree('2/b')
648
678
        # TODO ? have a symlink here?
649
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
679
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
 
680
        self.not_applicable_if_missing_in('a', tree2)
 
681
        self.not_applicable_if_missing_in('b', tree2)
650
682
        root_id = tree1.path2id('')
651
683
        expected = sorted([
652
684
            self.missing('a-id', 'a', 'a', root_id, 'file'),
665
697
        tree2.add(['directory'], ['file-id'])
666
698
        os.rmdir('tree2/directory')
667
699
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
 
700
        self.not_applicable_if_missing_in('directory', tree2)
668
701
 
669
702
        root_id = tree1.path2id('')
670
703
        expected = sorted([
672
705
            ])
673
706
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
674
707
 
 
708
    def test_only_in_source_and_missing(self):
 
709
        tree1 = self.make_branch_and_tree('tree1')
 
710
        tree2 = self.make_to_branch_and_tree('tree2')
 
711
        tree2.set_root_id(tree1.get_root_id())
 
712
        self.build_tree(['tree1/file'])
 
713
        tree1.add(['file'], ['file-id'])
 
714
        os.unlink('tree1/file')
 
715
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
 
716
        self.not_applicable_if_missing_in('file', tree1)
 
717
        root_id = tree1.path2id('')
 
718
        expected = [('file-id', ('file', None), False, (True, False),
 
719
            (root_id, None), ('file', None), (None, None), (False, None))]
 
720
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
 
721
 
 
722
    def test_only_in_target_and_missing(self):
 
723
        tree1 = self.make_branch_and_tree('tree1')
 
724
        tree2 = self.make_to_branch_and_tree('tree2')
 
725
        tree2.set_root_id(tree1.get_root_id())
 
726
        self.build_tree(['tree2/file'])
 
727
        tree2.add(['file'], ['file-id'])
 
728
        os.unlink('tree2/file')
 
729
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
 
730
        self.not_applicable_if_missing_in('file', tree2)
 
731
        root_id = tree1.path2id('')
 
732
        expected = [('file-id', (None, 'file'), False, (False, True),
 
733
            (None, root_id), (None, 'file'), (None, None), (None, False))]
 
734
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
 
735
 
675
736
    def test_unchanged_with_renames_and_modifications(self):
676
737
        """want_unchanged should generate a list of unchanged entries."""
677
738
        tree1 = self.make_branch_and_tree('1')
706
767
        tree2.add_reference(subtree2)
707
768
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
708
769
 
709
 
        self.assertEqual([], list(tree2._iter_changes(tree1)))
 
770
        self.assertEqual([], list(tree2.iter_changes(tree1)))
710
771
        subtree1.commit('commit', rev_id='commit-a')
711
772
        self.assertEqual([
712
773
            ('root-id',
725
786
             ('sub', 'sub'),
726
787
             ('tree-reference', 'tree-reference'),
727
788
             (False, False))],
728
 
                         list(tree2._iter_changes(tree1,
 
789
                         list(tree2.iter_changes(tree1,
729
790
                             include_unchanged=True)))
730
791
 
731
792
    def test_disk_in_subtrees_skipped(self):
732
793
        """subtrees are considered not-in-the-current-tree.
733
 
        
 
794
 
734
795
        This test tests the trivial case, where the basis has no paths in the
735
796
        current trees subtree.
736
797
        """
742
803
        tree2.set_root_id('root-id')
743
804
        subtree2 = self.make_to_branch_and_tree('2/sub')
744
805
        subtree2.set_root_id('subtree-id')
745
 
        tree2.add(['sub'], ['subtree-id'])
 
806
        tree2.add_reference(subtree2)
746
807
        self.build_tree(['2/sub/file'])
747
808
        subtree2.add(['file'])
748
809
 
785
846
        else:
786
847
            links_supported = False
787
848
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
 
849
        self.not_applicable_if_cannot_represent_unversioned(tree2)
788
850
        expected = [
789
851
            self.unversioned(tree2, 'file'),
790
852
            self.unversioned(tree2, 'dir'),
805
867
        else:
806
868
            links_supported = False
807
869
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
 
870
        self.not_applicable_if_cannot_represent_unversioned(tree2)
808
871
        expected = [
809
872
            self.unversioned(tree2, 'file'),
810
873
            self.unversioned(tree2, 'dir'),
820
883
 
821
884
    def test_unversioned_paths_in_target_matching_source_old_names(self):
822
885
        # its likely that naive implementations of unversioned file support
823
 
        # will fail if the path was versioned, but is not any more, 
 
886
        # will fail if the path was versioned, but is not any more,
824
887
        # due to a rename, not due to unversioning it.
825
888
        # That is, if the old tree has a versioned file 'foo', and
826
889
        # the new tree has the same file but versioned as 'bar', and also
845
908
            tree1.add(['link'], ['link-id'])
846
909
            tree2.add(['movedlink'], ['link-id'])
847
910
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
 
911
        self.not_applicable_if_cannot_represent_unversioned(tree2)
848
912
        root_id = tree1.path2id('')
849
913
        expected = [
850
914
            self.renamed(tree1, tree2, 'dir-id', False),
894
958
                  ['a-id', 'b-id', 'c-id', 'd-id', 'a-c-id', 'e-id'])
895
959
 
896
960
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
 
961
        self.not_applicable_if_cannot_represent_unversioned(tree2)
897
962
 
898
963
        self.assertEqual([], self.do_iter_changes(tree1, tree2,
899
964
                                                  want_unversioned=True))
917
982
        tree2 = self.make_to_branch_and_tree('tree2')
918
983
        tree2.set_root_id(tree1.get_root_id())
919
984
        self.build_tree(['tree2/dir/', 'tree2/dir/file'])
920
 
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
 
985
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
 
986
        self.not_applicable_if_cannot_represent_unversioned(tree2)
921
987
        expected = [
922
988
            self.unversioned(tree2, 'dir'),
923
989
            ]
930
996
        tree2.set_root_id(tree1.get_root_id())
931
997
        self.build_tree(['tree1/fromfile', 'tree1/fromdir/'])
932
998
        self.build_tree(['tree2/tofile', 'tree2/todir/', 'tree2/unknown'])
933
 
        # try:
934
999
        os.symlink('original', 'tree1/changed')
935
1000
        os.symlink('original', 'tree1/removed')
936
1001
        os.symlink('original', 'tree1/tofile')
963
1028
            ]
964
1029
        tree1.add(from_paths_and_ids, from_paths_and_ids)
965
1030
        tree2.add(to_paths_and_ids, to_paths_and_ids)
966
 
        # except ???:
967
 
        #   raise TestSkipped('OS does not support symlinks')
968
 
        #   links_supported = False
969
1031
        return self.mutable_trees_to_locked_test_trees(tree1, tree2)
970
1032
 
971
1033
    def test_versioned_symlinks(self):
972
 
        if not has_symlinks():
973
 
            raise tests.TestSkipped("No symlink support")
 
1034
        self.requireFeature(tests.SymlinkFeature)
974
1035
        tree1, tree2 = self.make_trees_with_symlinks()
 
1036
        self.not_applicable_if_cannot_represent_unversioned(tree2)
975
1037
        root_id = tree1.path2id('')
976
1038
        expected = [
977
1039
            self.unchanged(tree1, tree1.path2id('')),
991
1053
                want_unversioned=True))
992
1054
 
993
1055
    def test_versioned_symlinks_specific_files(self):
994
 
        if not has_symlinks():
995
 
            raise tests.TestSkipped("No symlink support")
 
1056
        self.requireFeature(tests.SymlinkFeature)
996
1057
        tree1, tree2 = self.make_trees_with_symlinks()
997
1058
        root_id = tree1.path2id('')
998
1059
        expected = [
1232
1293
        tree2.add([u'\u03b1'], [a_id])
1233
1294
 
1234
1295
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
 
1296
        self.not_applicable_if_cannot_represent_unversioned(tree2)
1235
1297
 
1236
1298
        expected = sorted([
1237
1299
            self.unversioned(tree2, u'\u03b1/unknown_dir'),
1282
1344
        self.build_tree(['tree2/a/file', 'tree2/a/dir/', 'tree2/a/dir/subfile'])
1283
1345
 
1284
1346
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
 
1347
        self.not_applicable_if_cannot_represent_unversioned(tree2)
1285
1348
 
1286
1349
        expected = sorted([
1287
1350
            self.unversioned(tree2, u'a/file'),
1349
1412
        tree2.add(['a', 'c'], ['a-id', 'c-id'])
1350
1413
 
1351
1414
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
 
1415
        self.not_applicable_if_cannot_represent_unversioned(tree2)
1352
1416
 
1353
1417
        expected = sorted([
1354
1418
            self.deleted(tree1, 'b-id'),
1422
1486
        os.rename('tree2/a', 'tree2/a2')
1423
1487
 
1424
1488
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
 
1489
        self.not_applicable_if_missing_in('a', tree2)
1425
1490
 
1426
1491
        expected = sorted([
1427
1492
            self.missing('a-id', 'a', 'a', tree2.get_root_id(), 'file'),