/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/per_repository/test_commit_builder.py

  • Committer: Martin Pool
  • Date: 2009-03-23 07:25:27 UTC
  • mfrom: (4183 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4189.
  • Revision ID: mbp@sourcefrog.net-20090323072527-317my4n8zej1g6v9
merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
58
58
            builder.record_entry_contents(ie, parent_invs, '', tree,
59
59
                tree.path_content_summary(''))
60
60
 
61
 
    def test_finish_inventory(self):
 
61
    def test_finish_inventory_with_record_root(self):
62
62
        tree = self.make_branch_and_tree(".")
63
63
        tree.lock_write()
64
64
        try:
65
65
            builder = tree.branch.get_commit_builder([])
 
66
            repo = tree.branch.repository
66
67
            self.record_root(builder, tree)
67
68
            builder.finish_inventory()
68
 
            tree.branch.repository.commit_write_group()
 
69
            repo.commit_write_group()
 
70
        finally:
 
71
            tree.unlock()
 
72
 
 
73
    def test_finish_inventory_record_iter_changes(self):
 
74
        tree = self.make_branch_and_tree(".")
 
75
        tree.lock_write()
 
76
        try:
 
77
            builder = tree.branch.get_commit_builder([])
 
78
            try:
 
79
                builder.record_iter_changes(tree, tree.last_revision(),
 
80
                    tree.iter_changes(tree.basis_tree()))
 
81
                builder.finish_inventory()
 
82
            except:
 
83
                builder.abort()
 
84
                raise
 
85
            repo = tree.branch.repository
 
86
            repo.commit_write_group()
69
87
        finally:
70
88
            tree.unlock()
71
89
 
80
98
        finally:
81
99
            tree.unlock()
82
100
 
 
101
    def test_abort_record_iter_changes(self):
 
102
        tree = self.make_branch_and_tree(".")
 
103
        tree.lock_write()
 
104
        try:
 
105
            builder = tree.branch.get_commit_builder([])
 
106
            try:
 
107
                basis = tree.basis_tree()
 
108
                last_rev = tree.last_revision()
 
109
                changes = tree.iter_changes(basis)
 
110
                builder.record_iter_changes(tree, last_rev, changes)
 
111
                builder.finish_inventory()
 
112
            finally:
 
113
                builder.abort()
 
114
        finally:
 
115
            tree.unlock()
 
116
 
83
117
    def test_commit_message(self):
84
118
        tree = self.make_branch_and_tree(".")
85
119
        tree.lock_write()
125
159
        self.assertEqual(revision_id,
126
160
            tree.branch.repository.get_inventory(revision_id).revision_id)
127
161
 
128
 
    def test_commit_without_root_errors(self):
 
162
    def test_commit_with_revision_id_record_iter_changes(self):
 
163
        tree = self.make_branch_and_tree(".")
 
164
        tree.lock_write()
 
165
        try:
 
166
            # use a unicode revision id to test more corner cases.
 
167
            # The repository layer is meant to handle this.
 
168
            revision_id = u'\xc8abc'.encode('utf8')
 
169
            try:
 
170
                try:
 
171
                    builder = tree.branch.get_commit_builder([],
 
172
                        revision_id=revision_id)
 
173
                except errors.NonAsciiRevisionId:
 
174
                    revision_id = 'abc'
 
175
                    builder = tree.branch.get_commit_builder([],
 
176
                        revision_id=revision_id)
 
177
            except errors.CannotSetRevisionId:
 
178
                # This format doesn't support supplied revision ids
 
179
                return
 
180
            self.assertFalse(builder.random_revid)
 
181
            try:
 
182
                builder.record_iter_changes(tree, tree.last_revision(),
 
183
                    tree.iter_changes(tree.basis_tree()))
 
184
                builder.finish_inventory()
 
185
            except:
 
186
                builder.abort()
 
187
                raise
 
188
            builder.finish_inventory()
 
189
            self.assertEqual(revision_id, builder.commit('foo bar'))
 
190
        finally:
 
191
            tree.unlock()
 
192
        self.assertTrue(tree.branch.repository.has_revision(revision_id))
 
193
        # the revision id must be set on the inventory when saving it. This
 
194
        # does not precisely test that - a repository that wants to can add it
 
195
        # on deserialisation, but thats all the current contract guarantees
 
196
        # anyway.
 
197
        self.assertEqual(revision_id,
 
198
            tree.branch.repository.get_inventory(revision_id).revision_id)
 
199
 
 
200
    def test_commit_without_root_or_record_iter_changes_errors(self):
129
201
        tree = self.make_branch_and_tree(".")
130
202
        tree.lock_write()
131
203
        try:
154
226
            delta, version_recorded, fs_hash = builder.record_entry_contents(
155
227
                ie, [parent_tree.inventory], '', tree,
156
228
                tree.path_content_summary(''))
 
229
            # Regardless of repository root behaviour we should consider this a
 
230
            # pointless commit.
 
231
            self.assertFalse(builder.any_changes())
157
232
            self.assertFalse(version_recorded)
158
233
            # if the repository format recorded a new root revision, that
159
234
            # should be in the delta
174
249
        else:
175
250
            tree.unlock()
176
251
 
 
252
    def test_commit_unchanged_root_record_iter_changes(self):
 
253
        tree = self.make_branch_and_tree(".")
 
254
        old_revision_id = tree.commit('')
 
255
        tree.lock_write()
 
256
        builder = tree.branch.get_commit_builder([old_revision_id])
 
257
        try:
 
258
            builder.record_iter_changes(tree, old_revision_id, [])
 
259
            # Regardless of repository root behaviour we should consider this a
 
260
            # pointless commit.
 
261
            self.assertFalse(builder.any_changes())
 
262
            builder.finish_inventory()
 
263
            new_root = tree.branch.repository.get_inventory(
 
264
                builder._new_revision_id).root
 
265
            if tree.branch.repository.supports_rich_root():
 
266
                # We should not have seen a new root revision
 
267
                self.assertEqual(old_revision_id, new_root.revision)
 
268
            else:
 
269
                # We should see a new root revision
 
270
                self.assertNotEqual(old_revision_id, new_root.revision)
 
271
        finally:
 
272
            builder.abort()
 
273
            tree.unlock()
 
274
 
177
275
    def test_commit(self):
178
276
        tree = self.make_branch_and_tree(".")
179
277
        tree.lock_write()
283
381
        self.addCleanup(rev_tree.unlock)
284
382
        self.assertFalse(rev_tree.path2id('foo'))
285
383
 
 
384
    def test_record_delete_record_iter_changes(self):
 
385
        tree = self.make_branch_and_tree(".")
 
386
        self.build_tree(["foo"])
 
387
        tree.add(["foo"], ["foo-id"])
 
388
        rev_id = tree.commit("added foo")
 
389
        tree.lock_write()
 
390
        try:
 
391
            builder = tree.branch.get_commit_builder([rev_id])
 
392
            try:
 
393
                delete_change = ('foo-id', ('foo', None), True, (True, False),
 
394
                    (tree.path2id(''), None), ('foo', None), ('file', None),
 
395
                    (False, None))
 
396
                builder.record_iter_changes(tree, rev_id, [delete_change])
 
397
                self.assertEqual(("foo", None, "foo-id", None),
 
398
                    builder._basis_delta[0])
 
399
                self.assertTrue(builder.any_changes())
 
400
                builder.finish_inventory()
 
401
                rev_id2 = builder.commit('delete foo')
 
402
            except:
 
403
                builder.abort()
 
404
                raise
 
405
        finally:
 
406
            tree.unlock()
 
407
        rev_tree = builder.revision_tree()
 
408
        rev_tree.lock_read()
 
409
        self.addCleanup(rev_tree.unlock)
 
410
        self.assertFalse(rev_tree.path2id('foo'))
 
411
 
286
412
    def test_record_delete_without_notification(self):
287
413
        tree = self.make_branch_and_tree(".")
288
414
        self.build_tree(["foo"])
316
442
        self.assertEqual(rev_id, rev_tree.get_revision_id())
317
443
        self.assertEqual([], rev_tree.get_parent_ids())
318
444
 
 
445
    def test_revision_tree_record_iter_changes(self):
 
446
        tree = self.make_branch_and_tree(".")
 
447
        tree.lock_write()
 
448
        try:
 
449
            builder = tree.branch.get_commit_builder([])
 
450
            try:
 
451
                builder.record_iter_changes(tree, _mod_revision.NULL_REVISION,
 
452
                    tree.iter_changes(tree.basis_tree()))
 
453
                builder.finish_inventory()
 
454
                rev_id = builder.commit('foo bar')
 
455
            except:
 
456
                builder.abort()
 
457
                raise
 
458
            rev_tree = builder.revision_tree()
 
459
            # Just a couple simple tests to ensure that it actually follows
 
460
            # the RevisionTree api.
 
461
            self.assertEqual(rev_id, rev_tree.get_revision_id())
 
462
            self.assertEqual([], rev_tree.get_parent_ids())
 
463
        finally:
 
464
            tree.unlock()
 
465
 
319
466
    def test_root_entry_has_revision(self):
320
467
        # test the root revision created and put in the basis
321
468
        # has the right rev id.
 
469
        # XXX: RBC 20081118 - this test is too big, it depends on the exact
 
470
        # behaviour of tree methods and so on; it should be written to the
 
471
        # commit builder interface directly.
322
472
        tree = self.make_branch_and_tree('.')
323
473
        rev_id = tree.commit('message')
324
474
        basis_tree = tree.basis_tree()
350
500
        else:
351
501
            self.assertEqual(rev2, tree2.inventory.root.revision)
352
502
 
353
 
    def _add_commit_check_unchanged(self, tree, name):
 
503
    def _add_commit_check_unchanged(self, tree, name, mini_commit=None):
354
504
        tree.add([name], [name + 'id'])
355
505
        rev1 = tree.commit('')
356
 
        rev2 = self.mini_commit(tree, name, name, False, False)
 
506
        if mini_commit is None:
 
507
            mini_commit = self.mini_commit
 
508
        rev2 = mini_commit(tree, name, name, False, False)
357
509
        tree1, tree2 = self._get_revtrees(tree, [rev1, rev2])
358
510
        self.assertEqual(rev1, tree1.inventory[name + 'id'].revision)
359
511
        self.assertEqual(rev1, tree2.inventory[name + 'id'].revision)
368
520
        self.build_tree(['dir/'])
369
521
        self._add_commit_check_unchanged(tree, 'dir')
370
522
 
 
523
    def test_last_modified_revision_after_commit_dir_unchanged_ric(self):
 
524
        # committing without changing a dir does not change the last modified.
 
525
        tree = self.make_branch_and_tree('.')
 
526
        self.build_tree(['dir/'])
 
527
        self._add_commit_check_unchanged(tree, 'dir',
 
528
            mini_commit=self.mini_commit_record_iter_changes)
 
529
 
371
530
    def test_last_modified_revision_after_commit_dir_contents_unchanged(self):
372
531
        # committing without changing a dir does not change the last modified
373
532
        # of the dir even the dirs contents are changed.
392
551
        self.build_tree(['file'])
393
552
        self._add_commit_check_unchanged(tree, 'file')
394
553
 
 
554
    def test_last_modified_revision_after_commit_file_unchanged_ric(self):
 
555
        # committing without changing a file does not change the last modified.
 
556
        tree = self.make_branch_and_tree('.')
 
557
        self.build_tree(['file'])
 
558
        self._add_commit_check_unchanged(tree, 'file',
 
559
            mini_commit=self.mini_commit_record_iter_changes)
 
560
 
395
561
    def test_last_modified_revision_after_commit_link_unchanged(self):
396
562
        # committing without changing a link does not change the last modified.
397
563
        self.requireFeature(tests.SymlinkFeature)
399
565
        os.symlink('target', 'link')
400
566
        self._add_commit_check_unchanged(tree, 'link')
401
567
 
 
568
    def test_last_modified_revision_after_commit_link_unchanged_ric(self):
 
569
        # committing without changing a link does not change the last modified.
 
570
        self.requireFeature(tests.SymlinkFeature)
 
571
        tree = self.make_branch_and_tree('.')
 
572
        os.symlink('target', 'link')
 
573
        self._add_commit_check_unchanged(tree, 'link',
 
574
            mini_commit=self.mini_commit_record_iter_changes)
 
575
 
402
576
    def _add_commit_renamed_check_changed(self, tree, name,
403
 
        expect_fs_hash=False):
 
577
        expect_fs_hash=False, mini_commit=None):
