/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/test_transform.py

  • Committer: Richard Wilbur
  • Date: 2016-02-04 19:07:28 UTC
  • mto: This revision was merged to the branch mainline in revision 6618.
  • Revision ID: richard.wilbur@gmail.com-20160204190728-p0zvfii6zase0fw7
Update COPYING.txt from the original http://www.gnu.org/licenses/gpl-2.0.txt  (Only differences were in whitespace.)  Thanks to Petr Stodulka for pointing out the discrepancy.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2012, 2016 Canonical Ltd
 
1
# Copyright (C) 2006-2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
16
16
 
17
17
import errno
18
18
import os
 
19
from StringIO import StringIO
19
20
import sys
20
21
import time
21
22
 
22
 
from .. import (
 
23
from bzrlib import (
23
24
    bencode,
24
25
    errors,
25
26
    filters,
27
28
    osutils,
28
29
    revision as _mod_revision,
29
30
    rules,
 
31
    symbol_versioning,
30
32
    tests,
31
33
    trace,
32
34
    transform,
33
35
    urlutils,
34
36
    )
35
 
from ..conflicts import (
 
37
from bzrlib.conflicts import (
36
38
    DeletingParent,
37
39
    DuplicateEntry,
38
40
    DuplicateID,
41
43
    ParentLoop,
42
44
    UnversionedParent,
43
45
)
44
 
from ..controldir import ControlDir
45
 
from ..diff import show_diff_trees
46
 
from ..errors import (
 
46
from bzrlib.controldir import ControlDir
 
47
from bzrlib.diff import show_diff_trees
 
48
from bzrlib.errors import (
47
49
    DuplicateKey,
48
50
    ExistingLimbo,
49
51
    ExistingPendingDeletion,
53
55
    MalformedTransform,
54
56
    ReusingTransform,
55
57
)
56
 
from ..osutils import (
 
58
from bzrlib.osutils import (
57
59
    file_kind,
58
60
    pathjoin,
59
61
)
60
 
from ..merge import Merge3Merger, Merger
61
 
from ..mutabletree import MutableTree
62
 
from ..sixish import (
63
 
    BytesIO,
64
 
    )
65
 
from . import (
 
62
from bzrlib.merge import Merge3Merger, Merger
 
63
from bzrlib.mutabletree import MutableTree
 
64
from bzrlib.tests import (
66
65
    features,
67
66
    TestCaseInTempDir,
68
67
    TestSkipped,
69
68
    )
70
 
from .features import (
 
69
from bzrlib.tests.features import (
71
70
    HardlinkFeature,
72
71
    SymlinkFeature,
73
72
    )
74
 
from ..transform import (
 
73
from bzrlib.transform import (
75
74
    build_tree,
76
75
    create_from_tree,
77
76
    cook_conflicts,
162
161
        transform.set_executability(False, trans_id2)
163
162
        transform.version_file('my_pretties2', trans_id2)
164
163
        modified_paths = transform.apply().modified_paths
165
 
        self.assertEqual('contents', self.wt.get_file('name').read())
 
164
        self.assertEqual('contents', self.wt.get_file_byname('name').read())
166
165
        self.assertEqual(self.wt.path2id('name'), 'my_pretties')
167
 
        self.assertIs(self.wt.is_executable('name'), True)
168
 
        self.assertIs(self.wt.is_executable('name2'), False)
 
166
        self.assertIs(self.wt.is_executable('my_pretties'), True)
 
167
        self.assertIs(self.wt.is_executable('my_pretties2'), False)
169
168
        self.assertEqual('directory', file_kind(self.wt.abspath('oz')))
170
169
        self.assertEqual(len(modified_paths), 3)
171
 
        tree_mod_paths = [self.wt.abspath(self.wt.id2path(f)) for f in
 
170
        tree_mod_paths = [self.wt.id2abspath(f) for f in
172
171
                          ('ozzie', 'my_pretties', 'my_pretties2')]
173
172
        self.assertSubset(tree_mod_paths, modified_paths)
174
173
        # is it safe to finalize repeatedly?
249
248
        transform.create_file('content-two',
250
249
                              transform.create_path('two', root))
251
250
        transform.apply()
252
 
        fo, st1 = self.wt.get_file_with_stat('one', filtered=False)
 
251
        fo, st1 = self.wt.get_file_with_stat(None, path='one', filtered=False)
253
252
        fo.close()
254
 
        fo, st2 = self.wt.get_file_with_stat('two', filtered=False)
 
253
        fo, st2 = self.wt.get_file_with_stat(None, path='two', filtered=False)
255
254
        fo.close()
256
255
        # We only guarantee 2s resolution
257
256
        self.assertTrue(abs(creation_mtime - st1.st_mtime) < 2.0,
261
260
 
262
261
    def test_change_root_id(self):
263
262
        transform, root = self.get_transform()
264
 
        self.assertNotEqual(b'new-root-id', self.wt.get_root_id())
265
 
        transform.new_directory('', ROOT_PARENT, b'new-root-id')
 
263
        self.assertNotEqual('new-root-id', self.wt.get_root_id())
 
264
        transform.new_directory('', ROOT_PARENT, 'new-root-id')
266
265
        transform.delete_contents(root)
267
266
        transform.unversion_file(root)
268
267
        transform.fixup_new_roots()
269
268
        transform.apply()
270
 
        self.assertEqual(b'new-root-id', self.wt.get_root_id())
 
269
        self.assertEqual('new-root-id', self.wt.get_root_id())
271
270
 
272
271
    def test_change_root_id_add_files(self):
273
272
        transform, root = self.get_transform()
274
 
        self.assertNotEqual(b'new-root-id', self.wt.get_root_id())
275
 
        new_trans_id = transform.new_directory('', ROOT_PARENT, b'new-root-id')
 
273
        self.assertNotEqual('new-root-id', self.wt.get_root_id())
 
274
        new_trans_id = transform.new_directory('', ROOT_PARENT, 'new-root-id')
276
275
        transform.new_file('file', new_trans_id, ['new-contents\n'],
277
276
                           'new-file-id')
278
277
        transform.delete_contents(root)
279
278
        transform.unversion_file(root)
280
279
        transform.fixup_new_roots()
281
280
        transform.apply()
282
 
        self.assertEqual(b'new-root-id', self.wt.get_root_id())
283
 
        self.assertEqual(b'new-file-id', self.wt.path2id('file'))
 
281
        self.assertEqual('new-root-id', self.wt.get_root_id())
 
282
        self.assertEqual('new-file-id', self.wt.path2id('file'))
284
283
        self.assertFileEqual('new-contents\n', self.wt.abspath('file'))
285
284
 
286
285
    def test_add_two_roots(self):
287
286
        transform, root = self.get_transform()
288
 
        new_trans_id = transform.new_directory('', ROOT_PARENT, b'new-root-id')
289
 
        new_trans_id = transform.new_directory('', ROOT_PARENT, b'alt-root-id')
 
287
        new_trans_id = transform.new_directory('', ROOT_PARENT, 'new-root-id')
 
288
        new_trans_id = transform.new_directory('', ROOT_PARENT, 'alt-root-id')
290
289
        self.assertRaises(ValueError, transform.fixup_new_roots)
291
290
 
292
291
    def test_retain_existing_root(self):
293
292
        tt, root = self.get_transform()
294
293
        with tt:
295
 
            tt.new_directory('', ROOT_PARENT, b'new-root-id')
 
294
            tt.new_directory('', ROOT_PARENT, 'new-root-id')
296
295
            tt.fixup_new_roots()
297
 
            self.assertNotEqual(b'new-root-id', tt.final_file_id(tt.root))
 
296
            self.assertNotEqual('new-root-id', tt.final_file_id(tt.root))
298
297
 
299
298
    def test_retain_existing_root_added_file(self):
300
299
        tt, root = self.get_transform()
301
 
        new_trans_id = tt.new_directory('', ROOT_PARENT, b'new-root-id')
302
 
        child = tt.new_directory('child', new_trans_id, b'child-id')
 
300
        new_trans_id = tt.new_directory('', ROOT_PARENT, 'new-root-id')
 
301
        child = tt.new_directory('child', new_trans_id, 'child-id')
303
302
        tt.fixup_new_roots()
304
303
        self.assertEqual(tt.root, tt.final_parent(child))
305
304
 
313
312
    def test_remove_root_fixup(self):
314
313
        transform, root = self.get_transform()
315
314
        old_root_id = self.wt.get_root_id()
316
 
        self.assertNotEqual(b'new-root-id', old_root_id)
 
315
        self.assertNotEqual('new-root-id', old_root_id)
317
316
        transform.delete_contents(root)
318
317
        transform.unversion_file(root)
319
318
        transform.fixup_new_roots()
321
320
        self.assertEqual(old_root_id, self.wt.get_root_id())
322
321
 
323
322
        transform, root = self.get_transform()
324
 
        new_trans_id = transform.new_directory('', ROOT_PARENT, b'new-root-id')
325
 
        new_trans_id = transform.new_directory('', ROOT_PARENT, b'alt-root-id')
 
323
        new_trans_id = transform.new_directory('', ROOT_PARENT, 'new-root-id')
 
324
        new_trans_id = transform.new_directory('', ROOT_PARENT, 'alt-root-id')
326
325
        self.assertRaises(ValueError, transform.fixup_new_roots)
327
326
 
328
327
    def test_fixup_new_roots_permits_empty_tree(self):
382
381
        self.assertRaises(ReusingTransform, transform.find_conflicts)
383
382
        self.assertEqual('contents', file(self.wt.abspath('name')).read())
384
383
        self.assertEqual(self.wt.path2id('name'), 'my_pretties')
385
 
        self.assertIs(self.wt.is_executable('name'), True)
 
384
        self.assertIs(self.wt.is_executable('my_pretties'), True)
386
385
        self.assertEqual(self.wt.path2id('oz'), 'oz-id')
387
386
        self.assertEqual(self.wt.path2id('oz/dorothy'), 'dorothy-id')
388
387
        self.assertEqual(self.wt.path2id('oz/dorothy/toto'), 'toto-id')
389
388
 
390
389
        self.assertEqual('toto-contents',
391
 
                         self.wt.get_file('oz/dorothy/toto').read())
392
 
        self.assertIs(self.wt.is_executable('oz/dorothy/toto'), False)
 
390
                         self.wt.get_file_byname('oz/dorothy/toto').read())
 
391
        self.assertIs(self.wt.is_executable('toto-id'), False)
393
392
 
394
393
    def test_tree_reference(self):
395
394
        transform, root = self.get_transform()
400
399
        tree.lock_read()
401
400
        self.addCleanup(tree.unlock)
402
401
        self.assertEqual('subtree-revision',
403
 
                         tree.root_inventory.get_entry('subtree-id').reference_revision)
 
402
                         tree.root_inventory['subtree-id'].reference_revision)
404
403
 
405
404
    def test_conflicts(self):
406
405
        transform, root = self.get_transform()
453
452
        self.assertEqual(self.wt.path2id('name'), 'my_pretties')
454
453
        self.assertEqual('contents', file(self.wt.abspath('name')).read())
455
454
        transform2, root = self.get_transform()
456
 
        oz_id = transform2.trans_id_tree_path('oz')
 
455
        oz_id = transform2.trans_id_tree_file_id('oz-id')
457
456
        newtip = transform2.new_file('tip', oz_id, 'other', 'tip-id')
458
457
        result = transform2.find_conflicts()
459
458
        fp = FinalPaths(transform2)
460
 
        self.assertTrue('oz/tip' in transform2._tree_path_ids)
 
459
        self.assert_('oz/tip' in transform2._tree_path_ids)
461
460
        self.assertEqual(fp.get_path(newtip), pathjoin('oz', 'tip'))
462
461
        self.assertEqual(len(result), 2)
463
462
        self.assertEqual((result[0][0], result[0][1]),
467
466
        transform2.finalize()
468
467
        transform3 = TreeTransform(self.wt)
469
468
        self.addCleanup(transform3.finalize)
470
 
        oz_id = transform3.trans_id_tree_path('oz')
 
469
        oz_id = transform3.trans_id_tree_file_id('oz-id')
471
470
        transform3.delete_contents(oz_id)
472
471
        self.assertEqual(transform3.find_conflicts(),
473
472
                         [('missing parent', oz_id)])
474
473
        root_id = transform3.root
475
 
        tip_id = transform3.trans_id_tree_path('oz/tip')
 
474
        tip_id = transform3.trans_id_tree_file_id('tip-id')
476
475
        transform3.adjust_path('tip', root_id, tip_id)
477
476
        transform3.apply()
478
477
 
601
600
        start.new_directory('a', root, 'a')
602
601
        start.apply()
603
602
        transform, root = self.get_transform()
604
 
        transform.delete_versioned(transform.trans_id_tree_path('a'))
 
603
        transform.delete_versioned(transform.trans_id_tree_file_id('a'))
605
604
        transform.new_directory('a', root, 'a')
606
605
        transform.apply()
607
606
 
608
607
    def test_unversioning(self):
609
608
        create_tree, root = self.get_transform()
610
 
        parent_id = create_tree.new_directory('parent', root, b'parent-id')
611
 
        create_tree.new_file('child', parent_id, 'child', b'child-id')
 
609
        parent_id = create_tree.new_directory('parent', root, 'parent-id')
 
610
        create_tree.new_file('child', parent_id, 'child', 'child-id')
612
611
        create_tree.apply()
613
612
        unversion = TreeTransform(self.wt)
614
613
        self.addCleanup(unversion.finalize)
616
615
        unversion.unversion_file(parent)
617
616
        self.assertEqual(unversion.find_conflicts(),
618
617
                         [('unversioned parent', parent_id)])
619
 
        file_id = unversion.trans_id_tree_path('parent/child')
 
618
        file_id = unversion.trans_id_tree_file_id('child-id')
620
619
        unversion.unversion_file(file_id)
621
620
        unversion.apply()
622
621
 
632
631
        create_tree.new_file('moving_file2', root, 'later2', 'mfile2')
633
632
        create_tree.apply()
634
633
 
635
 
        mangle_tree, root = self.get_transform()
 
634
        mangle_tree,root = self.get_transform()
636
635
        root = mangle_tree.root
637
636
        #swap names
638
 
        name1 = mangle_tree.trans_id_tree_path('name1')
639
 
        name2 = mangle_tree.trans_id_tree_path('name2')
 
637
        name1 = mangle_tree.trans_id_tree_file_id('name1')
 
638
        name2 = mangle_tree.trans_id_tree_file_id('name2')
640
639
        mangle_tree.adjust_path('name2', root, name1)
641
640
        mangle_tree.adjust_path('name1', root, name2)
642
641
 
643
642
        #tests for deleting parent directories
644
 
        ddir = mangle_tree.trans_id_tree_path('dying_directory')
 
643
        ddir = mangle_tree.trans_id_tree_file_id('ddir')
645
644
        mangle_tree.delete_contents(ddir)
646
 
        dfile = mangle_tree.trans_id_tree_path('dying_directory/dying_file')
 
645
        dfile = mangle_tree.trans_id_tree_file_id('dfile')
647
646
        mangle_tree.delete_versioned(dfile)
648
647
        mangle_tree.unversion_file(dfile)
649
 
        mfile = mangle_tree.trans_id_tree_path('dying_directory/moving_file')
 
648
        mfile = mangle_tree.trans_id_tree_file_id('mfile')
650
649
        mangle_tree.adjust_path('mfile', root, mfile)
651
650
 
652
651
        #tests for adding parent directories
653
652
        newdir = mangle_tree.new_directory('new_directory', root, 'newdir')
654
 
        mfile2 = mangle_tree.trans_id_tree_path('moving_file2')
 
653
        mfile2 = mangle_tree.trans_id_tree_file_id('mfile2')
655
654
        mangle_tree.adjust_path('mfile2', newdir, mfile2)
656
655
        mangle_tree.new_file('newfile', newdir, 'hello3', 'dfile')
657
656
        self.assertEqual(mangle_tree.final_file_id(mfile2), 'mfile2')
660
659
        mangle_tree.apply()
661
660
        self.assertEqual(file(self.wt.abspath('name1')).read(), 'hello2')
662
661
        self.assertEqual(file(self.wt.abspath('name2')).read(), 'hello1')
663
 
        mfile2_path = self.wt.abspath(pathjoin('new_directory', 'mfile2'))
 
662
        mfile2_path = self.wt.abspath(pathjoin('new_directory','mfile2'))
664
663
        self.assertEqual(mangle_tree.final_parent(mfile2), newdir)
665
664
        self.assertEqual(file(mfile2_path).read(), 'later2')
666
 
        self.assertEqual(self.wt.id2path(b'mfile2'), 'new_directory/mfile2')
667
 
        self.assertEqual(self.wt.path2id('new_directory/mfile2'), b'mfile2')
668
 
        newfile_path = self.wt.abspath(pathjoin('new_directory', 'newfile'))
 
665
        self.assertEqual(self.wt.id2path('mfile2'), 'new_directory/mfile2')
 
666
        self.assertEqual(self.wt.path2id('new_directory/mfile2'), 'mfile2')
 
667
        newfile_path = self.wt.abspath(pathjoin('new_directory','newfile'))
669
668
        self.assertEqual(file(newfile_path).read(), 'hello3')
670
 
        self.assertEqual(self.wt.path2id('dying_directory'), b'ddir')
 
669
        self.assertEqual(self.wt.path2id('dying_directory'), 'ddir')
671
670
        self.assertIs(self.wt.path2id('dying_directory/dying_file'), None)
672
 
        mfile2_path = self.wt.abspath(pathjoin('new_directory', 'mfile2'))
 
671
        mfile2_path = self.wt.abspath(pathjoin('new_directory','mfile2'))
673
672
 
674
673
    def test_both_rename(self):
675
 
        create_tree, root = self.get_transform()
 
674
        create_tree,root = self.get_transform()
676
675
        newdir = create_tree.new_directory('selftest', root, 'selftest-id')
677
676
        create_tree.new_file('blackbox.py', newdir, 'hello1', 'blackbox-id')
678
677
        create_tree.apply()
679
 
        mangle_tree, root = self.get_transform()
680
 
        selftest = mangle_tree.trans_id_tree_path('selftest')
681
 
        blackbox = mangle_tree.trans_id_tree_path('selftest/blackbox.py')
 
678
        mangle_tree,root = self.get_transform()
 
679
        selftest = mangle_tree.trans_id_tree_file_id('selftest-id')
 
680
        blackbox = mangle_tree.trans_id_tree_file_id('blackbox-id')
682
681
        mangle_tree.adjust_path('test', root, selftest)
683
682
        mangle_tree.adjust_path('test_too_much', root, selftest)
684
683
        mangle_tree.set_executability(True, blackbox)
685
684
        mangle_tree.apply()
686
685
 
687
686
    def test_both_rename2(self):
688
 
        create_tree, root = self.get_transform()
689
 
        breezy = create_tree.new_directory('breezy', root, 'breezy-id')
690
 
        tests = create_tree.new_directory('tests', breezy, 'tests-id')
 
687
        create_tree,root = self.get_transform()
 
688
        bzrlib = create_tree.new_directory('bzrlib', root, 'bzrlib-id')
 
689
        tests = create_tree.new_directory('tests', bzrlib, 'tests-id')
691
690
        blackbox = create_tree.new_directory('blackbox', tests, 'blackbox-id')
692
691
        create_tree.new_file('test_too_much.py', blackbox, 'hello1',
693
692
                             'test_too_much-id')
694
693
        create_tree.apply()
695
 
        mangle_tree, root = self.get_transform()
696
 
        breezy = mangle_tree.trans_id_tree_path('breezy')
697
 
        tests = mangle_tree.trans_id_tree_path('breezy/tests')
698
 
        test_too_much = mangle_tree.trans_id_tree_path('breezy/tests/blackbox/test_too_much.py')
699
 
        mangle_tree.adjust_path('selftest', breezy, tests)
 
694
        mangle_tree,root = self.get_transform()
 
695
        bzrlib = mangle_tree.trans_id_tree_file_id('bzrlib-id')
 
696
        tests = mangle_tree.trans_id_tree_file_id('tests-id')
 
697
        test_too_much = mangle_tree.trans_id_tree_file_id('test_too_much-id')
 
698
        mangle_tree.adjust_path('selftest', bzrlib, tests)
700
699
        mangle_tree.adjust_path('blackbox.py', tests, test_too_much)
701
700
        mangle_tree.set_executability(True, test_too_much)
702
701
        mangle_tree.apply()
703
702
 
704
703
    def test_both_rename3(self):
705
 
        create_tree, root = self.get_transform()
 
704
        create_tree,root = self.get_transform()
706
705
        tests = create_tree.new_directory('tests', root, 'tests-id')
707
706
        create_tree.new_file('test_too_much.py', tests, 'hello1',
708
707
                             'test_too_much-id')
709
708
        create_tree.apply()
710
 
        mangle_tree, root = self.get_transform()
711
 
        tests = mangle_tree.trans_id_tree_path('tests')
712
 
        test_too_much = mangle_tree.trans_id_tree_path('tests/test_too_much.py')
 
709
        mangle_tree,root = self.get_transform()
 
710
        tests = mangle_tree.trans_id_tree_file_id('tests-id')
 
711
        test_too_much = mangle_tree.trans_id_tree_file_id('test_too_much-id')
713
712
        mangle_tree.adjust_path('selftest', root, tests)
714
713
        mangle_tree.adjust_path('blackbox.py', tests, test_too_much)
715
714
        mangle_tree.set_executability(True, test_too_much)
722
721
        create_tree.new_file('name1', root, 'hello1', 'name1')
723
722
        create_tree.apply()
724
723
        delete_contents, root = self.get_transform()
725
 
        file = delete_contents.trans_id_tree_path('name1')
 
724
        file = delete_contents.trans_id_tree_file_id('name1')
726
725
        delete_contents.delete_contents(file)
727
726
        delete_contents.apply()
728
727
        move_id, root = self.get_transform()
729
 
        name1 = move_id.trans_id_tree_path('name1')
 
728
        name1 = move_id.trans_id_tree_file_id('name1')
730
729
        newdir = move_id.new_directory('dir', root, 'newdir')
731
730
        move_id.adjust_path('name2', newdir, name1)
732
731
        move_id.apply()
739
738
        create_tree.apply()
740
739
        delete_contents = TreeTransform(self.wt)
741
740
        self.addCleanup(delete_contents.finalize)
742
 
        file = delete_contents.trans_id_tree_path('name1')
 
741
        file = delete_contents.trans_id_tree_file_id('name1')
743
742
        delete_contents.delete_contents(file)
744
743
        delete_contents.apply()
745
744
        delete_contents.finalize()
747
746
        self.addCleanup(replace.finalize)
748
747
        name2 = replace.new_file('name2', root, 'hello2', 'name1')
749
748
        conflicts = replace.find_conflicts()
750
 
        name1 = replace.trans_id_tree_path('name1')
 
749
        name1 = replace.trans_id_tree_file_id('name1')
751
750
        self.assertEqual(conflicts, [('duplicate id', name1, name2)])
752
751
        resolve_conflicts(replace)
753
752
        replace.apply()
754
753
 
755
 
    def _test_symlinks(self, link_name1, link_target1,
 
754
    def _test_symlinks(self, link_name1,link_target1,
756
755
                       link_name2, link_target2):
757
756
 
758
757
        def ozpath(p): return 'oz/' + p
802
801
        os.symlink = None
803
802
        try:
804
803
            err = self.assertRaises(errors.UnableCreateSymlink, tt_helper)
805
 
            self.assertEqual(
 
804
            self.assertEquals(
806
805
                "Unable to create symlink 'foo' on this platform",
807
806
                str(err))
808
807
        finally:
810
809
                os.symlink = os_symlink
811
810
 
812
811
    def get_conflicted(self):
813
 
        create, root = self.get_transform()
 
812
        create,root = self.get_transform()
814
813
        create.new_file('dorothy', root, 'dorothy', 'dorothy-id')
815
814
        oz = create.new_directory('oz', root, 'oz-id')
816
815
        create.new_directory('emeraldcity', oz, 'emerald-id')
817
816
        create.apply()
818
 
        conflicts, root = self.get_transform()
 
817
        conflicts,root = self.get_transform()
819
818
        # set up duplicate entry, duplicate id
820
819
        new_dorothy = conflicts.new_file('dorothy', root, 'dorothy',
821
820
                                         'dorothy-id')
822
 
        old_dorothy = conflicts.trans_id_tree_path('dorothy')
823
 
        oz = conflicts.trans_id_tree_path('oz')
 
821
        old_dorothy = conflicts.trans_id_tree_file_id('dorothy-id')
 
822
        oz = conflicts.trans_id_tree_file_id('oz-id')
824
823
        # set up DeletedParent parent conflict
825
824
        conflicts.delete_versioned(oz)
826
 
        emerald = conflicts.trans_id_tree_path('oz/emeraldcity')
 
825
        emerald = conflicts.trans_id_tree_file_id('emerald-id')
827
826
        # set up MissingParent conflict
828
827
        munchkincity = conflicts.trans_id_file_id('munchkincity-id')
829
828
        conflicts.adjust_path('munchkincity', root, munchkincity)
900
899
 
901
900
    def prepare_wrong_parent_kind(self):
902
901
        tt, root = self.get_transform()
903
 
        tt.new_file('parent', root, 'contents', b'parent-id')
 
902
        tt.new_file('parent', root, 'contents', 'parent-id')
904
903
        tt.apply()
905
904
        tt, root = self.get_transform()
906
905
        parent_id = tt.trans_id_file_id('parent-id')
907
 
        tt.new_file('child,', parent_id, 'contents2', b'file-id')
 
906
        tt.new_file('child,', parent_id, 'contents2', 'file-id')
908
907
        return tt
909
908
 
910
909
    def test_find_conflicts_wrong_parent_kind(self):
914
913
    def test_resolve_conflicts_wrong_existing_parent_kind(self):
915
914
        tt = self.prepare_wrong_parent_kind()
916
915
        raw_conflicts = resolve_conflicts(tt)
917
 
        self.assertEqual({('non-directory parent', 'Created directory',
918
 
                         'new-3')}, raw_conflicts)
 
916
        self.assertEqual(set([('non-directory parent', 'Created directory',
 
917
                         'new-3')]), raw_conflicts)
919
918
        cooked_conflicts = cook_conflicts(raw_conflicts, tt)
920
919
        self.assertEqual([NonDirectoryParent('Created directory', 'parent.new',
921
 
        b'parent-id')], cooked_conflicts)
 
920
        'parent-id')], cooked_conflicts)
922
921
        tt.apply()
923
 
        self.assertFalse(self.wt.is_versioned('parent'))
 
922
        self.assertEqual(None, self.wt.path2id('parent'))
924
923
        self.assertEqual('parent-id', self.wt.path2id('parent.new'))
925
924
 
926
925
    def test_resolve_conflicts_wrong_new_parent_kind(self):
927
926
        tt, root = self.get_transform()
928
 
        parent_id = tt.new_directory('parent', root, b'parent-id')
929
 
        tt.new_file('child,', parent_id, 'contents2', b'file-id')
 
927
        parent_id = tt.new_directory('parent', root, 'parent-id')
 
928
        tt.new_file('child,', parent_id, 'contents2', 'file-id')
930
929
        tt.apply()
931
930
        tt, root = self.get_transform()
932
931
        parent_id = tt.trans_id_file_id('parent-id')
933
932
        tt.delete_contents(parent_id)
934
933
        tt.create_file('contents', parent_id)
935
934
        raw_conflicts = resolve_conflicts(tt)
936
 
        self.assertEqual({('non-directory parent', 'Created directory',
937
 
                         'new-3')}, raw_conflicts)
 
935
        self.assertEqual(set([('non-directory parent', 'Created directory',
 
936
                         'new-3')]), raw_conflicts)
938
937
        tt.apply()
939
 
        self.assertFalse(self.wt.is_versioned('parent'))
 
938
        self.assertEqual(None, self.wt.path2id('parent'))
940
939
        self.assertEqual('parent-id', self.wt.path2id('parent.new'))
941
940
 
942
941
    def test_resolve_conflicts_wrong_parent_kind_unversioned(self):
950
949
        tt.create_file('contents', parent_id)
951
950
        resolve_conflicts(tt)
952
951
        tt.apply()
953
 
        self.assertFalse(self.wt.is_versioned('parent'))
954
 
        self.assertFalse(self.wt.is_versioned('parent.new'))
 
952
        self.assertIs(None, self.wt.path2id('parent'))
 
953
        self.assertIs(None, self.wt.path2id('parent.new'))
955
954
 
956
955
    def test_resolve_conflicts_missing_parent(self):
957
956
        wt = self.make_branch_and_tree('.')
975
974
        create.new_directory('oz', root, 'oz-id')
976
975
        create.apply()
977
976
        cyclone, root = self.get_transform()
978
 
        oz = cyclone.trans_id_tree_path('oz')
979
 
        house = cyclone.trans_id_tree_path('house')
 
977
        oz = cyclone.trans_id_tree_file_id('oz-id')
 
978
        house = cyclone.trans_id_tree_file_id('house-id')
980
979
        cyclone.adjust_path('house', oz, house)
981
980
        cyclone.apply()
982
981
 
1021
1020
            # windows filesystems fail on renaming open files
1022
1021
            self.addCleanup(file(self.wt.abspath('myfile')).close)
1023
1022
        else:
1024
 
            self.skipTest("Can't force a permissions error on rename")
 
1023
            self.skip("Don't know how to force a permissions error on rename")
1025
1024
        # now transform to rename
1026
1025
        rename_transform, root_id = self.get_transform()
1027
1026
        file_trans_id = rename_transform.trans_id_file_id('myfile-id')
1066
1065
                                 'uws')
1067
1066
        self.assertRaises(KeyError, transform.set_executability, None, uws)
1068
1067
        transform.apply()
1069
 
        self.assertTrue(wt.is_executable('set_on_creation'))
1070
 
        self.assertTrue(wt.is_executable('set_after_creation'))
 
1068
        self.assertTrue(wt.is_executable('soc'))
 
1069
        self.assertTrue(wt.is_executable('sac'))
1071
1070
 
1072
1071
    def test_preserve_mode(self):
1073
1072
        """File mode is preserved when replacing content"""
1078
1077
        transform.apply()
1079
1078
        self.wt.lock_write()
1080
1079
        self.addCleanup(self.wt.unlock)
1081
 
        self.assertTrue(self.wt.is_executable('file1'))
 
1080
        self.assertTrue(self.wt.is_executable('file1-id'))
1082
1081
        transform, root = self.get_transform()
1083
 
        file1_id = transform.trans_id_tree_path('file1')
 
1082
        file1_id = transform.trans_id_tree_file_id('file1-id')
1084
1083
        transform.delete_contents(file1_id)
1085
1084
        transform.create_file('contents2', file1_id)
1086
1085
        transform.apply()
1087
 
        self.assertTrue(self.wt.is_executable('file1'))
 
1086
        self.assertTrue(self.wt.is_executable('file1-id'))
1088
1087
 
1089
1088
    def test__set_mode_stats_correctly(self):
1090
1089
        """_set_mode stats to determine file mode."""
1117
1116
        self.assertEqual([bar1_abspath], stat_paths)
1118
1117
 
1119
1118
    def test_iter_changes(self):
1120
 
        self.wt.set_root_id(b'eert_toor')
 
1119
        self.wt.set_root_id('eert_toor')
1121
1120
        transform, root = self.get_transform()
1122
1121
        transform.new_file('old', root, 'blah', 'id-1', True)
1123
1122
        transform.apply()
1124
1123
        transform, root = self.get_transform()
1125
1124
        try:
1126
1125
            self.assertEqual([], list(transform.iter_changes()))
1127
 
            old = transform.trans_id_tree_path('old')
 
1126
            old = transform.trans_id_tree_file_id('id-1')
1128
1127
            transform.unversion_file(old)
1129
1128
            self.assertEqual([('id-1', ('old', None), False, (True, False),
1130
1129
                ('eert_toor', 'eert_toor'), ('old', 'old'), ('file', 'file'),
1138
1137
            transform.finalize()
1139
1138
 
1140
1139
    def test_iter_changes_new(self):
1141
 
        self.wt.set_root_id(b'eert_toor')
 
1140
        self.wt.set_root_id('eert_toor')
1142
1141
        transform, root = self.get_transform()
1143
1142
        transform.new_file('old', root, 'blah')
1144
1143
        transform.apply()
1153
1152
            transform.finalize()
1154
1153
 
1155
1154
    def test_iter_changes_modifications(self):
1156
 
        self.wt.set_root_id(b'eert_toor')
 
1155
        self.wt.set_root_id('eert_toor')
1157
1156
        transform, root = self.get_transform()
1158
1157
        transform.new_file('old', root, 'blah', 'id-1')
1159
1158
        transform.new_file('new', root, 'blah')
1162
1161
        transform, root = self.get_transform()
1163
1162
        try:
1164
1163
            old = transform.trans_id_tree_path('old')
1165
 
            subdir = transform.trans_id_tree_path('subdir')
 
1164
            subdir = transform.trans_id_tree_file_id('subdir-id')
1166
1165
            new = transform.trans_id_tree_path('new')
1167
1166
            self.assertEqual([], list(transform.iter_changes()))
1168
1167
 
1225
1224
            transform.finalize()
1226
1225
 
1227
1226
    def test_iter_changes_modified_bleed(self):
1228
 
        self.wt.set_root_id(b'eert_toor')
 
1227
        self.wt.set_root_id('eert_toor')
1229
1228
        """Modified flag should not bleed from one change to another"""
1230
1229
        # unfortunately, we have no guarantee that file1 (which is modified)
1231
1230
        # will be applied before file2.  And if it's applied after file2, it
1252
1251
 
1253
1252
    def test_iter_changes_move_missing(self):
1254
1253
        """Test moving ids with no files around"""
1255
 
        self.wt.set_root_id(b'toor_eert')
 
1254
        self.wt.set_root_id('toor_eert')
1256
1255
        # Need two steps because versioning a non-existant file is a conflict.
1257
1256
        transform, root = self.get_transform()
1258
1257
        transform.new_directory('floater', root, 'floater-id')
1272
1271
 
1273
1272
    def test_iter_changes_pointless(self):
1274
1273
        """Ensure that no-ops are not treated as modifications"""
1275
 
        self.wt.set_root_id(b'eert_toor')
 
1274
        self.wt.set_root_id('eert_toor')
1276
1275
        transform, root = self.get_transform()
1277
1276
        transform.new_file('old', root, 'blah', 'id-1')
1278
1277
        transform.new_directory('subdir', root, 'subdir-id')
1280
1279
        transform, root = self.get_transform()
1281
1280
        try:
1282
1281
            old = transform.trans_id_tree_path('old')
1283
 
            subdir = transform.trans_id_tree_path('subdir')
 
1282
            subdir = transform.trans_id_tree_file_id('subdir-id')
1284
1283
            self.assertEqual([], list(transform.iter_changes()))
1285
1284
            transform.delete_contents(subdir)
1286
1285
            transform.create_directory(subdir)
1533
1532
        self.assertPathExists("foo/bar")
1534
1533
        wt.lock_read()
1535
1534
        try:
1536
 
            self.assertEqual(wt.kind("foo"), "directory")
 
1535
            self.assertEqual(wt.kind(wt.path2id("foo")), "directory")
1537
1536
        finally:
1538
1537
            wt.unlock()
1539
1538
        wt.commit("two")
1555
1554
        self.assertPathExists("foo")
1556
1555
        wt.lock_read()
1557
1556
        self.addCleanup(wt.unlock)
1558
 
        self.assertEqual(wt.kind("foo"), "symlink")
 
1557
        self.assertEqual(wt.kind(wt.path2id("foo")), "symlink")
1559
1558
 
1560
1559
    def test_dir_to_file(self):
1561
1560
        wt = self.make_branch_and_tree('.')
1573
1572
        self.assertPathExists("foo")
1574
1573
        wt.lock_read()
1575
1574
        self.addCleanup(wt.unlock)
1576
 
        self.assertEqual(wt.kind("foo"), "file")
 
1575
        self.assertEqual(wt.kind(wt.path2id("foo")), "file")
1577
1576
 
1578
1577
    def test_dir_to_hardlink(self):
1579
1578
        self.requireFeature(HardlinkFeature)
1594
1593
        self.assertPathExists("baz")
1595
1594
        wt.lock_read()
1596
1595
        self.addCleanup(wt.unlock)
1597
 
        self.assertEqual(wt.kind("foo"), "file")
 
1596
        self.assertEqual(wt.kind(wt.path2id("foo")), "file")
1598
1597
 
1599
1598
    def test_no_final_path(self):
1600
1599
        transform, root = self.get_transform()
1605
1604
 
1606
1605
    def test_create_from_tree(self):
1607
1606
        tree1 = self.make_branch_and_tree('tree1')
1608
 
        self.build_tree_contents([('tree1/foo/',), ('tree1/bar', b'baz')])
1609
 
        tree1.add(['foo', 'bar'], [b'foo-id', b'bar-id'])
 
1607
        self.build_tree_contents([('tree1/foo/',), ('tree1/bar', 'baz')])
 
1608
        tree1.add(['foo', 'bar'], ['foo-id', 'bar-id'])
1610
1609
        tree2 = self.make_branch_and_tree('tree2')
1611
1610
        tt = TreeTransform(tree2)
1612
1611
        foo_trans_id = tt.create_path('foo', tt.root)
1613
 
        create_from_tree(tt, foo_trans_id, tree1, 'foo', file_id=b'foo-id')
 
1612
        create_from_tree(tt, foo_trans_id, tree1, 'foo-id')
1614
1613
        bar_trans_id = tt.create_path('bar', tt.root)
1615
 
        create_from_tree(tt, bar_trans_id, tree1, 'bar', file_id='bbar-id')
 
1614
        create_from_tree(tt, bar_trans_id, tree1, 'bar-id')
1616
1615
        tt.apply()
1617
1616
        self.assertEqual('directory', osutils.file_kind('tree2/foo'))
1618
1617
        self.assertFileEqual('baz', 'tree2/bar')
1621
1620
        """Provided lines are used instead of tree content."""
1622
1621
        tree1 = self.make_branch_and_tree('tree1')
1623
1622
        self.build_tree_contents([('tree1/foo', 'bar'),])
1624
 
        tree1.add('foo', b'foo-id')
 
1623
        tree1.add('foo', 'foo-id')
1625
1624
        tree2 = self.make_branch_and_tree('tree2')
1626
1625
        tt = TreeTransform(tree2)
1627
1626
        foo_trans_id = tt.create_path('foo', tt.root)
1628
 
        create_from_tree(tt, foo_trans_id, tree1, 'foo', file_id=b'foo-id',
1629
 
                         bytes='qux')
 
1627
        create_from_tree(tt, foo_trans_id, tree1, 'foo-id', bytes='qux')
1630
1628
        tt.apply()
1631
1629
        self.assertFileEqual('qux', 'tree2/foo')
1632
1630
 
1634
1632
        self.requireFeature(SymlinkFeature)
1635
1633
        tree1 = self.make_branch_and_tree('tree1')
1636
1634
        os.symlink('bar', 'tree1/foo')
1637
 
        tree1.add('foo', b'foo-id')
 
1635
        tree1.add('foo', 'foo-id')
1638
1636
        tt = TreeTransform(self.make_branch_and_tree('tree2'))
1639
1637
        foo_trans_id = tt.create_path('foo', tt.root)
1640
 
        create_from_tree(tt, foo_trans_id, tree1, 'foo', file_id=b'foo-id')
 
1638
        create_from_tree(tt, foo_trans_id, tree1, 'foo-id')
1641
1639
        tt.apply()
1642
1640
        self.assertEqual('bar', os.readlink('tree2/foo'))
1643
1641
 
1651
1649
        self.wt.set_root_id(root_id)
1652
1650
        self.b = self.wt.branch
1653
1651
        self.tt = TreeTransform(self.wt)
1654
 
        self.root = self.tt.trans_id_tree_path('')
 
1652
        self.root = self.tt.trans_id_tree_file_id(self.wt.get_root_id())
1655
1653
 
1656
1654
 
1657
1655
def conflict_text(tree, merge):
1664
1662
    def test_inventory_altered_unchanged(self):
1665
1663
        tree = self.make_branch_and_tree('tree')
1666
1664
        self.build_tree(['tree/foo'])
1667
 
        tree.add('foo', b'foo-id')
 
1665
        tree.add('foo', 'foo-id')
1668
1666
        with TransformPreview(tree) as tt:
1669
1667
            self.assertEqual([], tt._inventory_altered())
1670
1668
 
1671
1669
    def test_inventory_altered_changed_parent_id(self):
1672
1670
        tree = self.make_branch_and_tree('tree')
1673
1671
        self.build_tree(['tree/foo'])
1674
 
        tree.add('foo', b'foo-id')
 
1672
        tree.add('foo', 'foo-id')
1675
1673
        with TransformPreview(tree) as tt:
1676
1674
            tt.unversion_file(tt.root)
1677
 
            tt.version_file(b'new-id', tt.root)
1678
 
            foo_trans_id = tt.trans_id_tree_path('foo')
 
1675
            tt.version_file('new-id', tt.root)
 
1676
            foo_trans_id = tt.trans_id_tree_file_id('foo-id')
1679
1677
            foo_tuple = ('foo', foo_trans_id)
1680
1678
            root_tuple = ('', tt.root)
1681
1679
            self.assertEqual([root_tuple, foo_tuple], tt._inventory_altered())
1683
1681
    def test_inventory_altered_noop_changed_parent_id(self):
1684
1682
        tree = self.make_branch_and_tree('tree')
1685
1683
        self.build_tree(['tree/foo'])
1686
 
        tree.add('foo', b'foo-id')
 
1684
        tree.add('foo', 'foo-id')
1687
1685
        with TransformPreview(tree) as tt:
1688
1686
            tt.unversion_file(tt.root)
1689
1687
            tt.version_file(tree.get_root_id(), tt.root)
1690
 
            foo_trans_id = tt.trans_id_tree_path('foo')
 
1688
            foo_trans_id = tt.trans_id_tree_file_id('foo-id')
1691
1689
            self.assertEqual([], tt._inventory_altered())
1692
1690
 
1693
1691
 
1730
1728
        Merge3Merger(this.wt, this.wt, base.wt, other.wt)
1731
1729
 
1732
1730
        # textual merge
1733
 
        self.assertEqual(this.wt.get_file(this.wt.id2path(b'a')).read(), 'y\nb\nc\nd\bz\n')
 
1731
        self.assertEqual(this.wt.get_file('a').read(), 'y\nb\nc\nd\bz\n')
1734
1732
        # three-way text conflict
1735
 
        self.assertEqual(this.wt.get_file(this.wt.id2path(b'b')).read(),
 
1733
        self.assertEqual(this.wt.get_file('b').read(),
1736
1734
                         conflict_text('b', 'b2'))
1737
1735
        # OTHER wins
1738
 
        self.assertEqual(this.wt.get_file(this.wt.id2path(b'c')).read(), 'c2')
 
1736
        self.assertEqual(this.wt.get_file('c').read(), 'c2')
1739
1737
        # THIS wins
1740
 
        self.assertEqual(this.wt.get_file(this.wt.id2path(b'd')).read(), 'd2')
 
1738
        self.assertEqual(this.wt.get_file('d').read(), 'd2')
1741
1739
        # Ambigious clean merge
1742
 
        self.assertEqual(this.wt.get_file(this.wt.id2path(b'e')).read(), 'e2')
 
1740
        self.assertEqual(this.wt.get_file('e').read(), 'e2')
1743
1741
        # No change
1744
 
        self.assertEqual(this.wt.get_file(this.wt.id2path(b'f')).read(), 'f')
 
1742
        self.assertEqual(this.wt.get_file('f').read(), 'f')
1745
1743
        # Correct correct results when THIS == OTHER
1746
 
        self.assertEqual(this.wt.get_file(this.wt.id2path(b'g')).read(), 'g')
 
1744
        self.assertEqual(this.wt.get_file('g').read(), 'g')
1747
1745
        # Text conflict when THIS & OTHER are text and BASE is dir
1748
 
        self.assertEqual(this.wt.get_file(this.wt.id2path(b'h')).read(),
 
1746
        self.assertEqual(this.wt.get_file('h').read(),
1749
1747
                         conflict_text('1\n2\n3\n4\n', 'h\ni\nj\nk\n'))
1750
 
        self.assertEqual(this.wt.get_file('h.THIS').read(),
 
1748
        self.assertEqual(this.wt.get_file_byname('h.THIS').read(),
1751
1749
                         '1\n2\n3\n4\n')
1752
 
        self.assertEqual(this.wt.get_file('h.OTHER').read(),
 
1750
        self.assertEqual(this.wt.get_file_byname('h.OTHER').read(),
1753
1751
                         'h\ni\nj\nk\n')
1754
1752
        self.assertEqual(file_kind(this.wt.abspath('h.BASE')), 'directory')
1755
 
        self.assertEqual(this.wt.get_file(this.wt.id2path(b'i')).read(),
 
1753
        self.assertEqual(this.wt.get_file('i').read(),
1756
1754
                         conflict_text('1\n2\n3\n4\n', 'h\ni\nj\nk\n'))
1757
 
        self.assertEqual(this.wt.get_file('i.THIS').read(),
 
1755
        self.assertEqual(this.wt.get_file_byname('i.THIS').read(),
1758
1756
                         '1\n2\n3\n4\n')
1759
 
        self.assertEqual(this.wt.get_file('i.OTHER').read(),
 
1757
        self.assertEqual(this.wt.get_file_byname('i.OTHER').read(),
1760
1758
                         'h\ni\nj\nk\n')
1761
1759
        self.assertEqual(os.path.exists(this.wt.abspath('i.BASE')), False)
1762
1760
        modified = ['a', 'b', 'c', 'h', 'i']
1763
1761
        merge_modified = this.wt.merge_modified()
1764
1762
        self.assertSubset(merge_modified, modified)
1765
1763
        self.assertEqual(len(merge_modified), len(modified))
1766
 
        with file(this.wt.abspath(this.wt.id2path('a')), 'wb') as f: f.write('booga')
 
1764
        with file(this.wt.id2abspath('a'), 'wb') as f: f.write('booga')
1767
1765
        modified.pop(0)
1768
1766
        merge_modified = this.wt.merge_modified()
1769
1767
        self.assertSubset(merge_modified, modified)
1800
1798
        for suffix in ('THIS', 'BASE', 'OTHER'):
1801
1799
            self.assertEqual(os.readlink(this.wt.abspath('d.'+suffix)), suffix)
1802
1800
        self.assertIs(os.path.lexists(this.wt.abspath('d')), False)
1803
 
        self.assertEqual(this.wt.id2path(b'd'), 'd.OTHER')
1804
 
        self.assertEqual(this.wt.id2path(b'f'), 'f.THIS')
 
1801
        self.assertEqual(this.wt.id2path('d'), 'd.OTHER')
 
1802
        self.assertEqual(this.wt.id2path('f'), 'f.THIS')
1805
1803
        self.assertEqual(os.readlink(this.wt.abspath('e')), 'other-e')
1806
1804
        self.assertIs(os.path.lexists(this.wt.abspath('e.THIS')), False)
1807
1805
        self.assertIs(os.path.lexists(this.wt.abspath('e.OTHER')), False)
1841
1839
        for tg in [this, base, other]:
1842
1840
            tg.tt.apply()
1843
1841
        Merge3Merger(this.wt, this.wt, base.wt, other.wt)
1844
 
        self.assertEqual(this.wt.id2path(b'c'), pathjoin('b/c1'))
1845
 
        self.assertEqual(this.wt.id2path(b'd'), pathjoin('b/d1'))
1846
 
        self.assertEqual(this.wt.id2path(b'e'), pathjoin('b/e1'))
1847
 
        self.assertEqual(this.wt.id2path(b'f'), pathjoin('b/f1'))
 
1842
        self.assertEqual(this.wt.id2path('c'), pathjoin('b/c1'))
 
1843
        self.assertEqual(this.wt.id2path('d'), pathjoin('b/d1'))
 
1844
        self.assertEqual(this.wt.id2path('e'), pathjoin('b/e1'))
 
1845
        self.assertEqual(this.wt.id2path('f'), pathjoin('b/f1'))
1848
1846
 
1849
1847
    def test_filename_merge_conflicts(self):
1850
1848
        root_id = generate_ids.gen_root_id()
1869
1867
            tg.tt.apply()
1870
1868
        Merge3Merger(this.wt, this.wt, base.wt, other.wt)
1871
1869
 
1872
 
        self.assertEqual(this.wt.id2path(b'g'), pathjoin('b/g1.OTHER'))
 
1870
        self.assertEqual(this.wt.id2path('g'), pathjoin('b/g1.OTHER'))
1873
1871
        self.assertIs(os.path.lexists(this.wt.abspath('b/g1.BASE')), True)
1874
1872
        self.assertIs(os.path.lexists(this.wt.abspath('b/g1.THIS')), False)
1875
 
        self.assertEqual(this.wt.id2path(b'h'), pathjoin('b/h1.THIS'))
 
1873
        self.assertEqual(this.wt.id2path('h'), pathjoin('b/h1.THIS'))
1876
1874
        self.assertIs(os.path.lexists(this.wt.abspath('b/h1.BASE')), True)
1877
1875
        self.assertIs(os.path.lexists(this.wt.abspath('b/h1.OTHER')), False)
1878
 
        self.assertEqual(this.wt.id2path(b'i'), pathjoin('b/i1.OTHER'))
 
1876
        self.assertEqual(this.wt.id2path('i'), pathjoin('b/i1.OTHER'))
1879
1877
 
1880
1878
 
1881
1879
class TestBuildTree(tests.TestCaseWithTransport):
2035
2033
    def create_ab_tree(self):
2036
2034
        """Create a committed test tree with two files"""
2037
2035
        source = self.make_branch_and_tree('source')
2038
 
        self.build_tree_contents([('source/file1', b'A')])
2039
 
        self.build_tree_contents([('source/file2', b'B')])
2040
 
        source.add(['file1', 'file2'], [b'file1-id', b'file2-id'])
 
2036
        self.build_tree_contents([('source/file1', 'A')])
 
2037
        self.build_tree_contents([('source/file2', 'B')])
 
2038
        source.add(['file1', 'file2'], ['file1-id', 'file2-id'])
2041
2039
        source.commit('commit files')
2042
2040
        source.lock_write()
2043
2041
        self.addCleanup(source.unlock)
2045
2043
 
2046
2044
    def test_build_tree_accelerator_tree(self):
2047
2045
        source = self.create_ab_tree()
2048
 
        self.build_tree_contents([('source/file2', b'C')])
 
2046
        self.build_tree_contents([('source/file2', 'C')])
2049
2047
        calls = []
2050
2048
        real_source_get_file = source.get_file
2051
 
        def get_file(path, file_id=None):
 
2049
        def get_file(file_id, path=None):
2052
2050
            calls.append(file_id)
2053
 
            return real_source_get_file(path, file_id)
 
2051
            return real_source_get_file(file_id, path)
2054
2052
        source.get_file = get_file
2055
2053
        target = self.make_branch_and_tree('target')
2056
2054
        revision_tree = source.basis_tree()
2090
2088
    def test_build_tree_accelerator_wrong_kind(self):
2091
2089
        self.requireFeature(SymlinkFeature)
2092
2090
        source = self.make_branch_and_tree('source')
2093
 
        self.build_tree_contents([('source/file1', b'')])
2094
 
        self.build_tree_contents([('source/file2', b'')])
2095
 
        source.add(['file1', 'file2'], [b'file1-id', b'file2-id'])
 
2091
        self.build_tree_contents([('source/file1', '')])
 
2092
        self.build_tree_contents([('source/file2', '')])
 
2093
        source.add(['file1', 'file2'], ['file1-id', 'file2-id'])
2096
2094
        source.commit('commit files')
2097
2095
        os.unlink('source/file2')
2098
 
        self.build_tree_contents([('source/file2/', b'C')])
 
2096
        self.build_tree_contents([('source/file2/', 'C')])
2099
2097
        os.unlink('source/file1')
2100
2098
        os.symlink('file2', 'source/file1')
2101
2099
        calls = []
2102
2100
        real_source_get_file = source.get_file
2103
 
        def get_file(path, file_id=None):
 
2101
        def get_file(file_id, path=None):
2104
2102
            calls.append(file_id)
2105
 
            return real_source_get_file(path, file_id)
 
2103
            return real_source_get_file(file_id, path)
2106
2104
        source.get_file = get_file
2107
2105
        target = self.make_branch_and_tree('target')
2108
2106
        revision_tree = source.basis_tree()
2141
2139
 
2142
2140
    def test_build_tree_accelerator_tree_moved(self):
2143
2141
        source = self.make_branch_and_tree('source')
2144
 
        self.build_tree_contents([('source/file1', b'A')])
2145
 
        source.add(['file1'], [b'file1-id'])
 
2142
        self.build_tree_contents([('source/file1', 'A')])
 
2143
        source.add(['file1'], ['file1-id'])
2146
2144
        source.commit('commit files')
2147
2145
        source.rename_one('file1', 'file2')
2148
2146
        source.lock_read()
2160
2158
        self.requireFeature(HardlinkFeature)
2161
2159
        source = self.create_ab_tree()
2162
2160
        tt = TreeTransform(source)
2163
 
        trans_id = tt.trans_id_tree_path('file1')
 
2161
        trans_id = tt.trans_id_tree_file_id('file1-id')
2164
2162
        tt.set_executability(True, trans_id)
2165
2163
        tt.apply()
2166
 
        self.assertTrue(source.is_executable('file1'))
 
2164
        self.assertTrue(source.is_executable('file1-id'))
2167
2165
        target = self.make_branch_and_tree('target')
2168
2166
        revision_tree = source.basis_tree()
2169
2167
        revision_tree.lock_read()
2172
2170
        target.lock_read()
2173
2171
        self.addCleanup(target.unlock)
2174
2172
        self.assertEqual([], list(target.iter_changes(revision_tree)))
2175
 
        self.assertTrue(source.is_executable('file1'))
 
2173
        self.assertTrue(source.is_executable('file1-id'))
2176
2174
 
2177
2175
    def install_rot13_content_filter(self, pattern):
2178
2176
        # We could use
2228
2226
            raise tests.UnavailableFeature('Fully case sensitive filesystem')
2229
2227
        source = self.make_branch_and_tree('source')
2230
2228
        self.build_tree(['source/file', 'source/FILE'])
2231
 
        source.add(['file', 'FILE'], [b'lower-id', b'upper-id'])
 
2229
        source.add(['file', 'FILE'], ['lower-id', 'upper-id'])
2232
2230
        source.commit('added files')
2233
2231
        # Don't try this at home, kids!
2234
2232
        # Force the tree to report that it is case insensitive
2235
2233
        target = self.make_branch_and_tree('target')
2236
2234
        target.case_sensitive = False
2237
2235
        build_tree(source.basis_tree(), target, source, delta_from_tree=True)
2238
 
        self.assertEqual('file.moved', target.id2path(b'lower-id'))
2239
 
        self.assertEqual('FILE', target.id2path(b'upper-id'))
 
2236
        self.assertEqual('file.moved', target.id2path('lower-id'))
 
2237
        self.assertEqual('FILE', target.id2path('upper-id'))
2240
2238
 
2241
2239
    def test_build_tree_observes_sha(self):
2242
2240
        source = self.make_branch_and_tree('source')
2243
2241
        self.build_tree(['source/file1', 'source/dir/', 'source/dir/file2'])
2244
2242
        source.add(['file1', 'dir', 'dir/file2'],
2245
 
                   [b'file1-id', b'dir-id', b'file2-id'])
 
2243
                   ['file1-id', 'dir-id', 'file2-id'])
2246
2244
        source.commit('new files')
2247
2245
        target = self.make_branch_and_tree('target')
2248
2246
        target.lock_write()
2268
2266
        entry2_state = entry2[1][0]
2269
2267
        # Now, make sure that we don't have to re-read the content. The
2270
2268
        # packed_stat should match exactly.
2271
 
        self.assertEqual(entry1_sha, target.get_file_sha1('file1', b'file1-id'))
 
2269
        self.assertEqual(entry1_sha, target.get_file_sha1('file1-id', 'file1'))
2272
2270
        self.assertEqual(entry2_sha,
2273
 
                         target.get_file_sha1('dir/file2', b'file2-id'))
 
2271
                         target.get_file_sha1('file2-id', 'dir/file2'))
2274
2272
        self.assertEqual(entry1_state, entry1[1][0])
2275
2273
        self.assertEqual(entry2_state, entry2[1][0])
2276
2274
 
2339
2337
 
2340
2338
    def test_add_files(self):
2341
2339
        branch, tt = self.get_branch_and_transform()
2342
 
        tt.new_file('file', tt.root, 'contents', b'file-id')
 
2340
        tt.new_file('file', tt.root, 'contents', 'file-id')
2343
2341
        trans_id = tt.new_directory('dir', tt.root, 'dir-id')
2344
2342
        if SymlinkFeature.available():
2345
2343
            tt.new_symlink('symlink', trans_id, 'target', 'symlink-id')
2346
2344
        rev = tt.commit(branch, 'message')
2347
2345
        tree = branch.basis_tree()
2348
 
        self.assertEqual('file', tree.id2path(b'file-id'))
2349
 
        self.assertEqual('contents', tree.get_file_text('file', b'file-id'))
2350
 
        self.assertEqual('dir', tree.id2path(b'dir-id'))
 
2346
        self.assertEqual('file', tree.id2path('file-id'))
 
2347
        self.assertEqual('contents', tree.get_file_text('file-id'))
 
2348
        self.assertEqual('dir', tree.id2path('dir-id'))
2351
2349
        if SymlinkFeature.available():
2352
 
            self.assertEqual('dir/symlink', tree.id2path(b'symlink-id'))
2353
 
            self.assertEqual('target', tree.get_symlink_target('dir/symlink'))
 
2350
            self.assertEqual('dir/symlink', tree.id2path('symlink-id'))
 
2351
            self.assertEqual('target', tree.get_symlink_target('symlink-id'))
2354
2352
 
2355
2353
    def test_add_unversioned(self):
2356
2354
        branch, tt = self.get_branch_and_transform()
2360
2358
 
2361
2359
    def test_modify_strict(self):
2362
2360
        branch, tt = self.get_branch_and_transform()
2363
 
        tt.new_file('file', tt.root, 'contents', b'file-id')
 
2361
        tt.new_file('file', tt.root, 'contents', 'file-id')
2364
2362
        tt.commit(branch, 'message', strict=True)
2365
2363
        tt = TransformPreview(branch.basis_tree())
2366
2364
        self.addCleanup(tt.finalize)
2376
2374
        """
2377
2375
        branch, tt = self.get_branch_and_transform()
2378
2376
        parent_id = tt.trans_id_file_id('parent-id')
2379
 
        tt.new_file('file', parent_id, 'contents', b'file-id')
 
2377
        tt.new_file('file', parent_id, 'contents', 'file-id')
2380
2378
        self.assertRaises(errors.MalformedTransform, tt.commit, branch,
2381
2379
                          'message')
2382
2380
 
2457
2455
        mover.rename('c/e', 'c/d')
2458
2456
        try:
2459
2457
            mover.rename('a', 'c')
2460
 
        except errors.FileExists as e:
 
2458
        except errors.FileExists, e:
2461
2459
            mover.rollback()
2462
2460
        self.assertPathExists('a')
2463
2461
        self.assertPathExists('c/d')
2538
2536
    def _override_globals_in_method(self, instance, method_name, globals):
2539
2537
        """Replace method on instance with one with updated globals"""
2540
2538
        import types
2541
 
        func = getattr(instance, method_name).__func__
2542
 
        new_globals = dict(func.__globals__)
 
2539
        func = getattr(instance, method_name).im_func
 
2540
        new_globals = dict(func.func_globals)
2543
2541
        new_globals.update(globals)
2544
 
        new_func = types.FunctionType(func.__code__, new_globals,
2545
 
            func.__name__, func.__defaults__)
 
2542
        new_func = types.FunctionType(func.func_code, new_globals,
 
2543
            func.func_name, func.func_defaults)
2546
2544
        setattr(instance, method_name,
2547
2545
            types.MethodType(new_func, instance, instance.__class__))
2548
2546
        self.addCleanup(delattr, instance, method_name)
2661
2659
    def make_tt_with_versioned_dir(self):
2662
2660
        wt = self.make_branch_and_tree('.')
2663
2661
        self.build_tree(['dir/',])
2664
 
        wt.add(['dir'], [b'dir-id'])
 
2662
        wt.add(['dir'], ['dir-id'])
2665
2663
        wt.commit('Create dir')
2666
2664
        tt = TreeTransform(wt)
2667
2665
        self.addCleanup(tt.finalize)
2669
2667
 
2670
2668
    def test_resolve_create_parent_for_versioned_file(self):
2671
2669
        wt, tt = self.make_tt_with_versioned_dir()
2672
 
        dir_tid = tt.trans_id_tree_path('dir')
2673
 
        file_tid = tt.new_file('file', dir_tid, 'Contents', file_id=b'file-id')
 
2670
        dir_tid = tt.trans_id_tree_file_id('dir-id')
 
2671
        file_tid = tt.new_file('file', dir_tid, 'Contents', file_id='file-id')
2674
2672
        tt.delete_contents(dir_tid)
2675
2673
        tt.unversion_file(dir_tid)
2676
2674
        conflicts = resolve_conflicts(tt)
2680
2678
 
2681
2679
    def test_non_versioned_file_create_conflict(self):
2682
2680
        wt, tt = self.make_tt_with_versioned_dir()
2683
 
        dir_tid = tt.trans_id_tree_path('dir')
 
2681
        dir_tid = tt.trans_id_tree_file_id('dir-id')
2684
2682
        tt.new_file('file', dir_tid, 'Contents')
2685
2683
        tt.delete_contents(dir_tid)
2686
2684
        tt.unversion_file(dir_tid)
2702
2700
 
2703
2701
    def create_tree(self):
2704
2702
        tree = self.make_branch_and_tree('.')
2705
 
        self.build_tree_contents([('a', b'content 1')])
2706
 
        tree.set_root_id(b'TREE_ROOT')
2707
 
        tree.add('a', b'a-id')
2708
 
        tree.commit('rev1', rev_id=b'rev1')
 
2703
        self.build_tree_contents([('a', 'content 1')])
 
2704
        tree.set_root_id('TREE_ROOT')
 
2705
        tree.add('a', 'a-id')
 
2706
        tree.commit('rev1', rev_id='rev1')
2709
2707
        return tree.branch.repository.revision_tree('rev1')
2710
2708
 
2711
2709
    def get_empty_preview(self):
2732
2730
        self.addCleanup(preview.finalize)
2733
2731
        preview.new_file('file2', preview.root, 'content B\n', 'file2-id')
2734
2732
        preview_tree = preview.get_preview_tree()
2735
 
        self.assertEqual(preview_tree.kind('file2'), 'file')
 
2733
        self.assertEqual(preview_tree.kind('file2-id'), 'file')
2736
2734
        self.assertEqual(
2737
 
            preview_tree.get_file('file2', 'file2-id').read(), 'content B\n')
 
2735
            preview_tree.get_file('file2-id').read(), 'content B\n')
2738
2736
 
2739
2737
    def test_diff_preview_tree(self):
2740
2738
        revision_tree = self.create_tree()
2742
2740
        self.addCleanup(preview.finalize)
2743
2741
        preview.new_file('file2', preview.root, 'content B\n', 'file2-id')
2744
2742
        preview_tree = preview.get_preview_tree()
2745
 
        out = BytesIO()
 
2743
        out = StringIO()
2746
2744
        show_diff_trees(revision_tree, preview_tree, out)
2747
2745
        lines = out.getvalue().splitlines()
2748
2746
        self.assertEqual(lines[0], "=== added file 'file2'")
2816
2814
        revision_tree = self.create_tree()
2817
2815
        preview = TransformPreview(revision_tree)
2818
2816
        self.addCleanup(preview.finalize)
2819
 
        preview.new_file('file', preview.root, 'contents', b'file-id')
 
2817
        preview.new_file('file', preview.root, 'contents', 'file-id')
2820
2818
        preview.new_directory('directory', preview.root, 'dir-id')
2821
2819
        preview_tree = preview.get_preview_tree()
2822
 
        self.assertEqual('file', preview_tree.kind('file'))
2823
 
        self.assertEqual('directory', preview_tree.kind('directory'))
 
2820
        self.assertEqual('file', preview_tree.kind('file-id'))
 
2821
        self.assertEqual('directory', preview_tree.kind('dir-id'))
2824
2822
 
2825
2823
    def test_get_file_mtime(self):
2826
2824
        preview = self.get_empty_preview()
2827
2825
        file_trans_id = preview.new_file('file', preview.root, 'contents',
2828
 
                                         b'file-id')
 
2826
                                         'file-id')
2829
2827
        limbo_path = preview._limbo_name(file_trans_id)
2830
2828
        preview_tree = preview.get_preview_tree()
2831
2829
        self.assertEqual(os.stat(limbo_path).st_mtime,
2832
 
                         preview_tree.get_file_mtime('file', b'file-id'))
 
2830
                         preview_tree.get_file_mtime('file-id'))
2833
2831
 
2834
2832
    def test_get_file_mtime_renamed(self):
2835
2833
        work_tree = self.make_branch_and_tree('tree')
2836
2834
        self.build_tree(['tree/file'])
2837
 
        work_tree.add('file', b'file-id')
 
2835
        work_tree.add('file', 'file-id')
2838
2836
        preview = TransformPreview(work_tree)
2839
2837
        self.addCleanup(preview.finalize)
2840
 
        file_trans_id = preview.trans_id_tree_path('file')
 
2838
        file_trans_id = preview.trans_id_tree_file_id('file-id')
2841
2839
        preview.adjust_path('renamed', preview.root, file_trans_id)
2842
2840
        preview_tree = preview.get_preview_tree()
2843
 
        preview_mtime = preview_tree.get_file_mtime('renamed', b'file-id')
2844
 
        work_mtime = work_tree.get_file_mtime('file', b'file-id')
 
2841
        preview_mtime = preview_tree.get_file_mtime('file-id', 'renamed')
 
2842
        work_mtime = work_tree.get_file_mtime('file-id', 'file')
2845
2843
 
2846
2844
    def test_get_file_size(self):
2847
2845
        work_tree = self.make_branch_and_tree('tree')
2848
 
        self.build_tree_contents([('tree/old', b'old')])
2849
 
        work_tree.add('old', b'old-id')
 
2846
        self.build_tree_contents([('tree/old', 'old')])
 
2847
        work_tree.add('old', 'old-id')
2850
2848
        preview = TransformPreview(work_tree)
2851
2849
        self.addCleanup(preview.finalize)
2852
 
        new_id = preview.new_file('name', preview.root, 'contents', b'new-id',
 
2850
        new_id = preview.new_file('name', preview.root, 'contents', 'new-id',
2853
2851
                                  'executable')
2854
2852
        tree = preview.get_preview_tree()
2855
 
        self.assertEqual(len('old'), tree.get_file_size('old'))
2856
 
        self.assertEqual(len('contents'), tree.get_file_size('name'))
 
2853
        self.assertEqual(len('old'), tree.get_file_size('old-id'))
 
2854
        self.assertEqual(len('contents'), tree.get_file_size('new-id'))
2857
2855
 
2858
2856
    def test_get_file(self):
2859
2857
        preview = self.get_empty_preview()
2860
 
        preview.new_file('file', preview.root, 'contents', b'file-id')
 
2858
        preview.new_file('file', preview.root, 'contents', 'file-id')
2861
2859
        preview_tree = preview.get_preview_tree()
2862
 
        tree_file = preview_tree.get_file('file')
 
2860
        tree_file = preview_tree.get_file('file-id')
2863
2861
        try:
2864
2862
            self.assertEqual('contents', tree_file.read())
2865
2863
        finally:
2871
2869
        preview.new_symlink('symlink', preview.root, 'target', 'symlink-id')
2872
2870
        preview_tree = preview.get_preview_tree()
2873
2871
        self.assertEqual('target',
2874
 
                         preview_tree.get_symlink_target('symlink'))
 
2872
                         preview_tree.get_symlink_target('symlink-id'))
2875
2873
 
2876
2874
    def test_all_file_ids(self):
2877
2875
        tree = self.make_branch_and_tree('tree')
2878
2876
        self.build_tree(['tree/a', 'tree/b', 'tree/c'])
2879
 
        tree.add(['a', 'b', 'c'], [b'a-id', b'b-id', b'c-id'])
 
2877
        tree.add(['a', 'b', 'c'], ['a-id', 'b-id', 'c-id'])
2880
2878
        preview = TransformPreview(tree)
2881
2879
        self.addCleanup(preview.finalize)
2882
 
        preview.unversion_file(preview.trans_id_file_id(b'b-id'))
2883
 
        c_trans_id = preview.trans_id_file_id(b'c-id')
 
2880
        preview.unversion_file(preview.trans_id_file_id('b-id'))
 
2881
        c_trans_id = preview.trans_id_file_id('c-id')
2884
2882
        preview.unversion_file(c_trans_id)
2885
 
        preview.version_file(b'c-id', c_trans_id)
 
2883
        preview.version_file('c-id', c_trans_id)
2886
2884
        preview_tree = preview.get_preview_tree()
2887
 
        self.assertEqual({b'a-id', b'c-id', tree.get_root_id()},
 
2885
        self.assertEqual(set(['a-id', 'c-id', tree.get_root_id()]),
2888
2886
                         preview_tree.all_file_ids())
2889
2887
 
2890
2888
    def test_path2id_deleted_unchanged(self):
2891
2889
        tree = self.make_branch_and_tree('tree')
2892
2890
        self.build_tree(['tree/unchanged', 'tree/deleted'])
2893
 
        tree.add(['unchanged', 'deleted'], [b'unchanged-id', b'deleted-id'])
 
2891
        tree.add(['unchanged', 'deleted'], ['unchanged-id', 'deleted-id'])
2894
2892
        preview = TransformPreview(tree)
2895
2893
        self.addCleanup(preview.finalize)
2896
 
        preview.unversion_file(preview.trans_id_file_id(b'deleted-id'))
 
2894
        preview.unversion_file(preview.trans_id_file_id('deleted-id'))
2897
2895
        preview_tree = preview.get_preview_tree()
2898
 
        self.assertEqual(b'unchanged-id', preview_tree.path2id('unchanged'))
2899
 
        self.assertFalse(preview_tree.is_versioned('deleted'))
 
2896
        self.assertEqual('unchanged-id', preview_tree.path2id('unchanged'))
 
2897
        self.assertIs(None, preview_tree.path2id('deleted'))
2900
2898
 
2901
2899
    def test_path2id_created(self):
2902
2900
        tree = self.make_branch_and_tree('tree')
2903
2901
        self.build_tree(['tree/unchanged'])
2904
 
        tree.add(['unchanged'], [b'unchanged-id'])
 
2902
        tree.add(['unchanged'], ['unchanged-id'])
2905
2903
        preview = TransformPreview(tree)
2906
2904
        self.addCleanup(preview.finalize)
2907
 
        preview.new_file('new', preview.trans_id_file_id(b'unchanged-id'),
 
2905
        preview.new_file('new', preview.trans_id_file_id('unchanged-id'),
2908
2906
            'contents', 'new-id')
2909
2907
        preview_tree = preview.get_preview_tree()
2910
 
        self.assertEqual(b'new-id', preview_tree.path2id('unchanged/new'))
 
2908
        self.assertEqual('new-id', preview_tree.path2id('unchanged/new'))
2911
2909
 
2912
2910
    def test_path2id_moved(self):
2913
2911
        tree = self.make_branch_and_tree('tree')
2914
2912
        self.build_tree(['tree/old_parent/', 'tree/old_parent/child'])
2915
2913
        tree.add(['old_parent', 'old_parent/child'],
2916
 
                 [b'old_parent-id', b'child-id'])
 
2914
                 ['old_parent-id', 'child-id'])
2917
2915
        preview = TransformPreview(tree)
2918
2916
        self.addCleanup(preview.finalize)
2919
2917
        new_parent = preview.new_directory('new_parent', preview.root,
2920
 
                                           b'new_parent-id')
 
2918
                                           'new_parent-id')
2921
2919
        preview.adjust_path('child', new_parent,
2922
 
                            preview.trans_id_file_id(b'child-id'))
 
2920
                            preview.trans_id_file_id('child-id'))
2923
2921
        preview_tree = preview.get_preview_tree()
2924
 
        self.assertFalse(preview_tree.is_versioned('old_parent/child'))
2925
 
        self.assertEqual(b'child-id', preview_tree.path2id('new_parent/child'))
 
2922
        self.assertIs(None, preview_tree.path2id('old_parent/child'))
 
2923
        self.assertEqual('child-id', preview_tree.path2id('new_parent/child'))
2926
2924
 
2927
2925
    def test_path2id_renamed_parent(self):
2928
2926
        tree = self.make_branch_and_tree('tree')
2929
2927
        self.build_tree(['tree/old_name/', 'tree/old_name/child'])
2930
2928
        tree.add(['old_name', 'old_name/child'],
2931
 
                 [b'parent-id', b'child-id'])
 
2929
                 ['parent-id', 'child-id'])
2932
2930
        preview = TransformPreview(tree)
2933
2931
        self.addCleanup(preview.finalize)
2934
2932
        preview.adjust_path('new_name', preview.root,
2935
 
                            preview.trans_id_file_id(b'parent-id'))
 
2933
                            preview.trans_id_file_id('parent-id'))
2936
2934
        preview_tree = preview.get_preview_tree()
2937
 
        self.assertFalse(preview_tree.is_versioned('old_name/child'))
2938
 
        self.assertEqual(b'child-id', preview_tree.path2id('new_name/child'))
 
2935
        self.assertIs(None, preview_tree.path2id('old_name/child'))
 
2936
        self.assertEqual('child-id', preview_tree.path2id('new_name/child'))
2939
2937
 
2940
 
    def assertMatchingIterEntries(self, tt, specific_files=None):
 
2938
    def assertMatchingIterEntries(self, tt, specific_file_ids=None):
2941
2939
        preview_tree = tt.get_preview_tree()
2942
2940
        preview_result = list(preview_tree.iter_entries_by_dir(
2943
 
                              specific_files=specific_files))
 
2941
                              specific_file_ids))
2944
2942
        tree = tt._tree
2945
2943
        tt.apply()
2946
 
        actual_result = list(tree.iter_entries_by_dir(
2947
 
            specific_files=specific_files))
 
2944
        actual_result = list(tree.iter_entries_by_dir(specific_file_ids))
2948
2945
        self.assertEqual(actual_result, preview_result)
2949
2946
 
2950
2947
    def test_iter_entries_by_dir_new(self):
2951
2948
        tree = self.make_branch_and_tree('tree')
2952
2949
        tt = TreeTransform(tree)
2953
 
        tt.new_file('new', tt.root, 'contents', b'new-id')
 
2950
        tt.new_file('new', tt.root, 'contents', 'new-id')
2954
2951
        self.assertMatchingIterEntries(tt)
2955
2952
 
2956
2953
    def test_iter_entries_by_dir_deleted(self):
2957
2954
        tree = self.make_branch_and_tree('tree')
2958
2955
        self.build_tree(['tree/deleted'])
2959
 
        tree.add('deleted', b'deleted-id')
 
2956
        tree.add('deleted', 'deleted-id')
2960
2957
        tt = TreeTransform(tree)
2961
 
        tt.delete_contents(tt.trans_id_file_id(b'deleted-id'))
 
2958
        tt.delete_contents(tt.trans_id_file_id('deleted-id'))
2962
2959
        self.assertMatchingIterEntries(tt)
2963
2960
 
2964
2961
    def test_iter_entries_by_dir_unversioned(self):
2965
2962
        tree = self.make_branch_and_tree('tree')
2966
2963
        self.build_tree(['tree/removed'])
2967
 
        tree.add('removed', b'removed-id')
 
2964
        tree.add('removed', 'removed-id')
2968
2965
        tt = TreeTransform(tree)
2969
 
        tt.unversion_file(tt.trans_id_file_id(b'removed-id'))
 
2966
        tt.unversion_file(tt.trans_id_file_id('removed-id'))
2970
2967
        self.assertMatchingIterEntries(tt)
2971
2968
 
2972
2969
    def test_iter_entries_by_dir_moved(self):
2973
2970
        tree = self.make_branch_and_tree('tree')
2974
2971
        self.build_tree(['tree/moved', 'tree/new_parent/'])
2975
 
        tree.add(['moved', 'new_parent'], [b'moved-id', b'new_parent-id'])
 
2972
        tree.add(['moved', 'new_parent'], ['moved-id', 'new_parent-id'])
2976
2973
        tt = TreeTransform(tree)
2977
 
        tt.adjust_path('moved', tt.trans_id_file_id(b'new_parent-id'),
2978
 
                       tt.trans_id_file_id(b'moved-id'))
 
2974
        tt.adjust_path('moved', tt.trans_id_file_id('new_parent-id'),
 
2975
                       tt.trans_id_file_id('moved-id'))
2979
2976
        self.assertMatchingIterEntries(tt)
2980
2977
 
2981
 
    def test_iter_entries_by_dir_specific_files(self):
 
2978
    def test_iter_entries_by_dir_specific_file_ids(self):
2982
2979
        tree = self.make_branch_and_tree('tree')
2983
 
        tree.set_root_id(b'tree-root-id')
 
2980
        tree.set_root_id('tree-root-id')
2984
2981
        self.build_tree(['tree/parent/', 'tree/parent/child'])
2985
 
        tree.add(['parent', 'parent/child'], [b'parent-id', b'child-id'])
 
2982
        tree.add(['parent', 'parent/child'], ['parent-id', 'child-id'])
2986
2983
        tt = TreeTransform(tree)
2987
 
        self.assertMatchingIterEntries(tt, ['', 'parent/child'])
 
2984
        self.assertMatchingIterEntries(tt, ['tree-root-id', 'child-id'])
2988
2985
 
2989
2986
    def test_symlink_content_summary(self):
2990
2987
        self.requireFeature(SymlinkFeature)
2991
2988
        preview = self.get_empty_preview()
2992
 
        preview.new_symlink('path', preview.root, 'target', b'path-id')
 
2989
        preview.new_symlink('path', preview.root, 'target', 'path-id')
2993
2990
        summary = preview.get_preview_tree().path_content_summary('path')
2994
2991
        self.assertEqual(('symlink', None, None, 'target'), summary)
2995
2992
 
3062
3059
 
3063
3060
    def test_annotate(self):
3064
3061
        tree = self.make_branch_and_tree('tree')
3065
 
        self.build_tree_contents([('tree/file', b'a\n')])
3066
 
        tree.add('file', b'file-id')
3067
 
        tree.commit('a', rev_id=b'one')
3068
 
        self.build_tree_contents([('tree/file', b'a\nb\n')])
 
3062
        self.build_tree_contents([('tree/file', 'a\n')])
 
3063
        tree.add('file', 'file-id')
 
3064
        tree.commit('a', rev_id='one')
 
3065
        self.build_tree_contents([('tree/file', 'a\nb\n')])
3069
3066
        preview = TransformPreview(tree)
3070
3067
        self.addCleanup(preview.finalize)
3071
 
        file_trans_id = preview.trans_id_file_id(b'file-id')
 
3068
        file_trans_id = preview.trans_id_file_id('file-id')
3072
3069
        preview.delete_contents(file_trans_id)
3073
3070
        preview.create_file('a\nb\nc\n', file_trans_id)
3074
3071
        preview_tree = preview.get_preview_tree()
3077
3074
            ('me:', 'b\n'),
3078
3075
            ('me:', 'c\n'),
3079
3076
        ]
3080
 
        annotation = preview_tree.annotate_iter('file', default_revision=b'me:')
 
3077
        annotation = preview_tree.annotate_iter('file-id', 'me:')
3081
3078
        self.assertEqual(expected, annotation)
3082
3079
 
3083
3080
    def test_annotate_missing(self):
3084
3081
        preview = self.get_empty_preview()
3085
 
        preview.new_file('file', preview.root, 'a\nb\nc\n', b'file-id')
 
3082
        preview.new_file('file', preview.root, 'a\nb\nc\n', 'file-id')
3086
3083
        preview_tree = preview.get_preview_tree()
3087
3084
        expected = [
3088
3085
            ('me:', 'a\n'),
3089
3086
            ('me:', 'b\n'),
3090
3087
            ('me:', 'c\n'),
3091
3088
         ]
3092
 
        annotation = preview_tree.annotate_iter('file', default_revision=b'me:')
 
3089
        annotation = preview_tree.annotate_iter('file-id', 'me:')
3093
3090
        self.assertEqual(expected, annotation)
3094
3091
 
3095
3092
    def test_annotate_rename(self):
3096
3093
        tree = self.make_branch_and_tree('tree')
3097
 
        self.build_tree_contents([('tree/file', b'a\n')])
3098
 
        tree.add('file', b'file-id')
3099
 
        tree.commit('a', rev_id=b'one')
 
3094
        self.build_tree_contents([('tree/file', 'a\n')])
 
3095
        tree.add('file', 'file-id')
 
3096
        tree.commit('a', rev_id='one')
3100
3097
        preview = TransformPreview(tree)
3101
3098
        self.addCleanup(preview.finalize)
3102
 
        file_trans_id = preview.trans_id_file_id(b'file-id')
 
3099
        file_trans_id = preview.trans_id_file_id('file-id')
3103
3100
        preview.adjust_path('newname', preview.root, file_trans_id)
3104
3101
        preview_tree = preview.get_preview_tree()
3105
3102
        expected = [
3106
3103
            ('one', 'a\n'),
3107
3104
        ]
3108
 
        annotation = preview_tree.annotate_iter('file', default_revision=b'me:')
 
3105
        annotation = preview_tree.annotate_iter('file-id', 'me:')
3109
3106
        self.assertEqual(expected, annotation)
3110
3107
 
3111
3108
    def test_annotate_deleted(self):
3112
3109
        tree = self.make_branch_and_tree('tree')
3113
 
        self.build_tree_contents([('tree/file', b'a\n')])
3114
 
        tree.add('file', b'file-id')
3115
 
        tree.commit('a', rev_id=b'one')
3116
 
        self.build_tree_contents([('tree/file', b'a\nb\n')])
 
3110
        self.build_tree_contents([('tree/file', 'a\n')])
 
3111
        tree.add('file', 'file-id')
 
3112
        tree.commit('a', rev_id='one')
 
3113
        self.build_tree_contents([('tree/file', 'a\nb\n')])
3117
3114
        preview = TransformPreview(tree)
3118
3115
        self.addCleanup(preview.finalize)
3119
 
        file_trans_id = preview.trans_id_file_id(b'file-id')
 
3116
        file_trans_id = preview.trans_id_file_id('file-id')
3120
3117
        preview.delete_contents(file_trans_id)
3121
3118
        preview_tree = preview.get_preview_tree()
3122
 
        annotation = preview_tree.annotate_iter('file', default_revision=b'me:')
 
3119
        annotation = preview_tree.annotate_iter('file-id', 'me:')
3123
3120
        self.assertIs(None, annotation)
3124
3121
 
3125
3122
    def test_stored_kind(self):
3126
3123
        preview = self.get_empty_preview()
3127
 
        preview.new_file('file', preview.root, 'a\nb\nc\n', b'file-id')
 
3124
        preview.new_file('file', preview.root, 'a\nb\nc\n', 'file-id')
3128
3125
        preview_tree = preview.get_preview_tree()
3129
 
        self.assertEqual('file', preview_tree.stored_kind('file'))
 
3126
        self.assertEqual('file', preview_tree.stored_kind('file-id'))
3130
3127
 
3131
3128
    def test_is_executable(self):
3132
3129
        preview = self.get_empty_preview()
3133
 
        preview.new_file('file', preview.root, 'a\nb\nc\n', b'file-id')
3134
 
        preview.set_executability(True, preview.trans_id_file_id(b'file-id'))
 
3130
        preview.new_file('file', preview.root, 'a\nb\nc\n', 'file-id')
 
3131
        preview.set_executability(True, preview.trans_id_file_id('file-id'))
3135
3132
        preview_tree = preview.get_preview_tree()
3136
 
        self.assertEqual(True, preview_tree.is_executable('file'))
 
3133
        self.assertEqual(True, preview_tree.is_executable('file-id'))
3137
3134
 
3138
3135
    def test_get_set_parent_ids(self):
3139
3136
        revision_tree, preview_tree = self.get_tree_and_preview_tree()
3140
3137
        self.assertEqual([], preview_tree.get_parent_ids())
3141
 
        preview_tree.set_parent_ids([b'rev-1'])
3142
 
        self.assertEqual([b'rev-1'], preview_tree.get_parent_ids())
 
3138
        preview_tree.set_parent_ids(['rev-1'])
 
3139
        self.assertEqual(['rev-1'], preview_tree.get_parent_ids())
3143
3140
 
3144
3141
    def test_plan_file_merge(self):
3145
3142
        work_a = self.make_branch_and_tree('wta')
3146
 
        self.build_tree_contents([('wta/file', b'a\nb\nc\nd\n')])
3147
 
        work_a.add('file', b'file-id')
 
3143
        self.build_tree_contents([('wta/file', 'a\nb\nc\nd\n')])
 
3144
        work_a.add('file', 'file-id')
3148
3145
        base_id = work_a.commit('base version')
3149
 
        tree_b = work_a.controldir.sprout('wtb').open_workingtree()
 
3146
        tree_b = work_a.bzrdir.sprout('wtb').open_workingtree()
3150
3147
        preview = TransformPreview(work_a)
3151
3148
        self.addCleanup(preview.finalize)
3152
 
        trans_id = preview.trans_id_file_id(b'file-id')
 
3149
        trans_id = preview.trans_id_file_id('file-id')
3153
3150
        preview.delete_contents(trans_id)
3154
3151
        preview.create_file('b\nc\nd\ne\n', trans_id)
3155
 
        self.build_tree_contents([('wtb/file', b'a\nc\nd\nf\n')])
 
3152
        self.build_tree_contents([('wtb/file', 'a\nc\nd\nf\n')])
3156
3153
        tree_a = preview.get_preview_tree()
3157
3154
        tree_a.set_parent_ids([base_id])
3158
3155
        self.assertEqual([
3162
3159
            ('unchanged', 'd\n'),
3163
3160
            ('new-a', 'e\n'),
3164
3161
            ('new-b', 'f\n'),
3165
 
        ], list(tree_a.plan_file_merge(b'file-id', tree_b)))
 
3162
        ], list(tree_a.plan_file_merge('file-id', tree_b)))
3166
3163
 
3167
3164
    def test_plan_file_merge_revision_tree(self):
3168
3165
        work_a = self.make_branch_and_tree('wta')
3169
 
        self.build_tree_contents([('wta/file', b'a\nb\nc\nd\n')])
3170
 
        work_a.add('file', b'file-id')
 
3166
        self.build_tree_contents([('wta/file', 'a\nb\nc\nd\n')])
 
3167
        work_a.add('file', 'file-id')
3171
3168
        base_id = work_a.commit('base version')
3172
 
        tree_b = work_a.controldir.sprout('wtb').open_workingtree()
 
3169
        tree_b = work_a.bzrdir.sprout('wtb').open_workingtree()
3173
3170
        preview = TransformPreview(work_a.basis_tree())
3174
3171
        self.addCleanup(preview.finalize)
3175
 
        trans_id = preview.trans_id_file_id(b'file-id')
 
3172
        trans_id = preview.trans_id_file_id('file-id')
3176
3173
        preview.delete_contents(trans_id)
3177
3174
        preview.create_file('b\nc\nd\ne\n', trans_id)
3178
 
        self.build_tree_contents([('wtb/file', b'a\nc\nd\nf\n')])
 
3175
        self.build_tree_contents([('wtb/file', 'a\nc\nd\nf\n')])
3179
3176
        tree_a = preview.get_preview_tree()
3180
3177
        tree_a.set_parent_ids([base_id])
3181
3178
        self.assertEqual([
3185
3182
            ('unchanged', 'd\n'),
3186
3183
            ('new-a', 'e\n'),
3187
3184
            ('new-b', 'f\n'),
3188
 
        ], list(tree_a.plan_file_merge(b'file-id', tree_b)))
 
3185
        ], list(tree_a.plan_file_merge('file-id', tree_b)))
3189
3186
 
3190
3187
    def test_walkdirs(self):
3191
3188
        preview = self.get_empty_preview()
3194
3191
        preview.fixup_new_roots()
3195
3192
        preview_tree = preview.get_preview_tree()
3196
3193
        file_trans_id = preview.new_file('a', preview.root, 'contents',
3197
 
                                         b'a-id')
3198
 
        expected = [(('', b'tree-root'),
3199
 
                    [('a', 'a', 'file', None, b'a-id', 'file')])]
 
3194
                                         'a-id')
 
3195
        expected = [(('', 'tree-root'),
 
3196
                    [('a', 'a', 'file', None, 'a-id', 'file')])]
3200
3197
        self.assertEqual(expected, list(preview_tree.walkdirs()))
3201
3198
 
3202
3199
    def test_extras(self):
3208
3205
        self.addCleanup(preview.finalize)
3209
3206
        preview.new_file('new-file', preview.root, 'contents')
3210
3207
        preview.new_file('new-versioned-file', preview.root, 'contents',
3211
 
                         b'new-versioned-id')
 
3208
                         'new-versioned-id')
3212
3209
        tree = preview.get_preview_tree()
3213
3210
        preview.unversion_file(preview.trans_id_tree_path('removed-file'))
3214
 
        self.assertEqual({'new-file', 'removed-file', 'existing-file'},
 
3211
        self.assertEqual(set(['new-file', 'removed-file', 'existing-file']),
3215
3212
                         set(tree.extras()))
3216
3213
 
3217
3214
    def test_merge_into_preview(self):
3218
3215
        work_tree = self.make_branch_and_tree('tree')
3219
 
        self.build_tree_contents([('tree/file', b'b\n')])
3220
 
        work_tree.add('file', b'file-id')
 
3216
        self.build_tree_contents([('tree/file','b\n')])
 
3217
        work_tree.add('file', 'file-id')
3221
3218
        work_tree.commit('first commit')
3222
 
        child_tree = work_tree.controldir.sprout('child').open_workingtree()
3223
 
        self.build_tree_contents([('child/file', b'b\nc\n')])
 
3219
        child_tree = work_tree.bzrdir.sprout('child').open_workingtree()
 
3220
        self.build_tree_contents([('child/file','b\nc\n')])
3224
3221
        child_tree.commit('child commit')
3225
3222
        child_tree.lock_write()
3226
3223
        self.addCleanup(child_tree.unlock)
3228
3225
        self.addCleanup(work_tree.unlock)
3229
3226
        preview = TransformPreview(work_tree)
3230
3227
        self.addCleanup(preview.finalize)
3231
 
        file_trans_id = preview.trans_id_file_id(b'file-id')
 
3228
        file_trans_id = preview.trans_id_file_id('file-id')
3232
3229
        preview.delete_contents(file_trans_id)
3233
3230
        preview.create_file('a\nb\n', file_trans_id)
3234
3231
        preview_tree = preview.get_preview_tree()
3235
 
        merger = Merger.from_revision_ids(preview_tree,
 
3232
        merger = Merger.from_revision_ids(None, preview_tree,
3236
3233
                                          child_tree.branch.last_revision(),
3237
3234
                                          other_branch=child_tree.branch,
3238
3235
                                          tree_branch=work_tree.branch)
3240
3237
        tt = merger.make_merger().make_preview_transform()
3241
3238
        self.addCleanup(tt.finalize)
3242
3239
        final_tree = tt.get_preview_tree()
3243
 
        self.assertEqual(
3244
 
                'a\nb\nc\n',
3245
 
                final_tree.get_file_text(final_tree.id2path(b'file-id')))
 
3240
        self.assertEqual('a\nb\nc\n', final_tree.get_file_text('file-id'))
3246
3241
 
3247
3242
    def test_merge_preview_into_workingtree(self):
3248
3243
        tree = self.make_branch_and_tree('tree')
3249
 
        tree.set_root_id(b'TREE_ROOT')
 
3244
        tree.set_root_id('TREE_ROOT')
3250
3245
        tt = TransformPreview(tree)
3251
3246
        self.addCleanup(tt.finalize)
3252
 
        tt.new_file('name', tt.root, 'content', b'file-id')
 
3247
        tt.new_file('name', tt.root, 'content', 'file-id')
3253
3248
        tree2 = self.make_branch_and_tree('tree2')
3254
 
        tree2.set_root_id(b'TREE_ROOT')
 
3249
        tree2.set_root_id('TREE_ROOT')
3255
3250
        merger = Merger.from_uncommitted(tree2, tt.get_preview_tree(),
3256
 
                                         tree.basis_tree())
 
3251
                                         None, tree.basis_tree())
3257
3252
        merger.merge_type = Merge3Merger
3258
3253
        merger.do_merge()
3259
3254
 
3260
3255
    def test_merge_preview_into_workingtree_handles_conflicts(self):
3261
3256
        tree = self.make_branch_and_tree('tree')
3262
 
        self.build_tree_contents([('tree/foo', b'bar')])
3263
 
        tree.add('foo', b'foo-id')
 
3257
        self.build_tree_contents([('tree/foo', 'bar')])
 
3258
        tree.add('foo', 'foo-id')
3264
3259
        tree.commit('foo')
3265
3260
        tt = TransformPreview(tree)
3266
3261
        self.addCleanup(tt.finalize)
3267
 
        trans_id = tt.trans_id_file_id(b'foo-id')
 
3262
        trans_id = tt.trans_id_file_id('foo-id')
3268
3263
        tt.delete_contents(trans_id)
3269
3264
        tt.create_file('baz', trans_id)
3270
 
        tree2 = tree.controldir.sprout('tree2').open_workingtree()
3271
 
        self.build_tree_contents([('tree2/foo', b'qux')])
 
3265
        tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
 
3266
        self.build_tree_contents([('tree2/foo', 'qux')])
 
3267
        pb = None
3272
3268
        merger = Merger.from_uncommitted(tree2, tt.get_preview_tree(),
3273
 
                                         tree.basis_tree())
 
3269
                                         pb, tree.basis_tree())
3274
3270
        merger.merge_type = Merge3Merger
3275
3271
        merger.do_merge()
3276
3272
 
3298
3294
        self.addCleanup(preview.finalize)
3299
3295
        preview.new_file('foo', preview.root, 'bar', 'baz-id')
3300
3296
        preview_tree = preview.get_preview_tree()
3301
 
        self.assertEqual(False, preview_tree.is_executable('tree/foo', 'baz-id'))
3302
 
        self.assertEqual(False, preview_tree.is_executable('tree/foo'))
 
3297
        self.assertEqual(False, preview_tree.is_executable('baz-id',
 
3298
                                                           'tree/foo'))
 
3299
        self.assertEqual(False, preview_tree.is_executable('baz-id'))
3303
3300
 
3304
3301
    def test_commit_preview_tree(self):
3305
3302
        tree = self.make_branch_and_tree('tree')
3316
3313
        builder.finish_inventory()
3317
3314
        rev2_id = builder.commit('rev2')
3318
3315
        rev2_tree = tree.branch.repository.revision_tree(rev2_id)
3319
 
        self.assertEqual('contents', rev2_tree.get_file_text('file'))
 
3316
        self.assertEqual('contents', rev2_tree.get_file_text('file_id'))
3320
3317
 
3321
3318
    def test_ascii_limbo_paths(self):
3322
3319
        self.requireFeature(features.UnicodeFilenameFeature)
3439
3436
    def make_destruction_preview(self):
3440
3437
        tree = self.make_branch_and_tree('.')
3441
3438
        self.build_tree([u'foo\u1234', 'bar'])
3442
 
        tree.add([u'foo\u1234', 'bar'], [b'foo-id', b'bar-id'])
 
3439
        tree.add([u'foo\u1234', 'bar'], ['foo-id', 'bar-id'])
3443
3440
        return self.get_preview(tree)
3444
3441
 
3445
3442
    def destruction_records(self):
3456
3453
 
3457
3454
    def test_serialize_destruction(self):
3458
3455
        tt = self.make_destruction_preview()
3459
 
        foo_trans_id = tt.trans_id_tree_path(u'foo\u1234')
 
3456
        foo_trans_id = tt.trans_id_tree_file_id('foo-id')
3460
3457
        tt.unversion_file(foo_trans_id)
3461
 
        bar_trans_id = tt.trans_id_tree_path('bar')
 
3458
        bar_trans_id = tt.trans_id_tree_file_id('bar-id')
3462
3459
        tt.delete_contents(bar_trans_id)
3463
3460
        self.assertSerializesTo(self.destruction_records(), tt)
3464
3461
 
3471
3468
        self.assertEqual({'new-1': u'foo\u1234',
3472
3469
                          'new-2': 'bar',
3473
3470
                          tt.root: ''}, tt._tree_id_paths)
3474
 
        self.assertEqual({'new-1'}, tt._removed_id)
3475
 
        self.assertEqual({'new-2'}, tt._removed_contents)
 
3471
        self.assertEqual(set(['new-1']), tt._removed_id)
 
3472
        self.assertEqual(set(['new-2']), tt._removed_contents)
3476
3473
 
3477
3474
    def missing_records(self):
3478
3475
        attribs = self.default_attribs()
3492
3489
        self.assertEqual({'boo': 'new-1'}, tt._non_present_ids)
3493
3490
 
3494
3491
    def make_modification_preview(self):
3495
 
        LINES_ONE = b'aa\nbb\ncc\ndd\n'
3496
 
        LINES_TWO = b'z\nbb\nx\ndd\n'
 
3492
        LINES_ONE = 'aa\nbb\ncc\ndd\n'
 
3493
        LINES_TWO = 'z\nbb\nx\ndd\n'
3497
3494
        tree = self.make_branch_and_tree('tree')
3498
3495
        self.build_tree_contents([('tree/file', LINES_ONE)])
3499
 
        tree.add('file', b'file-id')
 
3496
        tree.add('file', 'file-id')
3500
3497
        return self.get_preview(tree), LINES_TWO
3501
3498
 
3502
3499
    def modification_records(self):
3526
3523
        LINES = 'a\nb\nc\nd\n'
3527
3524
        tree = self.make_branch_and_tree('tree')
3528
3525
        self.build_tree(['tree/foo/'])
3529
 
        tree.add('foo', b'foo-id')
 
3526
        tree.add('foo', 'foo-id')
3530
3527
        return self.get_preview(tree), LINES
3531
3528
 
3532
3529
    def kind_change_records(self):
3542
3539
 
3543
3540
    def test_serialize_kind_change(self):
3544
3541
        tt, LINES = self.make_kind_change_preview()
3545
 
        trans_id = tt.trans_id_file_id(b'foo-id')
 
3542
        trans_id = tt.trans_id_file_id('foo-id')
3546
3543
        tt.delete_contents(trans_id)
3547
3544
        tt.create_file(LINES, trans_id)
3548
3545
        self.assertSerializesTo(self.kind_change_records(), tt)
3582
3579
        self.assertFileEqual(LINES, tt._limbo_name('new-1'))
3583
3580
 
3584
3581
    def test_get_parents_lines(self):
3585
 
        LINES_ONE = b'aa\nbb\ncc\ndd\n'
3586
 
        LINES_TWO = b'z\nbb\nx\ndd\n'
 
3582
        LINES_ONE = 'aa\nbb\ncc\ndd\n'
 
3583
        LINES_TWO = 'z\nbb\nx\ndd\n'
3587
3584
        tree = self.make_branch_and_tree('tree')
3588
3585
        self.build_tree_contents([('tree/file', LINES_ONE)])
3589
 
        tree.add('file', b'file-id')
 
3586
        tree.add('file', 'file-id')
3590
3587
        tt = self.get_preview(tree)
3591
3588
        trans_id = tt.trans_id_tree_path('file')
3592
3589
        self.assertEqual((['aa\n', 'bb\n', 'cc\n', 'dd\n'],),
3593
3590
            tt._get_parents_lines(trans_id))
3594
3591
 
3595
3592
    def test_get_parents_texts(self):
3596
 
        LINES_ONE = b'aa\nbb\ncc\ndd\n'
3597
 
        LINES_TWO = b'z\nbb\nx\ndd\n'
 
3593
        LINES_ONE = 'aa\nbb\ncc\ndd\n'
 
3594
        LINES_TWO = 'z\nbb\nx\ndd\n'
3598
3595
        tree = self.make_branch_and_tree('tree')
3599
3596
        self.build_tree_contents([('tree/file', LINES_ONE)])
3600
 
        tree.add('file', b'file-id')
 
3597
        tree.add('file', 'file-id')
3601
3598
        tt = self.get_preview(tree)
3602
3599
        trans_id = tt.trans_id_tree_path('file')
3603
3600
        self.assertEqual((LINES_ONE,),
3613
3610
        self.assertRaises(NotImplementedError, tt.new_orphan, 'foo', 'bar')
3614
3611
 
3615
3612
    def _set_orphan_policy(self, wt, policy):
3616
 
        wt.branch.get_config_stack().set('transform.orphan_policy',
 
3613
        wt.branch.get_config_stack().set('bzr.transform.orphan_policy',
3617
3614
                                               policy)
3618
3615
 
3619
3616
    def _prepare_orphan(self, wt):
3620
3617
        self.build_tree(['dir/', 'dir/file', 'dir/foo'])
3621
 
        wt.add(['dir', 'dir/file'], [b'dir-id', b'file-id'])
 
3618
        wt.add(['dir', 'dir/file'], ['dir-id', 'file-id'])
3622
3619
        wt.commit('add dir and file ignoring foo')
3623
3620
        tt = transform.TreeTransform(wt)
3624
3621
        self.addCleanup(tt.finalize)
3645
3642
            warnings.append(args[0] % args[1:])
3646
3643
        self.overrideAttr(trace, 'warning', warning)
3647
3644
        remaining_conflicts = resolve_conflicts(tt)
3648
 
        self.assertEqual(['dir/foo has been orphaned in brz-orphans'],
 
3645
        self.assertEquals(['dir/foo has been orphaned in bzr-orphans'],
3649
3646
                          warnings)
3650
3647
        # Yeah for resolved conflicts !
3651
3648
        self.assertLength(0, remaining_conflicts)
3652
3649
        # We have a new orphan
3653
 
        self.assertEqual('foo.~1~', tt.final_name(orphan_tid))
3654
 
        self.assertEqual('brz-orphans',
 
3650
        self.assertEquals('foo.~1~', tt.final_name(orphan_tid))
 
3651
        self.assertEquals('bzr-orphans',
3655
3652
                          tt.final_name(tt.final_parent(orphan_tid)))
3656
3653
 
3657
3654
    def test_never_orphan(self):
3717
3714
        old_root_id = transform.tree_file_id(root)
3718
3715
        transform.apply()
3719
3716
        self.assertEqual(old_root_id, self.wt.get_root_id())
3720
 
        self.assertEqual([(self.wt, transform)], calls)
 
3717
        self.assertEquals([(self.wt, transform)], calls)
3721
3718
 
3722
3719
    def test_post_commit_hooks(self):
3723
3720
        calls = []
3729
3726
        old_root_id = transform.tree_file_id(root)
3730
3727
        transform.apply()
3731
3728
        self.assertEqual(old_root_id, self.wt.get_root_id())
3732
 
        self.assertEqual([(self.wt, transform)], calls)
3733
 
 
3734
 
 
3735
 
class TestLinkTree(tests.TestCaseWithTransport):
3736
 
 
3737
 
    _test_needs_features = [HardlinkFeature]
3738
 
 
3739
 
    def setUp(self):
3740
 
        tests.TestCaseWithTransport.setUp(self)
3741
 
        self.parent_tree = self.make_branch_and_tree('parent')
3742
 
        self.parent_tree.lock_write()
3743
 
        self.addCleanup(self.parent_tree.unlock)
3744
 
        self.build_tree_contents([('parent/foo', b'bar')])
3745
 
        self.parent_tree.add('foo')
3746
 
        self.parent_tree.commit('added foo')
3747
 
        child_controldir = self.parent_tree.controldir.sprout('child')
3748
 
        self.child_tree = child_controldir.open_workingtree()
3749
 
 
3750
 
    def hardlinked(self):
3751
 
        parent_stat = os.lstat(self.parent_tree.abspath('foo'))
3752
 
        child_stat = os.lstat(self.child_tree.abspath('foo'))
3753
 
        return parent_stat.st_ino == child_stat.st_ino
3754
 
 
3755
 
    def test_link_fails_if_modified(self):
3756
 
        """If the file to be linked has modified text, don't link."""
3757
 
        self.build_tree_contents([('child/foo', b'baz')])
3758
 
        transform.link_tree(self.child_tree, self.parent_tree)
3759
 
        self.assertFalse(self.hardlinked())
3760
 
 
3761
 
    def test_link_fails_if_execute_bit_changed(self):
3762
 
        """If the file to be linked has modified execute bit, don't link."""
3763
 
        tt = TreeTransform(self.child_tree)
3764
 
        try:
3765
 
            trans_id = tt.trans_id_tree_path('foo')
3766
 
            tt.set_executability(True, trans_id)
3767
 
            tt.apply()
3768
 
        finally:
3769
 
            tt.finalize()
3770
 
        transform.link_tree(self.child_tree, self.parent_tree)
3771
 
        self.assertFalse(self.hardlinked())
3772
 
 
3773
 
    def test_link_succeeds_if_unmodified(self):
3774
 
        """If the file to be linked is unmodified, link"""
3775
 
        transform.link_tree(self.child_tree, self.parent_tree)
3776
 
        self.assertTrue(self.hardlinked())
 
3729
        self.assertEquals([(self.wt, transform)], calls)