/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/branch_implementations/test_branch.py

merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007, 2008 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
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""Tests for branch implementations - tests a branch format."""
18
18
 
24
24
    bzrdir,
25
25
    errors,
26
26
    gpg,
 
27
    merge,
27
28
    urlutils,
28
29
    transactions,
29
30
    remote,
30
31
    repository,
 
32
    tests,
31
33
    )
32
34
from bzrlib.branch import Branch, needs_read_lock, needs_write_lock
33
35
from bzrlib.delta import TreeDelta
39
41
                           )
40
42
from bzrlib.osutils import getcwd
41
43
import bzrlib.revision
 
44
from bzrlib.symbol_versioning import deprecated_in
42
45
from bzrlib.tests import TestCase, TestCaseWithTransport, TestSkipped
43
46
from bzrlib.tests.branch_implementations import TestCaseWithBranch
44
 
from bzrlib.tests.HttpServer import HttpServer
 
47
from bzrlib.tests.http_server import HttpServer
45
48
from bzrlib.trace import mutter
46
49
from bzrlib.transport import get_transport
47
50
from bzrlib.transport.memory import MemoryServer
49
52
from bzrlib.workingtree import WorkingTree
50
53
 
51
54
 
 
55
class TestTestCaseWithBranch(TestCaseWithBranch):
 
56
 
 
57
    def test_branch_format_matches_bzrdir_branch_format(self):
 
58
        bzrdir_branch_format = self.bzrdir_format.get_branch_format()
 
59
        self.assertIs(self.branch_format.__class__,
 
60
                      bzrdir_branch_format.__class__)
 
61
 
 
62
    def test_make_branch_gets_expected_format(self):
 
63
        branch = self.make_branch('.')
 
64
        self.assertIs(self.branch_format.__class__,
 
65
            branch._format.__class__)
 
66
 
 
67
 
52
68
class TestBranch(TestCaseWithBranch):
53
69
 
54
 
    def test_append_revisions(self):
55
 
        """Test appending more than one revision"""
56
 
        wt = self.make_branch_and_tree('tree')
57
 
        wt.commit('f', rev_id='rev1')
58
 
        wt.commit('f', rev_id='rev2')
59
 
        wt.commit('f', rev_id='rev3')
60
 
 
61
 
        br = self.get_branch()
62
 
        br.fetch(wt.branch)
63
 
        br.append_revision("rev1")
64
 
        self.assertEquals(br.revision_history(), ["rev1",])
65
 
        br.append_revision("rev2", "rev3")
66
 
        self.assertEquals(br.revision_history(), ["rev1", "rev2", "rev3"])
67
 
        self.assertRaises(errors.ReservedId, br.append_revision, 'current:')
68
 
 
69
70
    def test_create_tree_with_merge(self):
70
71
        tree = self.create_tree_with_merge()
71
 
        ancestry_graph = tree.branch.repository.get_revision_graph('rev-3')
72
 
        self.assertEqual({'rev-1':(),
 
72
        tree.lock_read()
 
73
        self.addCleanup(tree.unlock)
 
74
        graph = tree.branch.repository.get_graph()
 
75
        ancestry_graph = graph.get_parent_map(
 
76
            tree.branch.repository.all_revision_ids())
 
77
        self.assertEqual({'rev-1':('null:',),
73
78
                          'rev-2':('rev-1', ),
74
79
                          'rev-1.1.1':('rev-1', ),
75
80
                          'rev-3':('rev-2', 'rev-1.1.1', ),
105
110
        wt.commit('lala!', rev_id='revision-1', allow_pointless=False)
106
111
 
107
112
        b2 = self.make_branch('b2')
108
 
        self.assertEqual((1, []), b2.fetch(b1))
 
113
        b2.fetch(b1)
109
114
 
110
115
        rev = b2.repository.get_revision('revision-1')
111
116
        tree = b2.repository.revision_tree('revision-1')
 
117
        tree.lock_read()
 
118
        self.addCleanup(tree.unlock)
112
119
        self.assertEqual(tree.get_file_text('foo-id'), 'hello')
113
120
 
114
121
    def test_get_revision_delta(self):
173
180
        wt_a.add(['one'])
174
181
        wt_a.commit('commit one', rev_id='1')
175
182
 
176
 
        branch_b = wt_a.bzrdir.sprout('b', revision_id='1').open_branch()
 
183
        branch_b = wt_a.branch.bzrdir.sprout('b', revision_id='1').open_branch()
177
184
        self.assertEqual(wt_a.branch.base, branch_b.get_parent())
178
185
        return branch_b
179
186
 
180
187
    def test_clone_branch_nickname(self):
181
188
        # test the nick name is preserved always
182
 
        raise TestSkipped('XXX branch cloning is not yet tested..')
 
189
        raise TestSkipped('XXX branch cloning is not yet tested.')
183
190
 
184
191
    def test_clone_branch_parent(self):
185
192
        # test the parent is preserved always
206
213
        self.assertEqual(branch.get_submit_branch(), 'sftp://example.com')
207
214
        branch.set_submit_branch('sftp://example.net')
208
215
        self.assertEqual(branch.get_submit_branch(), 'sftp://example.net')
209
 
        
 
216
 
210
217
    def test_public_branch(self):
211
218
        """public location can be queried and set"""
212
219
        branch = self.make_branch('branch')
223
230
        wt = self.make_branch_and_tree('.')
224
231
        wt.set_parent_ids(['non:existent@rev--ision--0--2'],
225
232
            allow_leftmost_as_ghost=True)
 
233
        self.assertEqual(['non:existent@rev--ision--0--2'],
 
234
            wt.get_parent_ids())
226
235
        rev_id = wt.commit('commit against a ghost first parent.')
227
236
        rev = wt.branch.repository.get_revision(rev_id)
228
237
        self.assertEqual(rev.parent_ids, ['non:existent@rev--ision--0--2'])
250
259
                          None)
251
260
 
252
261
# TODO 20051003 RBC:
253
 
# compare the gpg-to-sign info for a commit with a ghost and 
 
262
# compare the gpg-to-sign info for a commit with a ghost and
254
263
#     an identical tree without a ghost
255
264
# fetch missing should rewrite the TOC of weaves to list newly available parents.
256
 
        
 
265
 
257
266
    def test_sign_existing_revision(self):
258
267
        wt = self.make_branch_and_tree('.')
259
268
        branch = wt.branch
260
269
        wt.commit("base", allow_pointless=True, rev_id='A')
261
270
        from bzrlib.testament import Testament
262
271
        strategy = gpg.LoopbackGPGStrategy(None)
 
272
        branch.repository.lock_write()
 
273
        branch.repository.start_write_group()
263
274
        branch.repository.sign_revision('A', strategy)
 
275
        branch.repository.commit_write_group()
 
276
        branch.repository.unlock()
264
277
        self.assertEqual('-----BEGIN PSEUDO-SIGNED CONTENT-----\n' +
265
278
                         Testament.from_revision(branch.repository,
266
279
                         'A').as_short_text() +
270
283
    def test_store_signature(self):
271
284
        wt = self.make_branch_and_tree('.')
272
285
        branch = wt.branch
273
 
        branch.repository.store_revision_signature(
274
 
            gpg.LoopbackGPGStrategy(None), 'FOO', 'A')
 
286
        branch.lock_write()
 
287
        try:
 
288
            branch.repository.start_write_group()
 
289
            try:
 
290
                branch.repository.store_revision_signature(
 
291
                    gpg.LoopbackGPGStrategy(None), 'FOO', 'A')
 
292
            except:
 
293
                branch.repository.abort_write_group()
 
294
                raise
 
295
            else:
 
296
                branch.repository.commit_write_group()
 
297
        finally:
 
298
            branch.unlock()
 
299
        # A signature without a revision should not be accessible.
275
300
        self.assertRaises(errors.NoSuchRevision,
276
301
                          branch.repository.has_signature_for_revision_id,
277
302
                          'A')
284
309
        wt = self.make_branch_and_tree('source')
285
310
        wt.commit('A', allow_pointless=True, rev_id='A')
286
311
        repo = wt.branch.repository
 
312
        repo.lock_write()
 
313
        repo.start_write_group()
287
314
        repo.sign_revision('A', gpg.LoopbackGPGStrategy(None))
 
315
        repo.commit_write_group()
 
316
        repo.unlock()
288
317
        #FIXME: clone should work to urls,
289
318
        # wt.clone should work to disks.
290
319
        self.build_tree(['target/'])
292
321
        self.assertEqual(repo.get_signature_text('A'),
293
322
                         d2.open_repository().get_signature_text('A'))
294
323
 
 
324
    def test_missing_revisions(self):
 
325
        t1 = self.make_branch_and_tree('b1')
 
326
        rev1 = t1.commit('one')
 
327
        t2 = t1.bzrdir.sprout('b2').open_workingtree()
 
328
        rev2 = t1.commit('two')
 
329
        rev3 = t1.commit('three')
 
330
 
 
331
        self.assertEqual([rev2, rev3],
 
332
            self.applyDeprecated(deprecated_in((1, 6, 0)),
 
333
            t2.branch.missing_revisions, t1.branch))
 
334
 
 
335
        self.assertEqual([],
 
336
            self.applyDeprecated(deprecated_in((1, 6, 0)),
 
337
            t2.branch.missing_revisions, t1.branch, stop_revision=1))
 
338
        self.assertEqual([rev2],
 
339
            self.applyDeprecated(deprecated_in((1, 6, 0)),
 
340
            t2.branch.missing_revisions, t1.branch, stop_revision=2))
 
341
        self.assertEqual([rev2, rev3],
 
342
            self.applyDeprecated(deprecated_in((1, 6, 0)),
 
343
            t2.branch.missing_revisions, t1.branch, stop_revision=3))
 
344
 
 
345
        self.assertRaises(errors.NoSuchRevision,
 
346
            self.applyDeprecated, deprecated_in((1, 6, 0)),
 
347
            t2.branch.missing_revisions, t1.branch, stop_revision=4)
 
348
 
 
349
        rev4 = t2.commit('four')
 
350
        self.assertRaises(errors.DivergedBranches,
 
351
            self.applyDeprecated, deprecated_in((1, 6, 0)),
 
352
            t2.branch.missing_revisions, t1.branch)
 
353
 
295
354
    def test_nicks(self):
296
355
        """Test explicit and implicit branch nicknames.