404
578
        def rename():
405
579
            tree.rename_one(name, 'new_' + name)
 
580
        if mini_commit is None:
 
581
            mini_commit = self.mini_commit
406
582
        self._add_commit_change_check_changed(tree, name, rename,
407
 
            expect_fs_hash=expect_fs_hash)
 
583
            expect_fs_hash=expect_fs_hash, mini_commit=mini_commit)
408
584
 
409
585
    def test_last_modified_revision_after_rename_dir_changes(self):
410
586
        # renaming a dir changes the last modified.
412
588
        self.build_tree(['dir/'])
413
589
        self._add_commit_renamed_check_changed(tree, 'dir')
414
590
 
 
591
    def test_last_modified_revision_after_rename_dir_changes_ric(self):
 
592
        # renaming a dir changes the last modified.
 
593
        tree = self.make_branch_and_tree('.')
 
594
        self.build_tree(['dir/'])
 
595
        self._add_commit_renamed_check_changed(tree, 'dir',
 
596
            mini_commit=self.mini_commit_record_iter_changes)
 
597
 
415
598
    def test_last_modified_revision_after_rename_file_changes(self):
416
599
        # renaming a file changes the last modified.
417
600
        tree = self.make_branch_and_tree('.')
419
602
        self._add_commit_renamed_check_changed(tree, 'file',
420
603
            expect_fs_hash=True)
