/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/workingtree_implementations/test_parents.py

  • Committer: Martin Pool
  • Date: 2007-10-10 00:21:57 UTC
  • mfrom: (2900 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2901.
  • Revision ID: mbp@sourcefrog.net-20071010002157-utci0x44m2w47wgd
merge news

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""Tests of the parent related functions of WorkingTrees."""
18
18
 
 
19
from errno import EEXIST
19
20
import os
20
21
 
21
22
from bzrlib import (
22
23
    errors,
 
24
    osutils,
23
25
    revision as _mod_revision,
24
26
    symbol_versioning,
25
27
    )
 
28
from bzrlib.inventory import (
 
29
    Inventory,
 
30
    InventoryFile,
 
31
    InventoryDirectory,
 
32
    InventoryLink,
 
33
    )
 
34
from bzrlib.revision import Revision
 
35
from bzrlib.tests import SymlinkFeature, TestNotApplicable
26
36
from bzrlib.tests.workingtree_implementations import TestCaseWithWorkingTree
27
37
from bzrlib.uncommit import uncommit
28
38
 
237
247
        first_revision = tree.commit('first post')
238
248
        tree.add_parent_tree(('second', None))
239
249
        self.assertConsistentParents([first_revision, 'second'], tree)
 
250
 
 
251
 
 
252
class UpdateToOneParentViaDeltaTests(TestParents):
 
253
    """Tests for the update_to_one_parent_via_delta call.
 
254
    
 
255
    This is intuitively defined as 'apply an inventory delta to the basis and
 
256
    discard other parents', but for trees that have an inventory that is not
 
257
    managed as a tree-by-id, the implementation requires roughly duplicated
 
258
    tests with those for apply_inventory_delta on the main tree.
 
259
    """
 
260
 
 
261
    def assertDeltaApplicationResultsInExpectedBasis(self, tree, revid, delta,
 
262
        expected_inventory):
 
263
        tree.update_to_one_parent_via_delta(revid, delta)
 
264
        # check the last revision was adjusted to rev_id
 
265
        self.assertEqual(revid, tree.last_revision())
 
266
        # check the parents are what we expect
 
267
        self.assertEqual([revid], tree.get_parent_ids())
 
268
        # check that the basis tree has the inventory we expect from applying
 
269
        # the delta.
 
270
        result_basis = tree.basis_tree()
 
271
        result_basis.lock_read()
 
272
        self.addCleanup(result_basis.unlock)
 
273
        self.assertEqual(expected_inventory, result_basis.inventory)
 
274
 
 
275
    def make_inv_delta(self, old, new):
 
276
        """Make an inventory delta from two inventories."""
 
277
        old_ids = set(old._byid.iterkeys())
 
278
        new_ids = set(new._byid.iterkeys())
 
279
        adds = new_ids - old_ids
 
280
        deletes = old_ids - new_ids
 
281
        common = old_ids.intersection(new_ids)
 
282
        delta = []
 
283
        for file_id in deletes:
 
284
            delta.append((old.id2path(file_id), None, file_id, None))
 
285
        for file_id in adds:
 
286
            delta.append((None, new.id2path(file_id), file_id, new[file_id]))
 
287
        for file_id in common:
 
288
            if old[file_id] != new[file_id]:
 
289
                delta.append((old.id2path(file_id), new.id2path(file_id),
 
290
                    file_id, new[file_id]))
 
291
        return delta
 
292
 
 
293
    def fake_up_revision(self, tree, revid, shape):
 
294
        tree.lock_write()
 
295
        try:
 
296
            tree.branch.repository.start_write_group()
 
297
            try:
 
298
                if shape.root.revision is None:
 
299
                    shape.root.revision = revid
 
300
                sha1 = tree.branch.repository.add_inventory(revid, shape, [])
 
301
                rev = Revision(timestamp=0,
 
302
                               timezone=None,
 
303
                               committer="Foo Bar <foo@example.com>",
 
304
                               message="Message",
 
305
                               inventory_sha1=sha1,
 
306
                               revision_id=revid)
 
307
                tree.branch.repository.add_revision(revid, rev)
 
308
            except:
 
309
                tree.branch.repository.abort_write_group()
 
310
                raise
 
311
            else:
 
312
                tree.branch.repository.commit_write_group()
 
313
        finally:
 
314
            tree.unlock()
 
315
 
 
316
    def add_entry(self, inv, rev_id, entry):
 
317
        entry.revision = rev_id
 
318
        inv.add(entry)
 
319
 
 
320
    def add_dir(self, inv, rev_id, file_id, parent_id, name):
 
321
        new_dir = InventoryDirectory(file_id, name, parent_id)
 
322
        self.add_entry(inv, rev_id, new_dir)
 
323
 
 
324
    def add_file(self, inv, rev_id, file_id, parent_id, name, sha, size):
 
325
        new_file = InventoryFile(file_id, name, parent_id)
 
326
        new_file.text_sha1 = sha
 
327
        new_file.text_size = size
 
328
        self.add_entry(inv, rev_id, new_file)
 
329
 
 
330
    def add_link(self, inv, rev_id, file_id, parent_id, name, target):
 
331
        new_link = InventoryLink(file_id, name, parent_id)
 
332
        new_link.symlink_target = target
 
333
        self.add_entry(inv, rev_id, new_link)
 
334
 
 
335
    def add_new_root(self, new_shape, old_revid, new_revid):
 
336
        if self.bzrdir_format.repository_format.rich_root_data:
 
337
            self.add_dir(new_shape, old_revid, 'root-id', None, '')
 
338
        else:
 
339
            self.add_dir(new_shape, new_revid, 'root-id', None, '')
 
340
 
 
341
    def assertTransitionFromBasisToShape(self, basis_shape, basis_revid,
 
342
        new_shape, new_revid, extra_parent=None):
 
343
        # set the inventory revision ids.
 
344
        basis_shape.revision_id = basis_revid
 
345
        new_shape.revision_id = new_revid
 
346
        delta = self.make_inv_delta(basis_shape, new_shape)
 
347
        tree = self.make_branch_and_tree('tree')
 
348
        # the shapes need to be in the tree's repository to be able to set them
 
349
        # as a parent, but the file content is not needed.
 
350
        if basis_revid is not None:
 
351
            self.fake_up_revision(tree, basis_revid, basis_shape)
 
352
            parents = [basis_revid]
 
353
            if extra_parent is not None:
 
354
                parents.append(extra_parent)
 
355
            tree.set_parent_ids(parents)
 
356
        self.fake_up_revision(tree, new_revid, new_shape)
 
357
        self.assertDeltaApplicationResultsInExpectedBasis(tree, new_revid,
 
358
            delta, new_shape)
 
359
        osutils.rmtree('tree')
 
360
 
 
361
    def test_no_parents_just_root(self):
 
362
        """Test doing an empty commit - no parent, set a root only."""
 
363
        basis_shape = Inventory(root_id=None) # empty tree
 
364
        new_shape = Inventory() # tree with a root
 
365
        self.assertTransitionFromBasisToShape(basis_shape, None, new_shape,
 
366
            'new_parent')
 
367
 
 
368
    def test_no_parents_full_tree(self):
 
369
        """Test doing a regular initial commit with files and dirs."""
 
370
        basis_shape = Inventory(root_id=None) # empty tree
 
371
        revid = 'new-parent'
 
372
        new_shape = Inventory(root_id=None)
 
373
        self.add_dir(new_shape, revid, 'root-id', None, '')
 
374
        self.add_link(new_shape, revid, 'link-id', 'root-id', 'link', 'target')
 
375
        self.add_file(new_shape, revid, 'file-id', 'root-id', 'file', '1' * 32,
 
376
            12)
 
377
        self.add_dir(new_shape, revid, 'dir-id', 'root-id', 'dir')
 
378
        self.add_file(new_shape, revid, 'subfile-id', 'dir-id', 'subfile',
 
379
            '2' * 32, 24)
 
380
        self.assertTransitionFromBasisToShape(basis_shape, None, new_shape,
 
381
            revid)
 
382
 
 
383
    def test_file_content_change(self):
 
384
        old_revid = 'old-parent'
 
385
        basis_shape = Inventory(root_id=None)
 
386
        self.add_dir(basis_shape, old_revid, 'root-id', None, '')
 
387
        self.add_file(basis_shape, old_revid, 'file-id', 'root-id', 'file',
 
388
            '1' * 32, 12)
 
389
        new_revid = 'new-parent'
 
390
        new_shape = Inventory(root_id=None)
 
391
        self.add_new_root(new_shape, old_revid, new_revid)
 
392
        self.add_file(new_shape, new_revid, 'file-id', 'root-id', 'file',
 
393
            '2' * 32, 24)
 
394
        self.assertTransitionFromBasisToShape(basis_shape, old_revid,
 
395
            new_shape, new_revid)
 
396
 
 
397
    def test_link_content_change(self):
 
398
        old_revid = 'old-parent'
 
399
        basis_shape = Inventory(root_id=None)
 
400
        self.add_dir(basis_shape, old_revid, 'root-id', None, '')
 
401
        self.add_link(basis_shape, old_revid, 'link-id', 'root-id', 'link',
 
402
            'old-target')
 
403
        new_revid = 'new-parent'
 
404
        new_shape = Inventory(root_id=None)
 
405
        self.add_new_root(new_shape, old_revid, new_revid)
 
406
        self.add_link(new_shape, new_revid, 'link-id', 'root-id', 'link',
 
407
            'new-target')
 
408
        self.assertTransitionFromBasisToShape(basis_shape, old_revid,
 
409
            new_shape, new_revid)
 
410
 
 
411
    def test_kind_changes(self):
 
412
        def do_file(inv, revid):
 
413
            self.add_file(inv, revid, 'path-id', 'root-id', 'path', '1' * 32,
 
414
                12)
 
415
        def do_link(inv, revid):
 
416
            self.add_link(inv, revid, 'path-id', 'root-id', 'path', 'target')
 
417
        def do_dir(inv, revid):
 
418
            self.add_dir(inv, revid, 'path-id', 'root-id', 'path')
 
419
        for old_factory in (do_file, do_link, do_dir):
 
420
            for new_factory in (do_file, do_link, do_dir):
 
421
                if old_factory == new_factory:
 
422
                    continue
 
423
                old_revid = 'old-parent'
 
424
                basis_shape = Inventory(root_id=None)
 
425
                self.add_dir(basis_shape, old_revid, 'root-id', None, '')
 
426
                old_factory(basis_shape, old_revid)
 
427
                new_revid = 'new-parent'
 
428
                new_shape = Inventory(root_id=None)
 
429
                self.add_new_root(new_shape, old_revid, new_revid)
 
430
                new_factory(new_shape, new_revid)
 
431
                self.assertTransitionFromBasisToShape(basis_shape, old_revid,
 
432
                    new_shape, new_revid)
 
433
 
 
434
    def test_content_from_second_parent_is_dropped(self):
 
435
        left_revid = 'left-parent'
 
436
        basis_shape = Inventory(root_id=None)
 
437
        self.add_dir(basis_shape, left_revid, 'root-id', None, '')
 
438
        self.add_link(basis_shape, left_revid, 'link-id', 'root-id', 'link',
 
439
            'left-target')
 
440
        # the right shape has content - file, link, subdir with a child,
 
441
        # that should all be discarded by the call.
 
442
        right_revid = 'right-parent'
 
443
        right_shape = Inventory(root_id=None)
 
444
        self.add_dir(right_shape, left_revid, 'root-id', None, '')
 
445
        self.add_link(right_shape, right_revid, 'link-id', 'root-id', 'link',
 
446
            'some-target')
 
447
        self.add_dir(right_shape, right_revid, 'subdir-id', 'root-id', 'dir')
 
448
        self.add_file(right_shape, right_revid, 'file-id', 'subdir-id', 'file',
 
449
            '2' * 32, 24)
 
450
        new_revid = 'new-parent'
 
451
        new_shape = Inventory(root_id=None)
 
452
        self.add_new_root(new_shape, left_revid, new_revid)
 
453
        self.add_link(new_shape, new_revid, 'link-id', 'root-id', 'link',
 
454
            'new-target')
 
455
        self.assertTransitionFromBasisToShape(basis_shape, left_revid,
 
456
            new_shape, new_revid, right_revid)
 
457
 
 
458
    def test_parent_id_changed(self):
 
459
        # test that when the only change to an entry is its parent id changing
 
460
        # that it is handled correctly (that is it keeps the same path)
 
461
        old_revid = 'old-parent'
 
462
        basis_shape = Inventory(root_id=None)
 
463
        self.add_dir(basis_shape, old_revid, 'root-id', None, '')
 
464
        self.add_dir(basis_shape, old_revid, 'orig-parent-id', 'root-id', 'dir')
 
465
        self.add_dir(basis_shape, old_revid, 'dir-id', 'orig-parent-id', 'dir')
 
466
        new_revid = 'new-parent'
 
467
        new_shape = Inventory(root_id=None)
 
468
        self.add_new_root(new_shape, old_revid, new_revid)
 
469
        self.add_dir(new_shape, new_revid, 'new-parent-id', 'root-id', 'dir')
 
470
        self.add_dir(new_shape, new_revid, 'dir-id', 'new-parent-id', 'dir')
 
471
        self.assertTransitionFromBasisToShape(basis_shape, old_revid,
 
472
            new_shape, new_revid)
 
473
 
 
474
    def test_name_changed(self):
 
475
        # test that when the only change to an entry is its name changing that
 
476
        # it is handled correctly (that is it keeps the same parent id)
 
477
        old_revid = 'old-parent'
 
478
        basis_shape = Inventory(root_id=None)
 
479
        self.add_dir(basis_shape, old_revid, 'root-id', None, '')
 
480
        self.add_dir(basis_shape, old_revid, 'parent-id', 'root-id', 'origdir')
 
481
        self.add_dir(basis_shape, old_revid, 'dir-id', 'parent-id', 'olddir')
 
482
        new_revid = 'new-parent'
 
483
        new_shape = Inventory(root_id=None)
 
484
        self.add_new_root(new_shape, old_revid, new_revid)
 
485
        self.add_dir(new_shape, new_revid, 'parent-id', 'root-id', 'newdir')
 
486
        self.add_dir(new_shape, new_revid, 'dir-id', 'parent-id', 'newdir')
 
487
        self.assertTransitionFromBasisToShape(basis_shape, old_revid,
 
488
            new_shape, new_revid)
 
489
 
 
490
    def test_path_swap(self):
 
491
        # test a A->B and B->A path swap.
 
492
        old_revid = 'old-parent'
 
493
        basis_shape = Inventory(root_id=None)
 
494
        self.add_dir(basis_shape, old_revid, 'root-id', None, '')
 
495
        self.add_dir(basis_shape, old_revid, 'dir-id-A', 'root-id', 'A')
 
496
        self.add_dir(basis_shape, old_revid, 'dir-id-B', 'root-id', 'B')
 
497
        self.add_link(basis_shape, old_revid, 'link-id-C', 'root-id', 'C', 'C')
 
498
        self.add_link(basis_shape, old_revid, 'link-id-D', 'root-id', 'D', 'D')
 
499
        self.add_file(basis_shape, old_revid, 'file-id-E', 'root-id', 'E',
 
500
            '1' * 32, 12)
 
501
        self.add_file(basis_shape, old_revid, 'file-id-F', 'root-id', 'F',
 
502
            '2' * 32, 24)
 
503
        new_revid = 'new-parent'
 
504
        new_shape = Inventory(root_id=None)
 
505
        self.add_new_root(new_shape, old_revid, new_revid)
 
506
        self.add_dir(new_shape, new_revid, 'dir-id-A', 'root-id', 'B')
 
507
        self.add_dir(new_shape, new_revid, 'dir-id-B', 'root-id', 'A')
 
508
        self.add_link(new_shape, new_revid, 'link-id-C', 'root-id', 'D', 'C')
 
509
        self.add_link(new_shape, new_revid, 'link-id-D', 'root-id', 'C', 'D')
 
510
        self.add_file(new_shape, new_revid, 'file-id-E', 'root-id', 'F',
 
511
            '1' * 32, 12)
 
512
        self.add_file(new_shape, new_revid, 'file-id-F', 'root-id', 'E',
 
513
            '2' * 32, 24)
 
514
        self.assertTransitionFromBasisToShape(basis_shape, old_revid,
 
515
            new_shape, new_revid)
 
516
 
 
517
    def test_adds(self):
 
518
        # test adding paths and dirs, including adding to a newly added dir.
 
519
        old_revid = 'old-parent'
 
520
        basis_shape = Inventory(root_id=None)
 
521
        # with a root, so its a commit after the first.
 
522
        self.add_dir(basis_shape, old_revid, 'root-id', None, '')
 
523
        new_revid = 'new-parent'
 
524
        new_shape = Inventory(root_id=None)
 
525
        self.add_new_root(new_shape, old_revid, new_revid)
 
526
        self.add_dir(new_shape, new_revid, 'dir-id-A', 'root-id', 'A')
 
527
        self.add_link(new_shape, new_revid, 'link-id-B', 'root-id', 'B', 'C')
 
528
        self.add_file(new_shape, new_revid, 'file-id-C', 'root-id', 'C',
 
529
            '1' * 32, 12)
 
530
        self.add_file(new_shape, new_revid, 'file-id-D', 'dir-id-A', 'D',
 
531
            '2' * 32, 24)
 
532
        self.assertTransitionFromBasisToShape(basis_shape, old_revid,
 
533
            new_shape, new_revid)
 
534
 
 
535
    def test_removes(self):
 
536
        # test removing paths, including paths that are within other also
 
537
        # removed paths.
 
538
        old_revid = 'old-parent'
 
539
        basis_shape = Inventory(root_id=None)
 
540
        self.add_dir(basis_shape, old_revid, 'root-id', None, '')
 
541
        self.add_dir(basis_shape, old_revid, 'dir-id-A', 'root-id', 'A')
 
542
        self.add_link(basis_shape, old_revid, 'link-id-B', 'root-id', 'B', 'C')
 
543
        self.add_file(basis_shape, old_revid, 'file-id-C', 'root-id', 'C',
 
544
            '1' * 32, 12)
 
545
        self.add_file(basis_shape, old_revid, 'file-id-D', 'dir-id-A', 'D',
 
546
            '2' * 32, 24)
 
547
        new_revid = 'new-parent'
 
548
        new_shape = Inventory(root_id=None)
 
549
        self.add_new_root(new_shape, old_revid, new_revid)
 
550
        self.assertTransitionFromBasisToShape(basis_shape, old_revid,
 
551
            new_shape, new_revid)
 
552
 
 
553
    def test_move_to_added_dir(self):
 
554
        old_revid = 'old-parent'
 
555
        basis_shape = Inventory(root_id=None)
 
556
        self.add_dir(basis_shape, old_revid, 'root-id', None, '')
 
557
        self.add_link(basis_shape, old_revid, 'link-id-B', 'root-id', 'B', 'C')
 
558
        new_revid = 'new-parent'
 
559
        new_shape = Inventory(root_id=None)
 
560
        self.add_new_root(new_shape, old_revid, new_revid)
 
561
        self.add_dir(new_shape, new_revid, 'dir-id-A', 'root-id', 'A')
 
562
        self.add_link(new_shape, new_revid, 'link-id-B', 'dir-id-A', 'B', 'C')
 
563
        self.assertTransitionFromBasisToShape(basis_shape, old_revid,
 
564
            new_shape, new_revid)
 
565
 
 
566
    def test_move_from_removed_dir(self):
 
567
        old_revid = 'old-parent'
 
568
        basis_shape = Inventory(root_id=None)
 
569
        self.add_dir(basis_shape, old_revid, 'root-id', None, '')
 
570
        self.add_dir(basis_shape, old_revid, 'dir-id-A', 'root-id', 'A')
 
571
        self.add_link(basis_shape, old_revid, 'link-id-B', 'dir-id-A', 'B', 'C')
 
572
        new_revid = 'new-parent'
 
573
        new_shape = Inventory(root_id=None)
 
574
        self.add_new_root(new_shape, old_revid, new_revid)
 
575
        self.add_link(new_shape, new_revid, 'link-id-B', 'root-id', 'B', 'C')
 
576
        self.assertTransitionFromBasisToShape(basis_shape, old_revid,
 
577
            new_shape, new_revid)