297
 
        
 
356
 
298
357
        Nicknames are implicitly the name of the branch's directory, unless an
299
358
        explicit nickname is set.  That is, an explicit nickname always
300
359
        overrides the implicit one.
311
370
        # Set the branch nick explicitly.  This will ensure there's a branch
312
371
        # config file in the branch.
313
372
        branch.nick = "Aaron's branch"
314
 
        branch.nick = "Aaron's branch"
315
373
        if not isinstance(branch, remote.RemoteBranch):
316
 
            controlfilename = branch.control_files.controlfilename
317
 
            self.failUnless(t.has(t.relpath(controlfilename("branch.conf"))))
 
374
            self.failUnless(branch._transport.has("branch.conf"))
318
375
        # Because the nick has been set explicitly, the nick is now always
319
376
        # "Aaron's branch", regardless of directory name.
320
377
        self.assertEqual(branch.nick, "Aaron's branch")
358
415
        text = tree.branch._format.get_format_description()
359
416
        self.failUnless(len(text))
360
417
 
361
 
    def test_check_branch_report_results(self):
362
 
        """Checking a branch produces results which can be printed"""
363
 
        branch = self.make_branch('.')
364
 
        result = branch.check()
365
 
        # reports results through logging
366
 
        result.report_results(verbose=True)