421
604
 
 
605
    def test_last_modified_revision_after_rename_file_changes_ric(self):
 
606
        # renaming a file changes the last modified.
 
607
        tree = self.make_branch_and_tree('.')
 
608
        self.build_tree(['file'])
 
609
        self._add_commit_renamed_check_changed(tree, 'file',
 
610
            expect_fs_hash=True,
 
611
            mini_commit=self.mini_commit_record_iter_changes)
 
612
 
422
613
    def test_last_modified_revision_after_rename_link_changes(self):
423
614
        # renaming a link changes the last modified.
424
615
        self.requireFeature(tests.SymlinkFeature)
426
617
        os.symlink('target', 'link')
427
618
        self._add_commit_renamed_check_changed(tree, 'link')
428
619
 
 
620
    def test_last_modified_revision_after_rename_link_changes_ric(self):
 
621
        # renaming a link changes the last modified.
 
622
        self.requireFeature(tests.SymlinkFeature)
 
623
        tree = self.make_branch_and_tree('.')
 
624
        os.symlink('target', 'link')
 
625
        self._add_commit_renamed_check_changed(tree, 'link',
 
626
            mini_commit=self.mini_commit_record_iter_changes)
 
627
 
429
628
    def _add_commit_reparent_check_changed(self, tree, name,
430
 
        expect_fs_hash=False):
 
