/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 breezy/tests/test_workingtree.py

  • Committer: Jelmer Vernooij
  • Date: 2017-07-23 22:06:41 UTC
  • mfrom: (6738 trunk)
  • mto: This revision was merged to the branch mainline in revision 6739.
  • Revision ID: jelmer@jelmer.uk-20170723220641-69eczax9bmv8d6kk
Merge trunk, address review comments.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
# along with this program; if not, write to the Free Software
16
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
 
18
 
from io import BytesIO
19
 
import os
20
 
 
21
18
from .. import (
22
19
    conflicts,
23
20
    errors,
24
 
    symbol_versioning,
25
 
    trace,
26
21
    transport,
27
22
    workingtree,
28
23
    )
29
24
from ..bzr import (
30
25
    bzrdir,
31
 
    conflicts as _mod_bzr_conflicts,
32
26
    workingtree as bzrworkingtree,
33
27
    workingtree_3,
34
28
    workingtree_4,
35
29
    )
36
30
from ..lock import write_locked
37
31
from ..lockdir import LockDir
 
32
from ..mutabletree import needs_tree_write_lock
38
33
from . import TestCase, TestCaseWithTransport, TestSkipped
39
 
from ..tree import (
 
34
from ..workingtree import (
40
35
    TreeEntry,
41
36
    TreeDirectory,
42
37
    TreeFile,
43
38
    TreeLink,
44
39
    )
45
40
 
46
 
from .features import SymlinkFeature
47
41
 
48
42
class TestTreeDirectory(TestCaseWithTransport):
49
43
 
74
68
    def test_get_set_default_format(self):
75
69
        old_format = workingtree.format_registry.get_default()
76
70
        # default is 6
77
 
        self.assertTrue(isinstance(
78
 
            old_format, workingtree_4.WorkingTreeFormat6))
 
71
        self.assertTrue(isinstance(old_format, workingtree_4.WorkingTreeFormat6))
79
72
        workingtree.format_registry.set_default(SampleTreeFormat())
80
73
        try:
81
74
            # the default branch format is used by the meta dir format
91
84
 
92
85
    def test_from_string(self):
93
86
        self.assertIsInstance(
94
 
            SampleTreeFormat.from_string(b"Sample tree format."),
 
87
            SampleTreeFormat.from_string("Sample tree format."),
95
88
            SampleTreeFormat)
96
 
        self.assertRaises(
97
 
            AssertionError, SampleTreeFormat.from_string,
98
 
            b"Different format string.")
 
89
        self.assertRaises(AssertionError,
 
90
            SampleTreeFormat.from_string, "Different format string.")
99
91
 
100
92
    def test_get_set_default_format_by_key(self):
101
93
        old_format = workingtree.format_registry.get_default()
103
95
        format = SampleTreeFormat()
104
96
        workingtree.format_registry.register(format)
105
97
        self.addCleanup(workingtree.format_registry.remove, format)
106
 
        self.assertTrue(isinstance(
107
 
            old_format, workingtree_4.WorkingTreeFormat6))
 
98
        self.assertTrue(isinstance(old_format, workingtree_4.WorkingTreeFormat6))
108
99
        workingtree.format_registry.set_default_key(format.get_format_string())
109
100
        try:
110
101
            # the default branch format is used by the meta dir format
134
125
        open_no_args, relpath = workingtree.WorkingTree.open_containing()
135
126
        self.assertEqual(tree.basedir, open_no_args.basedir)
136
127
        self.assertEqual('', relpath)
137
 
        open_subdir, relpath = workingtree.WorkingTree.open_containing(
138
 
            'subdir')
 
128
        open_subdir, relpath = workingtree.WorkingTree.open_containing('subdir')
139
129
        self.assertEqual(tree.basedir, open_subdir.basedir)
140
130
        self.assertEqual('subdir', relpath)
141
131
 
150
140
    @classmethod
151
141
    def get_format_string(cls):
152
142
        """See WorkingTreeFormat.get_format_string()."""
153
 
        return b"Sample tree format."
 
143
        return "Sample tree format."
154
144
 
155
145
    def initialize(self, a_controldir, revision_id=None, from_branch=None,
156
146
                   accelerator_tree=None, hardlink=False):
192
182
    def test_find_format_string(self):
193
183
        # is the right format object found for a working tree?
194
184
        branch = self.make_branch('branch')
195
 
        self.assertRaises(
196
 
            errors.NoWorkingTree,
197
 
            bzrworkingtree.WorkingTreeFormatMetaDir.find_format_string,
198
 
            branch.controldir)
 
185
        self.assertRaises(errors.NoWorkingTree,
 
186
            bzrworkingtree.WorkingTreeFormatMetaDir.find_format_string, branch.controldir)
199
187
        transport = branch.controldir.get_workingtree_transport(None)
200
188
        transport.mkdir('.')
201
 
        transport.put_bytes("format", b"some format name")
 
189
        transport.put_bytes("format", "some format name")
202
190
        # The format does not have to be known by Bazaar,
203
191
        # find_format_string just retrieves the name
204
 
        self.assertEqual(
205
 
            b"some format name",
206
 
            bzrworkingtree.WorkingTreeFormatMetaDir.find_format_string(
207
 
                branch.controldir))
 
192
        self.assertEqual("some format name",
 
193
            bzrworkingtree.WorkingTreeFormatMetaDir.find_format_string(branch.controldir))
208
194
 
209
195
    def test_find_format(self):
210
196
        # is the right format object found for a working tree?
211
197
        # create a branch with a few known format objects.
212
198
        self.build_tree(["foo/", "bar/"])
213
 
 
214
199
        def check_format(format, url):
215
 
            dir = format._matchingcontroldir.initialize(url)
 
200
            dir = format._matchingbzrdir.initialize(url)
216
201
            dir.create_repository()
217
202
            dir.create_branch()
218
203
            format.initialize(dir)
219
 
            found_format = bzrworkingtree.WorkingTreeFormatMetaDir.find_format(
220
 
                dir)
 
204
            t = transport.get_transport(url)
 
205
            found_format = bzrworkingtree.WorkingTreeFormatMetaDir.find_format(dir)
221
206
            self.assertIsInstance(found_format, format.__class__)
222
207
        check_format(workingtree_3.WorkingTreeFormat3(), "bar")
223
208
 
238
223
 
239
224
    def test_find_format_with_features(self):
240
225
        tree = self.make_branch_and_tree('.', format='2a')
241
 
        tree.update_feature_flags({b"name": b"necessity"})
 
226
        tree.update_feature_flags({"name": "necessity"})
242
227
        found_format = bzrworkingtree.WorkingTreeFormatMetaDir.find_format(
243
228
            tree.controldir)
244
229
        self.assertIsInstance(found_format, workingtree.WorkingTreeFormat)
245
 
        self.assertEqual(found_format.features.get(b"name"), b"necessity")
246
 
        self.assertRaises(
247
 
            bzrdir.MissingFeature, found_format.check_support_status, True)
248
 
        self.addCleanup(
249
 
            bzrworkingtree.WorkingTreeFormatMetaDir.unregister_feature,
250
 
            b"name")
251
 
        bzrworkingtree.WorkingTreeFormatMetaDir.register_feature(b"name")
 
230
        self.assertEqual(found_format.features.get("name"), "necessity")
 
231
        self.assertRaises(bzrdir.MissingFeature, found_format.check_support_status,
 
232
            True)
 
233
        self.addCleanup(bzrworkingtree.WorkingTreeFormatMetaDir.unregister_feature,
 
234
            "name")
 
235
        bzrworkingtree.WorkingTreeFormatMetaDir.register_feature("name")
252
236
        found_format.check_support_status(True)
253
237
 
254
238
 
257
241
    def make_simple_tree(self):
258
242
        tree = self.make_branch_and_tree('tree', format='development-subtree')
259
243
        self.build_tree(['tree/a/', 'tree/a/b/', 'tree/a/b/c'])
260
 
        tree.set_root_id(b'root-id')
261
 
        tree.add(['a', 'a/b', 'a/b/c'], [b'a-id', b'b-id', b'c-id'])
 
244
        tree.set_root_id('root-id')
 
245
        tree.add(['a', 'a/b', 'a/b/c'], ['a-id', 'b-id', 'c-id'])
262
246
        tree.commit('initial')
263
247
        return tree
264
248
 
265
249
    def test_just_directory(self):
266
250
        tree = self.make_simple_tree()
267
 
        self.assertEqual([('directory', b'root-id'),
268
 
                          ('directory', b'a-id'),
269
 
                          ('directory', b'b-id'),
270
 
                          ('file', b'c-id')],
 
251
        self.assertEqual([('directory', 'root-id'),
 
252
                          ('directory', 'a-id'),
 
253
                          ('directory', 'b-id'),
 
254
                          ('file', 'c-id')],
271
255
                         [(ie.kind, ie.file_id)
272
256
                          for path, ie in tree.iter_entries_by_dir()])
273
 
        self.make_branch_and_tree('tree/a/b')
274
 
        self.assertEqual([('tree-reference', b'b-id')],
 
257
        subtree = self.make_branch_and_tree('tree/a/b')
 
258
        self.assertEqual([('tree-reference', 'b-id')],
275
259
                         [(ie.kind, ie.file_id)
276
 
                          for path, ie in tree.iter_entries_by_dir(
277
 
                              specific_files=['a/b'])])
 
260
                          for path, ie in tree.iter_entries_by_dir(['b-id'])])
278
261
 
279
262
    def test_direct_subtree(self):
280
263
        tree = self.make_simple_tree()
281
 
        self.make_branch_and_tree('tree/a/b')
282
 
        self.assertEqual([('directory', b'root-id'),
283
 
                          ('directory', b'a-id'),
284
 
                          ('tree-reference', b'b-id')],
 
264
        subtree = self.make_branch_and_tree('tree/a/b')
 
265
        self.assertEqual([('directory', 'root-id'),
 
266
                          ('directory', 'a-id'),
 
267
                          ('tree-reference', 'b-id')],
285
268
                         [(ie.kind, ie.file_id)
286
269
                          for path, ie in tree.iter_entries_by_dir()])
287
270
 
288
271
    def test_indirect_subtree(self):
289
272
        tree = self.make_simple_tree()
290
 
        self.make_branch_and_tree('tree/a')
291
 
        self.assertEqual([('directory', b'root-id'),
292
 
                          ('tree-reference', b'a-id')],
 
273
        subtree = self.make_branch_and_tree('tree/a')
 
274
        self.assertEqual([('directory', 'root-id'),
 
275
                          ('tree-reference', 'a-id')],
293
276
                         [(ie.kind, ie.file_id)
294
277
                          for path, ie in tree.iter_entries_by_dir()])
295
278
 
303
286
    def test_register_unregister_format(self):
304
287
        format = SampleTreeFormat()
305
288
        self.registry.register(format)
306
 
        self.assertEqual(format, self.registry.get(b"Sample tree format."))
 
289
        self.assertEqual(format, self.registry.get("Sample tree format."))
307
290
        self.registry.remove(format)
308
 
        self.assertRaises(KeyError, self.registry.get, b"Sample tree format.")
 
291
        self.assertRaises(KeyError, self.registry.get, "Sample tree format.")
309
292
 
310
293
    def test_get_all(self):
311
294
        format = SampleTreeFormat()
322
305
    def test_register_extra_lazy(self):
323
306
        self.assertEqual([], self.registry._get_all())
324
307
        self.registry.register_extra_lazy("breezy.tests.test_workingtree",
325
 
                                          "SampleExtraTreeFormat")
 
308
            "SampleExtraTreeFormat")
326
309
        formats = self.registry._get_all()
327
310
        self.assertEqual(1, len(formats))
328
311
        self.assertIsInstance(formats[0], SampleExtraTreeFormat)
335
318
        control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
336
319
        control.create_repository()
337
320
        control.create_branch()
338
 
        workingtree_3.WorkingTreeFormat3().initialize(control)
 
321
        tree = workingtree_3.WorkingTreeFormat3().initialize(control)
339
322
        # we want:
340
323
        # format 'Bazaar-NG Working Tree format 3'
341
324
        # inventory = blank inventory
343
326
        # stat-cache = ??
344
327
        # no inventory.basis yet
345
328
        t = control.get_workingtree_transport(None)
346
 
        self.assertEqualDiff(b'Bazaar-NG Working Tree format 3',
 
329
        self.assertEqualDiff('Bazaar-NG Working Tree format 3',
347
330
                             t.get('format').read())
348
331
        self.assertEqualDiff(t.get('inventory').read(),
349
 
                             b'<inventory format="5">\n'
350
 
                             b'</inventory>\n',
 
332
                              '<inventory format="5">\n'
 
333
                              '</inventory>\n',
351
334
                             )
352
 
        self.assertEqualDiff(b'### bzr hashcache v5\n',
 
335
        self.assertEqualDiff('### bzr hashcache v5\n',
353
336
                             t.get('stat-cache').read())
354
337
        self.assertFalse(t.has('inventory.basis'))
355
338
        # no last-revision file means 'None' or 'NULLREVISION'
366
349
        t = self.get_transport()
367
350
        url = self.get_url()
368
351
        dir = bzrdir.BzrDirMetaFormat1().initialize(url)
369
 
        dir.create_repository()
370
 
        dir.create_branch()
 
352
        repo = dir.create_repository()
 
353
        branch = dir.create_branch()
371
354
        try:
372
355
            tree = workingtree_3.WorkingTreeFormat3().initialize(dir)
373
356
        except errors.NotLocalUrl:
377
360
        self.assertIsDirectory('.bzr/checkout/lock', t)
378
361
        our_lock = LockDir(t, '.bzr/checkout/lock')
379
362
        self.assertEqual(our_lock.peek(), None)
380
 
        with tree.lock_write():
381
 
            self.assertTrue(our_lock.peek())
 
363
        tree.lock_write()
 
364
        self.assertTrue(our_lock.peek())
 
365
        tree.unlock()
382
366
        self.assertEqual(our_lock.peek(), None)
383
367
 
384
368
    def test_missing_pending_merges(self):
390
374
        self.assertEqual([], tree.get_parent_ids())
391
375
 
392
376
 
 
377
class InstrumentedTree(object):
 
378
    """A instrumented tree to check the needs_tree_write_lock decorator."""
 
379
 
 
380
    def __init__(self):
 
381
        self._locks = []
 
382
 
 
383
    def lock_tree_write(self):
 
384
        self._locks.append('t')
 
385
 
 
386
    @needs_tree_write_lock
 
387
    def method_with_tree_write_lock(self, *args, **kwargs):
 
388
        """A lock_tree_write decorated method that returns its arguments."""
 
389
        return args, kwargs
 
390
 
 
391
    @needs_tree_write_lock
 
392
    def method_that_raises(self):
 
393
        """This method causes an exception when called with parameters.
 
394
 
 
395
        This allows the decorator code to be checked - it should still call
 
396
        unlock.
 
397
        """
 
398
 
 
399
    def unlock(self):
 
400
        self._locks.append('u')
 
401
 
 
402
 
 
403
class TestInstrumentedTree(TestCase):
 
404
 
 
405
    def test_needs_tree_write_lock(self):
 
406
        """@needs_tree_write_lock should be semantically transparent."""
 
407
        tree = InstrumentedTree()
 
408
        self.assertEqual(
 
409
            'method_with_tree_write_lock',
 
410
            tree.method_with_tree_write_lock.__name__)
 
411
        self.assertDocstring(
 
412
            "A lock_tree_write decorated method that returns its arguments.",
 
413
            tree.method_with_tree_write_lock)
 
414
        args = (1, 2, 3)
 
415
        kwargs = {'a':'b'}
 
416
        result = tree.method_with_tree_write_lock(1,2,3, a='b')
 
417
        self.assertEqual((args, kwargs), result)
 
418
        self.assertEqual(['t', 'u'], tree._locks)
 
419
        self.assertRaises(TypeError, tree.method_that_raises, 'foo')
 
420
        self.assertEqual(['t', 'u', 't', 'u'], tree._locks)
 
421
 
 
422
 
393
423
class TestRevert(TestCaseWithTransport):
394
424
 
395
425
    def test_revert_conflicts_recursive(self):
396
426
        this_tree = self.make_branch_and_tree('this-tree')
397
427
        self.build_tree_contents([('this-tree/foo/',),
398
 
                                  ('this-tree/foo/bar', b'bar')])
 
428
                                  ('this-tree/foo/bar', 'bar')])
399
429
        this_tree.add(['foo', 'foo/bar'])
400
430
        this_tree.commit('created foo/bar')
401
 
        other_tree = this_tree.controldir.sprout(
402
 
            'other-tree').open_workingtree()
403
 
        self.build_tree_contents([('other-tree/foo/bar', b'baz')])
 
431
        other_tree = this_tree.controldir.sprout('other-tree').open_workingtree()
 
432
        self.build_tree_contents([('other-tree/foo/bar', 'baz')])
404
433
        other_tree.commit('changed bar')
405
 
        self.build_tree_contents([('this-tree/foo/bar', b'qux')])
 
434
        self.build_tree_contents([('this-tree/foo/bar', 'qux')])
406
435
        this_tree.commit('changed qux')
407
436
        this_tree.merge_from_branch(other_tree.branch)
408
437
        self.assertEqual(1, len(this_tree.conflicts()))
412
441
 
413
442
class TestAutoResolve(TestCaseWithTransport):
414
443
 
415
 
    def _auto_resolve(self, tree):
416
 
        """Call auto_resolve on tree expecting deprecation"""
417
 
        return self.applyDeprecated(
418
 
            symbol_versioning.deprecated_in((3, 0, 1)),
419
 
            tree.auto_resolve,)
420
 
 
421
444
    def test_auto_resolve(self):
422
445
        base = self.make_branch_and_tree('base')
423
 
        self.build_tree_contents([('base/hello', b'Hello')])
424
 
        base.add('hello', b'hello_id')
 
446
        self.build_tree_contents([('base/hello', 'Hello')])
 
447
        base.add('hello', 'hello_id')
425
448
        base.commit('Hello')
426
449
        other = base.controldir.sprout('other').open_workingtree()
427
 
        self.build_tree_contents([('other/hello', b'hELLO')])
 
450
        self.build_tree_contents([('other/hello', 'hELLO')])
428
451
        other.commit('Case switch')
429
452
        this = base.controldir.sprout('this').open_workingtree()
430
453
        self.assertPathExists('this/hello')
431
 
        self.build_tree_contents([('this/hello', b'Hello World')])
 
454
        self.build_tree_contents([('this/hello', 'Hello World')])
432
455
        this.commit('Add World')
433
456
        this.merge_from_branch(other.branch)
434
 
        self.assertEqual([_mod_bzr_conflicts.TextConflict('hello', b'hello_id')],
 
457
        self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
435
458
                         this.conflicts())
436
 
        self._auto_resolve(this)
437
 
        self.assertEqual([_mod_bzr_conflicts.TextConflict('hello', b'hello_id')],
 
459
        this.auto_resolve()
 
460
        self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
438
461
                         this.conflicts())
439
462
        self.build_tree_contents([('this/hello', '<<<<<<<')])
440
 
        self._auto_resolve(this)
441
 
        self.assertEqual([_mod_bzr_conflicts.TextConflict('hello', b'hello_id')],
 
463
        this.auto_resolve()
 
464
        self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
442
465
                         this.conflicts())
443
466
        self.build_tree_contents([('this/hello', '=======')])
444
 
        self._auto_resolve(this)
445
 
        self.assertEqual([_mod_bzr_conflicts.TextConflict('hello', b'hello_id')],
 
467
        this.auto_resolve()
 
468
        self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
446
469
                         this.conflicts())
447
470
        self.build_tree_contents([('this/hello', '\n>>>>>>>')])
448
 
        remaining, resolved = self._auto_resolve(this)
449
 
        self.assertEqual([_mod_bzr_conflicts.TextConflict('hello', b'hello_id')],
 
471
        remaining, resolved = this.auto_resolve()
 
472
        self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
450
473
                         this.conflicts())
451
474
        self.assertEqual([], resolved)
452
 
        self.build_tree_contents([('this/hello', b'hELLO wORLD')])
453
 
        remaining, resolved = self._auto_resolve(this)
 
475
        self.build_tree_contents([('this/hello', 'hELLO wORLD')])
 
476
        remaining, resolved = this.auto_resolve()
454
477
        self.assertEqual([], this.conflicts())
455
 
        self.assertEqual([_mod_bzr_conflicts.TextConflict('hello', b'hello_id')],
 
478
        self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
456
479
                         resolved)
457
480
        self.assertPathDoesNotExist('this/hello.BASE')
458
481
 
459
 
    def test_unsupported_symlink_auto_resolve(self):
460
 
        self.requireFeature(SymlinkFeature)
461
 
        base = self.make_branch_and_tree('base')
462
 
        self.build_tree_contents([('base/hello', 'Hello')])
463
 
        base.add('hello', b'hello_id')
464
 
        base.commit('commit 0')
465
 
        other = base.controldir.sprout('other').open_workingtree()
466
 
        self.build_tree_contents([('other/hello', 'Hello')])
467
 
        os.symlink('other/hello', 'other/foo')
468
 
        other.add('foo', b'foo_id')
469
 
        other.commit('commit symlink')
470
 
        this = base.controldir.sprout('this').open_workingtree()
471
 
        self.assertPathExists('this/hello')
472
 
        self.build_tree_contents([('this/hello', 'Hello')])
473
 
        this.commit('commit 2')
474
 
        log = BytesIO()
475
 
        trace.push_log_file(log)
476
 
        os_symlink = getattr(os, 'symlink', None)
477
 
        os.symlink = None
478
 
        try:
479
 
            this.merge_from_branch(other.branch)
480
 
        finally:
481
 
            if os_symlink:
482
 
                os.symlink = os_symlink
483
 
        self.assertContainsRe(
484
 
            log.getvalue(),
485
 
            b'Unable to create symlink "foo" on this filesystem')
486
 
 
487
482
    def test_auto_resolve_dir(self):
488
483
        tree = self.make_branch_and_tree('tree')
489
484
        self.build_tree(['tree/hello/'])
490
 
        tree.add('hello', b'hello-id')
491
 
        file_conflict = _mod_bzr_conflicts.TextConflict('hello', b'hello-id')
492
 
        tree.set_conflicts([file_conflict])
493
 
        remaining, resolved = self._auto_resolve(tree)
494
 
        self.assertEqual(
495
 
            remaining,
496
 
            conflicts.ConflictList([_mod_bzr_conflicts.TextConflict(u'hello', 'hello-id')]))
497
 
        self.assertEqual(resolved, [])
498
 
 
499
 
    def test_auto_resolve_missing(self):
500
 
        tree = self.make_branch_and_tree('tree')
501
 
        file_conflict = _mod_bzr_conflicts.TextConflict('hello', b'hello-id')
502
 
        tree.set_conflicts([file_conflict])
503
 
        remaining, resolved = self._auto_resolve(tree)
504
 
        self.assertEqual(remaining, [])
505
 
        self.assertEqual(
506
 
            resolved,
507
 
            conflicts.ConflictList([_mod_bzr_conflicts.TextConflict(u'hello', 'hello-id')]))
 
485
        tree.add('hello', 'hello-id')
 
486
        file_conflict = conflicts.TextConflict('file', 'hello-id')
 
487
        tree.set_conflicts(conflicts.ConflictList([file_conflict]))
 
488
        tree.auto_resolve()
 
489
 
 
490
 
 
491
class TestFindTrees(TestCaseWithTransport):
 
492
 
 
493
    def test_find_trees(self):
 
494
        self.make_branch_and_tree('foo')
 
495
        self.make_branch_and_tree('foo/bar')
 
496
        # Sticking a tree inside a control dir is heinous, so let's skip it
 
497
        self.make_branch_and_tree('foo/.bzr/baz')
 
498
        self.make_branch('qux')
 
499
        trees = workingtree.WorkingTree.find_trees('.')
 
500
        self.assertEqual(2, len(list(trees)))
508
501
 
509
502
 
510
503
class TestStoredUncommitted(TestCaseWithTransport):
512
505
    def store_uncommitted(self):
513
506
        tree = self.make_branch_and_tree('tree')
514
507
        tree.commit('get root in there')
515
 
        self.build_tree_contents([('tree/file', b'content')])
516
 
        tree.add('file', b'file-id')
 
508
        self.build_tree_contents([('tree/file', 'content')])
 
509
        tree.add('file', 'file-id')
517
510
        tree.store_uncommitted()
518
511
        return tree
519
512