367
 
        result.report_results(verbose=False)
368
 
 
369
418
    def test_get_commit_builder(self):
370
419
        branch = self.make_branch(".")
371
420
        branch.lock_write()
393
442
        tree_a = self.make_branch_and_tree('a')
394
443
        branch_a = tree_a.branch
395
444
        checkout_b = branch_a.create_checkout('b')
396
 
        self.assertEqual(None, checkout_b.last_revision())
 
445
        self.assertEqual('null:', checkout_b.last_revision())
397
446
        checkout_b.commit('rev1', rev_id='rev1')
398
447
        self.assertEqual('rev1', branch_a.last_revision())
399
448
        self.assertNotEqual(checkout_b.branch.base, branch_a.base)
445
494
        self.assertEquals(br.revision_history(), [])
446
495
 
447
496
 
 
497
class TestBranchFormat(TestCaseWithBranch):
 
498
 
 
499
    def test_branch_format_network_name(self):
 
500
        br = self.make_branch('.')
 
501
        format = br._format
 
502
        network_name = format.network_name()
 
503
        self.assertIsInstance(network_name, str)
 
504
        # We want to test that the network_name matches the actual format on
 
505
        # disk. For local branches that means that using network_name as a key
 
506
        # in the registry gives back the same format. For remote branches we
 