629
        expect_fs_hash=False, mini_commit=None):
431
630
        self.build_tree(['newparent/'])
432
631
        tree.add(['newparent'])
433
632
        def reparent():
434
633
            tree.rename_one(name, 'newparent/new_' + name)
435
634
        self._add_commit_change_check_changed(tree, name, reparent,
436
 
            expect_fs_hash=expect_fs_hash)
 
635
            expect_fs_hash=expect_fs_hash, mini_commit=mini_commit)
437
636
 
438
637
    def test_last_modified_revision_after_reparent_dir_changes(self):
439
638
        # reparenting a dir changes the last modified.
441
640
        self.build_tree(['dir/'])
442
641
        self._add_commit_reparent_check_changed(tree, 'dir')
443
642
 
 
643
    def test_last_modified_revision_after_reparent_dir_changes_ric(self):
 
644
        # reparenting a dir changes the last modified.
 
645
        tree = self.make_branch_and_tree('.')
 
646
        self.build_tree(['dir/'])
 
647
        self._add_commit_reparent_check_changed(tree, 'dir',
 
648
            mini_commit=self.mini_commit_record_iter_changes)
 
649
 
444
650
    def test_last_modified_revision_after_reparent_file_changes(self):
445
651
        # reparenting a file changes the last modified.
446
652
        tree = self.make_branch_and_tree('.')
448
654
        self._add_commit_reparent_check_changed(tree, 'file',
449
655
            expect_fs_hash=True)
450
656
 
 
657
    def test_last_modified_revision_after_reparent_file_changes_ric(self):
 
658
        # reparenting a file changes the last modified.
 
659
        tree = self.make_branch_and_tree('.')
 
660
        self.build_tree(['file'])
 
661
        self._add_commit_reparent_check_changed(tree, 'file',
 
662
            expect_fs_hash=True,
 
663
            mini_commit=self.mini_commit_record_iter_changes)
 
664
 
451
665
    def test_last_modified_revision_after_reparent_link_changes(self):
452
666
        # reparenting a link changes the last modified.
453
667
        self.requireFeature(tests.SymlinkFeature)
455
669
        os.symlink('target', 'link')
456
670
        self._add_commit_reparent_check_changed(tree, 'link')
457
671
 
 
672
    def test_last_modified_revision_after_reparent_link_changes_ric(self):
 
673
        # reparenting a link changes the last modified.
 
674
        self.requireFeature(tests.SymlinkFeature)
 
675
        tree = self.make_branch_and_tree('.')
 
676
        os.symlink('target', 'link')
 
677
        self._add_commit_reparent_check_changed(tree, 'link',
 
678
            mini_commit=self.mini_commit_record_iter_changes)
 
679
 
458
680
    def _add_commit_change_check_changed(self, tree, name, changer,
459
 
        expect_fs_hash=False):
 
681
        expect_fs_hash=False, mini_commit=None):
460
682
        tree.add([name], [name + 'id'])
461
683
        rev1 = tree.commit('')
462
684
        changer()
463
 
        rev2 = self.mini_commit(tree, name, tree.id2path(name + 'id'),
 
685
        if mini_commit is None:
 
686
            mini_commit = self.mini_commit
 
687
        rev2 = mini_commit(tree, name, tree.id2path(name + 'id'),
464
688
            expect_fs_hash=expect_fs_hash)
465
689
        tree1, tree2 = self._get_revtrees(tree, [rev1, rev2])
466
690
        self.assertEqual(rev1, tree1.inventory[name + 'id'].revision)
549
773
            tree.unlock()
550
774
        return rev2
551
775
 
 
776
    def mini_commit_record_iter_changes(self, tree, name, new_name,
 
777
        records_version=True, delta_against_basis=True, expect_fs_hash=False):
 
778
        """Perform a miniature commit looking for record entry results.
 
779
 
 
780
        This version uses the record_iter_changes interface.
 
781
        
 
782
        :param tree: The tree to commit.
 
783
        :param name: The path in the basis tree of the tree being committed.
 
784
        :param new_name: The path in the tree being committed.
 
785
        :param records_version: True if the commit of new_name is expected to
 
786
            record a new version.
 
787
        :param delta_against_basis: True of the commit of new_name is expected
 
788
            to have a delta against the basis.
 
789
        :param expect_fs_hash: ignored, present for compatibility with test
 
790
            driver code for 'mini_commit'.
 
791
        """
 
792
        tree.lock_write()
 
793
        try:
 
794
            # mini manual commit here so we can check the return of
 
795
            # record_entry_contents.
 
796
            parent_ids = tree.get_parent_ids()
 
797
            builder = tree.branch.get_commit_builder(parent_ids)
 
798
            parent_tree = tree.basis_tree()
 
799
            parent_tree.lock_read()
 
800
            self.addCleanup(parent_tree.unlock)
 
801
            parent_invs = [parent_tree.inventory]
 
802
            for parent_id in parent_ids[1:]:
 
803
                parent_invs.append(tree.branch.repository.revision_tree(
 
804
                    parent_id).inventory)
 
805
            changes = list(tree.iter_changes(parent_tree))
 
806
            builder.record_iter_changes(tree, parent_ids[0], changes)
 
807
            delta = builder._basis_delta
 
808
            delta_dict = dict((change[2], change) for change in delta)
 
809
            file_id = tree.path2id(new_name)
 
810
            version_recorded = (file_id in delta_dict and
 
811
                delta_dict[file_id][3] is not None and
 
812
                delta_dict[file_id][3].revision == builder._new_revision_id)
 
813
            if records_version:
 
814
                self.assertTrue(version_recorded)
 
815
            else:
 
816
                self.assertFalse(version_recorded)
 
817
            builder.finish_inventory()
 
818
            new_inventory = builder.revision_tree().inventory
 
819
            new_entry = new_inventory[file_id]
 
820
            if delta_against_basis:
 
821
                expected_delta = (name, new_name, file_id, new_entry)
 
822
                self.assertEqual(expected_delta, delta_dict[file_id])
 
823
            else:
 
824
                expected_delta = None
 
825
                self.assertFalse(version_recorded)
 
826
            rev2 = builder.commit('')
 
827
            tree.set_parent_ids([rev2])
 
828
        except:
 
829
            builder.abort()
 
830
            tree.unlock()
 
831
            raise
 
832
        else:
 
833
            tree.unlock()
 
834
        return rev2
 
835
 
552
836
    def assertFileGraph(self, expected_graph, tree, tip):
553
837
        # all the changes that have occured should be in the ancestry
554
838
        # (closest to a public per-file graph API we have today)
566
850
        self._add_commit_change_check_changed(tree, 'file', change_file,
567
851
            expect_fs_hash=True)
568
852
 
 
853
    def test_last_modified_revision_after_content_file_changes_ric(self):
 
854
        # altering a file changes the last modified.
 
855
        tree = self.make_branch_and_tree('.')
 
856
        self.build_tree(['file'])
 
857
        def change_file():
 
858
            tree.put_file_bytes_non_atomic('fileid', 'new content')
 
859
        self._add_commit_change_check_changed(tree, 'file', change_file,
 
860
            expect_fs_hash=True,
 
861
            mini_commit=self.mini_commit_record_iter_changes)
 
862
 
569
863
    def test_last_modified_revision_after_content_link_changes(self):
570
864
        # changing a link changes the last modified.
571
865
        self.requireFeature(tests.SymlinkFeature)
576
870
            os.symlink('newtarget', 'link')
577
871
        self._add_commit_change_check_changed(tree, 'link', change_link)
578
872
 
 
873
    def test_last_modified_revision_after_content_link_changes_ric(self):
 
874
        # changing a link changes the last modified.
 
875
        self.requireFeature(tests.SymlinkFeature)
 
876
        tree = self.make_branch_and_tree('.')
 
877
        os.symlink('target', 'link')
 
878
        def change_link():
 
879
            os.unlink('link')
 
880
            os.symlink('newtarget', 'link')
 
881
        self._add_commit_change_check_changed(tree, 'link', change_link,
 
882
            mini_commit=self.mini_commit_record_iter_changes)
 
883
 
579
884
    def _commit_sprout(self, tree, name):
580
885
        tree.add([name], [name + 'id'])
581
886
        rev_id = tree.commit('')
585
890
        tree.rename_one(name, 'new_' + name)
586
891
        return tree.commit('')
587
892
 
588
 
    def _commit_sprout_rename_merge(self, tree1, name, expect_fs_hash=False):
 
893
    def _commit_sprout_rename_merge(self, tree1, name, expect_fs_hash=False,
 
894
        mini_commit=None):
 
895
        """Do a rename in both trees."""
589
896
        rev1, tree2 = self._commit_sprout(tree1, name)
590
897
        # change both sides equally
591
898
        rev2 = self._rename_in_tree(tree1, name)
592
899
        rev3 = self._rename_in_tree(tree2, name)
593
900
        tree1.merge_from_branch(tree2.branch)
594
 
        rev4 = self.mini_commit(tree1, 'new_' + name, 'new_' + name,
 
901
        if mini_commit is None:
 
902
            mini_commit = self.mini_commit
 
903
        rev4 = mini_commit(tree1, 'new_' + name, 'new_' + name,
595
904
            expect_fs_hash=expect_fs_hash)
596
905
        tree3, = self._get_revtrees(tree1, [rev4])
597
906
        self.assertEqual(rev4, tree3.inventory[name + 'id'].revision)
609
918
        self.build_tree(['t1/dir/'])
610
919
        self._commit_sprout_rename_merge(tree1, 'dir')
611
920
 
 
921
    def test_last_modified_revision_after_merge_dir_changes_ric(self):
 
922
        # merge a dir changes the last modified.
 
923
        tree1 = self.make_branch_and_tree('t1')
 
924
        self.build_tree(['t1/dir/'])
 
925
        self._commit_sprout_rename_merge(tree1, 'dir',
 
926
            mini_commit=self.mini_commit_record_iter_changes)
 
927
 
612
928
    def test_last_modified_revision_after_merge_file_changes(self):
613
929
        # merge a file changes the last modified.
614
930
        tree1 = self.make_branch_and_tree('t1')
615
931
        self.build_tree(['t1/file'])
616
932
        self._commit_sprout_rename_merge(tree1, 'file', expect_fs_hash=True)
617
933
 
 
934
    def test_last_modified_revision_after_merge_file_changes_ric(self):
 
935
        # merge a file changes the last modified.
 
936
        tree1 = self.make_branch_and_tree('t1')
 
937
        self.build_tree(['t1/file'])
 
938
        self._commit_sprout_rename_merge(tree1, 'file', expect_fs_hash=True,
 
939
            mini_commit=self.mini_commit_record_iter_changes)
 
940
 
618
941
    def test_last_modified_revision_after_merge_link_changes(self):
619
942
        # merge a link changes the last modified.
620
943
        self.requireFeature(tests.SymlinkFeature)
622
945
        os.symlink('target', 't1/link')
623
946
        self._commit_sprout_rename_merge(tree1, 'link')
624
947
 
625
 
    def _commit_sprout_rename_merge_converged(self, tree1, name):
 
948
    def test_last_modified_revision_after_merge_link_changes_ric(self):
 
949
        # merge a link changes the last modified.
 
950
        self.requireFeature(tests.SymlinkFeature)
 
951
        tree1 = self.make_branch_and_tree('t1')
 
952
        os.symlink('target', 't1/link')
 
953
        self._commit_sprout_rename_merge(tree1, 'link',
 
954
            mini_commit=self.mini_commit_record_iter_changes)
 
955
 
 
956
    def _commit_sprout_rename_merge_converged(self, tree1, name,
 
957
        mini_commit=None):
 
958
        # Make a merge which just incorporates a change from a branch:
 
959
        # The per-file graph is straight line, and no alteration occurs
 
960
        # in the inventory.
626
961
        rev1, tree2 = self._commit_sprout(tree1, name)
627
962
        # change on the other side to merge back
628
963
        rev2 = self._rename_in_tree(tree2, name)
629
964
        tree1.merge_from_branch(tree2.branch)
630
 
        rev3 = self.mini_commit(tree1, name, 'new_' + name, False)
 
965
        if mini_commit is None:
 
966
            mini_commit = self.mini_commit
 
967
        rev3 = mini_commit(tree1, name, 'new_' + name, False)
631
968
        tree3, = self._get_revtrees(tree1, [rev2])
632
969
        self.assertEqual(rev2, tree3.inventory[name + 'id'].revision)
633
970
        file_id = name + 'id'
636
973
        expected_graph[(file_id, rev2)] = ((file_id, rev1),)
637
974
        self.assertFileGraph(expected_graph, tree1, (file_id, rev2))
638
975
 
639
 
    def test_last_modified_revision_after_converged_merge_dir_changes(self):
640
 
        # merge a dir changes the last modified.
 
976
    def _commit_sprout_make_merge(self, tree1, make, mini_commit=None):
 
977
        # Make a merge which incorporates the addition of a new object to
 
978
        # another branch. The per-file graph shows no additional change
 
979
        # in the merge because its a straight line.
 
980
        rev1 = tree1.commit('')
 
981
        tree2 = tree1.bzrdir.sprout('t2').open_workingtree()
 
982
        # make and commit on the other side to merge back
 
983
        make('t2/name')
 
984
        file_id = 'nameid'
 
985
        tree2.add(['name'], [file_id])
 
986
        rev2 = tree2.commit('')
 
987
        tree1.merge_from_branch(tree2.branch)
 
988
        if mini_commit is None:
 
989
            mini_commit = self.mini_commit
 
990
        rev3 = mini_commit(tree1, None, 'name', False)
 
991
        tree3, = self._get_revtrees(tree1, [rev2])
 
992
        # in rev2, name should be only changed in rev2
 
993
        self.assertEqual(rev2, tree3.inventory[file_id].revision)
 
994
        expected_graph = {}
 
995
        expected_graph[(file_id, rev2)] = ()
 
996
        self.assertFileGraph(expected_graph, tree1, (file_id, rev2))
 
997
 
 
998
    def test_last_modified_revision_after_converged_merge_dir_unchanged(self):
 
999
        # merge a dir that changed preserves the last modified.
641
1000
        tree1 = self.make_branch_and_tree('t1')
642
1001
        self.build_tree(['t1/dir/'])
643
1002
        self._commit_sprout_rename_merge_converged(tree1, 'dir')
644
1003
 
645
 
    def test_last_modified_revision_after_converged_merge_file_changes(self):
646
 
        # merge a file changes the last modified.
 
1004
    def test_last_modified_revision_after_converged_merge_dir_unchanged_ric(self):
 
1005
        # merge a dir that changed preserves the last modified.
 
1006
        tree1 = self.make_branch_and_tree('t1')
 
1007
        self.build_tree(['t1/dir/'])
 
1008
        self._commit_sprout_rename_merge_converged(tree1, 'dir',
 
1009
            mini_commit=self.mini_commit_record_iter_changes)
 
1010
 
 
1011
    def test_last_modified_revision_after_converged_merge_file_unchanged(self):
 
1012
        # merge a file that changed preserves the last modified.
647
1013
        tree1 = self.make_branch_and_tree('t1')
648
1014
        self.build_tree(['t1/file'])
649
1015
        self._commit_sprout_rename_merge_converged(tree1, 'file')
650
1016
 
651
 
    def test_last_modified_revision_after_converged_merge_link_changes(self):
652
 
        # merge a link changes the last modified.
 
1017
    def test_last_modified_revision_after_converged_merge_file_unchanged_ric(self):
 
1018
        # merge a file that changed preserves the last modified.
 
1019
        tree1 = self.make_branch_and_tree('t1')
 
1020
        self.build_tree(['t1/file'])
 
1021
        self._commit_sprout_rename_merge_converged(tree1, 'file',
 
1022
            mini_commit=self.mini_commit_record_iter_changes)
 
1023
 
 
1024
    def test_last_modified_revision_after_converged_merge_link_unchanged(self):
 
1025
        # merge a link that changed preserves the last modified.
653
1026
        self.requireFeature(tests.SymlinkFeature)
654
1027
        tree1 = self.make_branch_and_tree('t1')
655
1028
        os.symlink('target', 't1/link')
656
1029
        self._commit_sprout_rename_merge_converged(tree1, 'link')
657
1030
 
 
1031
    def test_last_modified_revision_after_converged_merge_link_unchanged_ric(self):
 
1032
        # merge a link that changed preserves the last modified.
 
1033
        self.requireFeature(tests.SymlinkFeature)
 
1034
        tree1 = self.make_branch_and_tree('t1')
 
1035
        os.symlink('target', 't1/link')
 
1036
        self._commit_sprout_rename_merge_converged(tree1, 'link',
 
1037
            mini_commit=self.mini_commit_record_iter_changes)
 
1038
 
 
1039
    def test_last_modified_revision_after_merge_new_dir_unchanged(self):
 
1040
        # merge a new dir does not change the last modified.
 
1041
        tree1 = self.make_branch_and_tree('t1')
 
1042
        self._commit_sprout_make_merge(tree1, self.make_dir)
 
1043
 
 
1044
    def test_last_modified_revision_after_merge_new_dir_unchanged_ric(self):
 
1045
        # merge a new dir does not change the last modified.
 
1046
        tree1 = self.make_branch_and_tree('t1')
 
1047
        self._commit_sprout_make_merge(tree1, self.make_dir,
 
1048
            mini_commit=self.mini_commit_record_iter_changes)
 
1049
 
 
1050
    def test_last_modified_revision_after_merge_new_file_unchanged(self):
 
1051
        # merge a new file does not change the last modified.
 
1052
        tree1 = self.make_branch_and_tree('t1')
 
1053
        self._commit_sprout_make_merge(tree1, self.make_file)
 
1054
 
 
1055
    def test_last_modified_revision_after_merge_new_file_unchanged_ric(self):
 
1056
        # merge a new file does not change the last modified.
 
1057
        tree1 = self.make_branch_and_tree('t1')
 
1058
        self._commit_sprout_make_merge(tree1, self.make_file,
 
1059
            mini_commit=self.mini_commit_record_iter_changes)
 
1060
 
 
1061
    def test_last_modified_revision_after_merge_new_link_unchanged(self):
 
1062
        # merge a new link does not change the last modified.
 
1063
        tree1 = self.make_branch_and_tree('t1')
 
1064
        self._commit_sprout_make_merge(tree1, self.make_link)
 
1065
 
 
1066
    def test_last_modified_revision_after_merge_new_link_unchanged_ric(self):
 
1067
        # merge a new link does not change the last modified.
 
1068
        tree1 = self.make_branch_and_tree('t1')
 
1069
        self._commit_sprout_make_merge(tree1, self.make_link,
 
1070
            mini_commit=self.mini_commit_record_iter_changes)
 
1071
 
658
1072
    def make_dir(self, name):
659
1073
        self.build_tree([name + '/'])
660
1074
 
665
1079
        self.requireFeature(tests.SymlinkFeature)
666
1080
        os.symlink('target', name)
667
1081
 
668
 
    def _check_kind_change(self, make_before, make_after, expect_fs_hash=False):
 
1082
    def _check_kind_change(self, make_before, make_after, expect_fs_hash=False,
 
1083
        mini_commit=None):
669
1084
        tree = self.make_branch_and_tree('.')
670
1085
        path = 'name'
671
1086
        make_before(path)
675
1090
            make_after(path)
676
1091
 
677
1092
        self._add_commit_change_check_changed(tree, path, change_kind,
678
 
            expect_fs_hash=expect_fs_hash)
 
1093
            expect_fs_hash=expect_fs_hash, mini_commit=mini_commit)
679
1094
 
680
1095
    def test_last_modified_dir_file(self):
681
1096
        self._check_kind_change(self.make_dir, self.make_file,
682
1097
            expect_fs_hash=True)
683
1098
 
 
1099
    def test_last_modified_dir_file_ric(self):
 
1100
        self._check_kind_change(self.make_dir, self.make_file,
 
1101
            expect_fs_hash=True,
 
1102
            mini_commit=self.mini_commit_record_iter_changes)
 
1103
 
684
1104
    def test_last_modified_dir_link(self):
685
1105
        self._check_kind_change(self.make_dir, self.make_link)
686
1106
 
 
1107
    def test_last_modified_dir_link_ric(self):
 
1108
        self._check_kind_change(self.make_dir, self.make_link,
 
1109
            mini_commit=self.mini_commit_record_iter_changes)
 
1110
 
687
1111
    def test_last_modified_link_file(self):
688
1112
        self._check_kind_change(self.make_link, self.make_file,
689
1113
            expect_fs_hash=True)
690
1114
 
 
1115
    def test_last_modified_link_file_ric(self):
 
1116
        self._check_kind_change(self.make_link, self.make_file,
 
1117
            expect_fs_hash=True,
 
1118
            mini_commit=self.mini_commit_record_iter_changes)
 
1119
 
691
1120
    def test_last_modified_link_dir(self):
692
1121
        self._check_kind_change(self.make_link, self.make_dir)
693
1122
 
 
1123
    def test_last_modified_link_dir_ric(self):
 
1124
        self._check_kind_change(self.make_link, self.make_dir,
 
1125
            mini_commit=self.mini_commit_record_iter_changes)
 
1126
 
694
1127
    def test_last_modified_file_dir(self):
695
1128
        self._check_kind_change(self.make_file, self.make_dir)
696
1129
 
 
1130
    def test_last_modified_file_dir_ric(self):
 
1131
        self._check_kind_change(self.make_file, self.make_dir,
 
1132
            mini_commit=self.mini_commit_record_iter_changes)
 
1133
 
697
1134
    def test_last_modified_file_link(self):
698
1135
        self._check_kind_change(self.make_file, self.make_link)
699
1136
 
 
1137
    def test_last_modified_file_link_ric(self):
 
1138
        self._check_kind_change(self.make_file, self.make_link,
 
1139
            mini_commit=self.mini_commit_record_iter_changes)
 
1140
 
700
1141
    def test_get_commit_builder_with_invalid_revprops(self):
701
1142
        branch = self.make_branch('.')
702
1143
        branch.repository.lock_write()