507
        # check that the network_name of the RemoteBranchFormat we have locally
 
508
        # matches the actual format present on disk.
 
509
        if isinstance(format, remote.RemoteBranchFormat):
 
510
            br._ensure_real()
 
511
            real_branch = br._real_branch
 
512
            self.assertEqual(real_branch._format.network_name(), network_name)
 
513
        else:
 
514
            registry = branch.network_format_registry
 
515
            looked_up_format = registry.get(network_name)
 
516
            self.assertEqual(format.__class__, looked_up_format.__class__)
 
517
 
 
518
 
448
519
class ChrootedTests(TestCaseWithBranch):
449
520
    """A support class that provides readonly urls outside the local namespace.
450
521
 
468
539
        self.assertEqual('', relpath)
469
540
        branch, relpath = Branch.open_containing(self.get_readonly_url('g/p/q'))
470
541
        self.assertEqual('g/p/q', relpath)
471
 
        
 
542
 
472
543
 
473
544
class InstrumentedTransaction(object):
474
545
 
543
614
                                   ensure_config_dir_exists)
544
615
        ensure_config_dir_exists()
545
616
        fn = locations_config_filename()
546
 
        print >> open(fn, 'wt'), ("[%s]\n"
547
 
                                  "push_location=foo" %
548
 
                                  self.get_branch().base[:-1])
 
617
        open(fn, 'wt').write(("[%s]\n"
 
618
                                  "push_location=foo\n" %
 
619
                                  self.get_branch().base[:-1]))
549
620
        self.assertEqual("foo", self.get_branch().get_push_location())
550
621
 
551
622
    def test_set_push_location(self):
568
639
        self.assertEqual(None,
569
640
            made_branch._format.get_reference(made_branch.bzrdir))
570
641
 
 
642
    def test_set_reference(self):
 
643
        """set_reference on all regular branches should be callable."""
 
644
        if not self.branch_format.is_supported():
 
645
            # unsupported formats are not loopback testable
 
646
            # because the default open will not open them and
 
647
            # they may not be initializable.
 
648
            return
 
649
        this_branch = self.make_branch('this')
 
650
        other_branch = self.make_branch('other')
 
651
        try:
 
652
            this_branch._format.set_reference(this_branch.bzrdir, other_branch)
 
653
        except NotImplementedError:
 
654
            # that's ok
 
655
            pass
 
656
        else:
 
657
            ref = this_branch._format.get_reference(this_branch.bzrdir)
 
658
            self.assertEqual(ref, other_branch.base)
 
659
 
571
660
    def test_format_initialize_find_open(self):
572
661
        # loopback test to check the current format initializes to itself.
573
662
        if not self.branch_format.is_supported():
611
700
        try:
612
701
            branch.bind(branch2)
613
702
        except errors.UpgradeRequired:
614
 
            raise TestSkipped('Format does not support binding')
 
703
            raise tests.TestNotApplicable('Format does not support binding')
615
704
        self.assertTrue(branch.unbind())
616
705
        self.assertFalse(branch.unbind())
617
706
        self.assertIs(None, branch.get_bound_location())
621
710
        try:
622
711
            self.assertIs(None, branch.get_old_bound_location())
623
712
        except errors.UpgradeRequired:
624
 
            raise TestSkipped('Format does not store old bound locations')
 
713
            raise tests.TestNotApplicable(
 
714
                    'Format does not store old bound locations')
625
715
        branch2 = self.make_branch('branch2')
626
716
        branch.bind(branch2)
627
717
        self.assertIs(None, branch.get_old_bound_location())
628
718
        branch.unbind()
629
719
        self.assertContainsRe(branch.get_old_bound_location(), '\/branch2\/$')
630
720
 
 
721
    def test_bind_diverged(self):
 
722
        tree_a = self.make_branch_and_tree('tree_a')
 
723
        tree_a.commit('rev1a')
 
724
        tree_b = tree_a.bzrdir.sprout('tree_b').open_workingtree()
 
725
        tree_a.commit('rev2a')
 
726
        tree_b.commit('rev2b')
 
727
        try:
 
728
            tree_b.branch.bind(tree_a.branch)
 
729
        except errors.UpgradeRequired:
 
730
            raise tests.TestNotApplicable('Format does not support binding')
 
731
 
631
732
 
632
733
class TestStrict(TestCaseWithBranch):
633
734
 
652
753
        tree3.merge_from_branch(tree2.branch)
653
754
        tree3.commit('empty commit 6')
654
755
        tree2.pull(tree3.branch)
 
756
 
 
757
 
 
758
class TestIgnoreFallbacksParameter(TestCaseWithBranch):
 
759
 
 
760
    def make_branch_with_fallback(self):
 
761
        fallback = self.make_branch('fallback')
 
762
        if not fallback._format.supports_stacking():
 
763
            raise tests.TestNotApplicable("format does not support stacking")
 
764
        stacked = self.make_branch('stacked')
 
765
        stacked.set_stacked_on_url(fallback.base)
 
766
        return stacked
 
767
 
 
768
    def test_fallbacks_not_opened(self):
 
769
        stacked = self.make_branch_with_fallback()
 
770
        self.get_transport('').rename('fallback', 'moved')
 
771
        reopened = stacked.bzrdir.open_branch(ignore_fallbacks=True)
 
772
        self.assertEqual([], reopened.repository._fallback_repositories)
 
773
 
 
774
    def test_fallbacks_are_opened(self):
 
775
        stacked = self.make_branch_with_fallback()
 
776
        reopened = stacked.bzrdir.open_branch(ignore_fallbacks=False)
 
777
        self.assertLength(1, reopened.repository._fallback_repositories)
 
778
 
 
779
 
 
780
class TestReferenceLocation(TestCaseWithBranch):
 
781
 
 
782
    def test_reference_parent(self):
 
783
        tree = self.make_branch_and_tree('tree')
 
784
        subtree = self.make_branch_and_tree('tree/subtree')
 
785
        subtree.set_root_id('subtree-id')
 
786
        try:
 
787
            tree.add_reference(subtree)
 
788
        except bzrlib.errors.UnsupportedOperation:
 
789
            raise tests.TestNotApplicable('Tree cannot hold references.')
 
790
        reference_parent = tree.branch.reference_parent('subtree-id',
 
791
                                                        'subtree')
 
792
        self.assertEqual(subtree.branch.base, reference_parent.base)
 
793
 
 
794
    def test_reference_parent_accepts_possible_transports(self):
 
795
        tree = self.make_branch_and_tree('tree')
 
796
        subtree = self.make_branch_and_tree('tree/subtree')
 
797
        subtree.set_root_id('subtree-id')
 
798
        try:
 
799
            tree.add_reference(subtree)
 
800
        except bzrlib.errors.UnsupportedOperation:
 
801
            raise tests.TestNotApplicable('Tree cannot hold references.')
 
802
        reference_parent = tree.branch.reference_parent('subtree-id',
 
803
            'subtree', possible_transports=[subtree.bzrdir.root_transport])
 
804
 
 
805
    def test_get_reference_info(self):
 
806
        branch = self.make_branch('branch')
 
807
        try:
 
808
            path, loc = branch.get_reference_info('file-id')
 
809
        except bzrlib.errors.UnsupportedOperation:
 
810
            raise tests.TestNotApplicable('Branch cannot hold references.')
 
811
        self.assertIs(None, path)
 
812
        self.assertIs(None, loc)
 
813
 
 
814
    def test_set_reference_info(self):
 
815
        branch = self.make_branch('branch')
 
816
        try:
 
817
            branch.set_reference_info('file-id', 'path/to/location',
 
818
                                      'path/to/file')
 
819
        except bzrlib.errors.UnsupportedOperation:
 
820
            raise tests.TestNotApplicable('Branch cannot hold references.')
 
821
 
 
822
    def test_set_get_reference_info(self):
 
823
        branch = self.make_branch('branch')
 
824
        try:
 
825
            branch.set_reference_info('file-id', 'path/to/file',
 
826
                                      'path/to/location')
 
827
        except bzrlib.errors.UnsupportedOperation:
 
828
            raise tests.TestNotApplicable('Branch cannot hold references.')
 
829
        # Create a new instance to ensure storage is permanent
 
830
        branch = Branch.open('branch')
 
831
        tree_path, branch_location = branch.get_reference_info('file-id')
 
832
        self.assertEqual('path/to/location', branch_location)
 
833
 
 
834
    def test_set_null_reference_info(self):
 
835
        branch = self.make_branch('branch')
 
836
        try:
 
837
            branch.set_reference_info('file-id', 'path/to/file',
 
838
                                      'path/to/location')
 
839
        except bzrlib.errors.UnsupportedOperation:
 
840
            raise tests.TestNotApplicable('Branch cannot hold references.')
 
841
        branch.set_reference_info('file-id', None, None)
 
842
        tree_path, branch_location = branch.get_reference_info('file-id')
 
843
        self.assertIs(None, tree_path)
 
844
        self.assertIs(None, branch_location)
 
845
 
 
846
    def test_set_null_reference_info_when_null(self):
 
847
        branch = self.make_branch('branch')
 
848
        try:
 
849
            tree_path, branch_location = branch.get_reference_info('file-id')
 
850
        except bzrlib.errors.UnsupportedOperation:
 
851
            raise tests.TestNotApplicable('Branch cannot hold references.')
 
852
        self.assertIs(None, tree_path)
 
853
        self.assertIs(None, branch_location)
 
854
        branch.set_reference_info('file-id', None, None)
 
855
 
 
856
    def test_set_null_requires_two_nones(self):
 
857
        branch = self.make_branch('branch')
 
858
        try:
 
859
            e = self.assertRaises(ValueError, branch.set_reference_info,
 
860
                                  'file-id', 'path', None)
 
861
        except bzrlib.errors.UnsupportedOperation:
 
862
            raise tests.TestNotApplicable('Branch cannot hold references.')
 
863
        self.assertEqual('tree_path must be None when branch_location is'
 
864
                         ' None.', str(e))
 
865
        e = self.assertRaises(ValueError, branch.set_reference_info,
 
866
                              'file-id', None, 'location')
 
867
        self.assertEqual('branch_location must be None when tree_path is'
 
868
                         ' None.', str(e))
 
869
 
 
870
    def make_branch_with_reference(self, location, reference_location,
 
871
                                   file_id='file-id'):
 
872
        branch = self.make_branch(location)
 
873
        try:
 
874
            branch.set_reference_info(file_id, 'path/to/file',
 
875
                                      reference_location)
 
876
        except bzrlib.errors.UnsupportedOperation:
 
877
            raise tests.TestNotApplicable('Branch cannot hold references.')
 
878
        return branch
 
879
 
 
880
    def test_reference_parent_from_reference_info_(self):
 
881
        referenced_branch = self.make_branch('reference_branch')
 
882
        branch = self.make_branch_with_reference('branch',
 
883
                                                 referenced_branch.base)
 
884
        parent = branch.reference_parent('file-id', 'path/to/file')
 
885
        self.assertEqual(parent.base, referenced_branch.base)
 
886
 
 
887
    def test_branch_relative_reference_location(self):
 
888
        branch = self.make_branch('branch')
 
889
        try:
 
890
            branch.set_reference_info('file-id', 'path/to/file',
 
891
            '../reference_branch')
 
892
        except bzrlib.errors.UnsupportedOperation:
 
893
            raise tests.TestNotApplicable('Branch cannot hold references.')
 
894
        referenced_branch = self.make_branch('reference_branch')
 
895
        parent = branch.reference_parent('file-id', 'path/to/file')
 
896
        self.assertEqual(parent.base, referenced_branch.base)
 
897
 
 
898
    def test_sprout_copies_reference_location(self):
 
899
        branch = self.make_branch_with_reference('branch', '../reference')
 
900
        new_branch = branch.bzrdir.sprout('new-branch').open_branch()
 
901
        self.assertEqual('../reference',
 
902
                         new_branch.get_reference_info('file-id')[1])
 
903
 
 
904
    def test_clone_copies_reference_location(self):
 
905
        branch = self.make_branch_with_reference('branch', '../reference')
 
906
        new_branch = branch.bzrdir.clone('new-branch').open_branch()
 
907
        self.assertEqual('../reference',
 
908
                         new_branch.get_reference_info('file-id')[1])
 
909
 
 
910
    def test_copied_locations_are_rebased(self):
 
911
        branch = self.make_branch_with_reference('branch', 'reference')
 
912
        new_branch = branch.bzrdir.sprout('branch/new-branch').open_branch()
 
913
        self.assertEqual('../reference',
 
914
                         new_branch.get_reference_info('file-id')[1])
 
915
 
 
916
    def test_update_references_retains_old_references(self):
 
917
        branch = self.make_branch_with_reference('branch', 'reference')
 
918
        new_branch = self.make_branch_with_reference(
 
919
            'new_branch', 'reference', 'file-id2')
 
920
        new_branch.update_references(branch)
 
921
        self.assertEqual('reference',
 
922
                         branch.get_reference_info('file-id')[1])
 
923
 
 
924
    def test_update_references_retains_known_references(self):
 
925
        branch = self.make_branch_with_reference('branch', 'reference')
 
926
        new_branch = self.make_branch_with_reference(
 
927
            'new_branch', 'reference2')
 
928
        new_branch.update_references(branch)
 
929
        self.assertEqual('reference',
 
930
                         branch.get_reference_info('file-id')[1])
 
931
 
 
932
    def test_update_references_skips_known_references(self):
 
933
        branch = self.make_branch_with_reference('branch', 'reference')
 
934
        new_branch = branch.bzrdir.sprout('branch/new-branch').open_branch()
 
935
        new_branch.set_reference_info('file-id', '../foo', '../foo')
 
936
        new_branch.update_references(branch)
 
937
        self.assertEqual('reference',
 
938
                         branch.get_reference_info('file-id')[1])
 
939
 
 
940
    def test_pull_updates_references(self):
 
941
        branch = self.make_branch_with_reference('branch', 'reference')
 
942
        new_branch = branch.bzrdir.sprout('branch/new-branch').open_branch()
 
943
        new_branch.set_reference_info('file-id2', '../foo', '../foo')
 
944
        branch.pull(new_branch)
 
945
        self.assertEqual('foo',
 
946
                         branch.get_reference_info('file-id2')[1])
 
947
 
 
948
    def test_push_updates_references(self):
 
949
        branch = self.make_branch_with_reference('branch', 'reference')
 
950
        new_branch = branch.bzrdir.sprout('branch/new-branch').open_branch()
 
951
        new_branch.set_reference_info('file-id2', '../foo', '../foo')
 
952
        new_branch.push(branch)
 
953
        self.assertEqual('foo',
 
954
                         branch.get_reference_info('file-id2')[1])
 
955
 
 
956
    def test_merge_updates_references(self):
 
957
        branch = self.make_branch_with_reference('branch', 'reference')
 
958
        tree = self.make_branch_and_tree('tree')
 
959
        tree.commit('foo')
 
960
        branch.pull(tree.branch)
 
961
        checkout = branch.create_checkout('checkout', lightweight=True)
 
962
        checkout.commit('bar')
 
963
        tree.lock_write()
 
964
        self.addCleanup(tree.unlock)
 
965
        merger = merge.Merger.from_revision_ids(None, tree,
 
966
                                                branch.last_revision(),
 
967
                                                other_branch=branch)
 
968
        merger.merge_type = merge.Merge3Merger
 
969
        merger.do_merge()
 
970
        self.assertEqual('../branch/reference',
 
971
                         tree.branch.get_reference_info('file-id')[1])