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

  • Committer: Martin Pool
  • Date: 2007-02-21 05:34:56 UTC
  • mfrom: (2296 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2309.
  • Revision ID: mbp@sourcefrog.net-20070221053456-vyr6o0ehqnbetrvb
merge trunk, in particular new Branch6 changes

Show diffs side-by-side

added added

removed removed

Lines of Context:
233
233
        try:
234
234
            if last_revision is None:
235
235
                pb.update('get source history')
236
 
                last_revision = from_branch.last_revision_info()[1]
 
236
                last_revision = from_branch.last_revision()
 
237
                if last_revision is None:
 
238
                    last_revision = _mod_revision.NULL_REVISION
237
239
            return self.repository.fetch(from_branch.repository,
238
240
                                         revision_id=last_revision,
239
241
                                         pb=nested_pb)
250
252
        """
251
253
        return None
252
254
    
 
255
    def get_old_bound_location(self):
 
256
        """Return the URL of the branch we used to be bound to
 
257
        """
 
258
        raise errors.UpgradeRequired(self.base)
 
259
 
253
260
    def get_commit_builder(self, parents, config=None, timestamp=None, 
254
261
                           timezone=None, committer=None, revprops=None, 
255
262
                           revision_id=None):
319
326
        """Older format branches cannot bind or unbind."""
320
327
        raise errors.UpgradeRequired(self.base)
321
328
 
 
329
    def set_append_revisions_only(self, enabled):
 
330
        """Older format branches are never restricted to append-only"""
 
331
        raise errors.UpgradeRequired(self.base)
 
332
 
322
333
    def last_revision(self):
323
334
        """Return last revision id, or None"""
324
335
        ph = self.revision_history()
375
386
        """Given a revision id, return its revno"""
376
387
        if revision_id is None:
377
388
            return 0
 
389
        revision_id = osutils.safe_revision_id(revision_id)
378
390
        history = self.revision_history()
379
391
        try:
380
392
            return history.index(revision_id) + 1
562
574
        result.set_parent(self.bzrdir.root_transport.base)
563
575
        return result
564
576
 
565
 
    @needs_read_lock
566
 
    def copy_content_into(self, destination, revision_id=None):
567
 
        """Copy the content of self into destination.
568
 
 
569
 
        revision_id: if not None, the revision history in the new branch will
570
 
                     be truncated to end with revision_id.
 
577
    def _synchronize_history(self, destination, revision_id):
 
578
        """Synchronize last revision and revision history between branches.
 
579
 
 
580
        This version is most efficient when the destination is also a
 
581
        BzrBranch5, but works for BzrBranch6 as long as the revision
 
582
        history is the true lefthand parent history, and all of the revisions
 
583
        are in the destination's repository.  If not, set_revision_history
 
584
        will fail.
 
585
 
 
586
        :param destination: The branch to copy the history into
 
587
        :param revision_id: The revision-id to truncate history at.  May
 
588
          be None to copy complete history.
571
589
        """
572
590
        new_history = self.revision_history()
573
591
        if revision_id is not None:
 
592
            revision_id = osutils.safe_revision_id(revision_id)
574
593
            try:
575
594
                new_history = new_history[:new_history.index(revision_id) + 1]
576
595
            except ValueError:
577
596
                rev = self.repository.get_revision(revision_id)
578
597
                new_history = rev.get_history(self.repository)[1:]
579
598
        destination.set_revision_history(new_history)
 
599
 
 
600
    @needs_read_lock
 
601
    def copy_content_into(self, destination, revision_id=None):
 
602
        """Copy the content of self into destination.
 
603
 
 
604
        revision_id: if not None, the revision history in the new branch will
 
605
                     be truncated to end with revision_id.
 
606
        """
 
607
        self._synchronize_history(destination, revision_id)
580
608
        try:
581
609
            parent = self.get_parent()
582
610
        except errors.InaccessibleParent, e:
625
653
            format.repository_format = weaverepo.RepositoryFormat7()
626
654
        else:
627
655
            format = self.repository.bzrdir.cloning_metadir()
 
656
            format.branch_format = self._format
628
657
        return format
629
658
 
630
659
    def create_checkout(self, to_location, revision_id=None,
717
746
        """Return the short format description for this format."""
718
747
        raise NotImplementedError(self.get_format_description)
719
748
 
 
749
    def _initialize_helper(self, a_bzrdir, utf8_files, lock_type='metadir',
 
750
                           set_format=True):
 
751
        """Initialize a branch in a bzrdir, with specified files
 
752
 
 
753
        :param a_bzrdir: The bzrdir to initialize the branch in
 
754
        :param utf8_files: The files to create as a list of
 
755
            (filename, content) tuples
 
756
        :param set_format: If True, set the format with
 
757
            self.get_format_string.  (BzrBranch4 has its format set
 
758
            elsewhere)
 
759
        :return: a branch in this format
 
760
        """
 
761
        mutter('creating branch %r in %s', self, a_bzrdir.transport.base)
 
762
        branch_transport = a_bzrdir.get_branch_transport(self)
 
763
        lock_map = {
 
764
            'metadir': ('lock', lockdir.LockDir),
 
765
            'branch4': ('branch-lock', lockable_files.TransportLock),
 
766
        }
 
767
        lock_name, lock_class = lock_map[lock_type]
 
768
        control_files = lockable_files.LockableFiles(branch_transport,
 
769
            lock_name, lock_class)
 
770
        control_files.create_lock()
 
771
        control_files.lock_write()
 
772
        if set_format:
 
773
            control_files.put_utf8('format', self.get_format_string())
 
774
        try:
 
775
            for file, content in utf8_files:
 
776
                control_files.put_utf8(file, content)
 
777
        finally:
 
778
            control_files.unlock()
 
779
        return self.open(a_bzrdir, _found=True)
 
780
 
720
781
    def initialize(self, a_bzrdir):
721
782
        """Create a branch of this format in a_bzrdir."""
722
783
        raise NotImplementedError(self.initialize)
857
918
        utf8_files = [('revision-history', ''),
858
919
                      ('branch-name', ''),
859
920
                      ]
860
 
        self._initialize_control_files(a_bzrdir, utf8_files,
861
 
             'branch-lock', lockable_files.TransportLock)
862
 
        return self.open(a_bzrdir, _found=True)
 
921
        return self._initialize_helper(a_bzrdir, utf8_files,
 
922
                                       lock_type='branch4', set_format=False)
863
923
 
864
924
    def __init__(self):
865
925
        super(BzrBranchFormat4, self).__init__()
906
966
        
907
967
    def initialize(self, a_bzrdir):
908
968
        """Create a branch of this format in a_bzrdir."""
909
 
        mutter('creating branch %r in %s', self, a_bzrdir.transport.base)
910
 
        branch_transport = a_bzrdir.get_branch_transport(self)
911
969
        utf8_files = [('revision-history', ''),
912
970
                      ('branch-name', ''),
913
971
                      ]
914
 
        control_files = lockable_files.LockableFiles(branch_transport, 'lock',
915
 
                                                     lockdir.LockDir)
916
 
        control_files.create_lock()
917
 
        control_files.lock_write()
918
 
        control_files.put_utf8('format', self.get_format_string())
919
 
        try:
920
 
            for file, content in utf8_files:
921
 
                control_files.put_utf8(file, content)
922
 
        finally:
923
 
            control_files.unlock()
924
 
        return self.open(a_bzrdir, _found=True, )
 
972
        return self._initialize_helper(a_bzrdir, utf8_files)
925
973
 
926
974
    def __init__(self):
927
975
        super(BzrBranchFormat5, self).__init__()
945
993
                          _repository=a_bzrdir.find_repository())
946
994
 
947
995
 
 
996
class BzrBranchFormat6(BzrBranchFormat5):
 
997
    """Branch format with last-revision
 
998
 
 
999
    Unlike previous formats, this has no explicit revision history. Instead,
 
1000
    this just stores the last-revision, and the left-hand history leading
 
1001
    up to there is the history.
 
1002
 
 
1003
    This format was introduced in bzr 0.15
 
1004
    """
 
1005
 
 
1006
    def get_format_string(self):
 
1007
        """See BranchFormat.get_format_string()."""
 
1008
        return "Bazaar-NG branch format 6\n"
 
1009
 
 
1010
    def get_format_description(self):
 
1011
        """See BranchFormat.get_format_description()."""
 
1012
        return "Branch format 6"
 
1013
 
 
1014
    def initialize(self, a_bzrdir):
 
1015
        """Create a branch of this format in a_bzrdir."""
 
1016
        utf8_files = [('last-revision', '0 null:\n'),
 
1017
                      ('branch-name', ''),
 
1018
                      ('branch.conf', '')
 
1019
                      ]
 
1020
        return self._initialize_helper(a_bzrdir, utf8_files)
 
1021
 
 
1022
    def open(self, a_bzrdir, _found=False):
 
1023
        """Return the branch object for a_bzrdir
 
1024
 
 
1025
        _found is a private parameter, do not use it. It is used to indicate
 
1026
               if format probing has already be done.
 
1027
        """
 
1028
        if not _found:
 
1029
            format = BranchFormat.find_format(a_bzrdir)
 
1030
            assert format.__class__ == self.__class__
 
1031
        transport = a_bzrdir.get_branch_transport(None)
 
1032
        control_files = lockable_files.LockableFiles(transport, 'lock',
 
1033
                                                     lockdir.LockDir)
 
1034
        return BzrBranch6(_format=self,
 
1035
                          _control_files=control_files,
 
1036
                          a_bzrdir=a_bzrdir,
 
1037
                          _repository=a_bzrdir.find_repository())
 
1038
 
 
1039
 
948
1040
class BranchReferenceFormat(BranchFormat):
949
1041
    """Bzr branch reference format.
950
1042
 
1020
1112
__default_format = BzrBranchFormat5()
1021
1113
BranchFormat.register_format(__default_format)
1022
1114
BranchFormat.register_format(BranchReferenceFormat())
 
1115
BranchFormat.register_format(BzrBranchFormat6())
1023
1116
BranchFormat.set_default_format(__default_format)
1024
1117
_legacy_formats = [BzrBranchFormat4(),
1025
1118
                   ]
1193
1286
    @needs_write_lock
1194
1287
    def append_revision(self, *revision_ids):
1195
1288
        """See Branch.append_revision."""
 
1289
        revision_ids = [osutils.safe_revision_id(r) for r in revision_ids]
1196
1290
        for revision_id in revision_ids:
1197
1291
            _mod_revision.check_not_reserved_id(revision_id)
1198
1292
            mutter("add {%s} to revision-history" % revision_id)
1200
1294
        rev_history.extend(revision_ids)
1201
1295
        self.set_revision_history(rev_history)
1202
1296
 
 
1297
    def _write_revision_history(self, history):
 
1298
        """Factored out of set_revision_history.
 
1299
 
 
1300
        This performs the actual writing to disk.
 
1301
        It is intended to be called by BzrBranch5.set_revision_history."""
 
1302
        self.control_files.put_bytes(
 
1303
            'revision-history', '\n'.join(history))
 
1304
 
1203
1305
    @needs_write_lock
1204
1306
    def set_revision_history(self, rev_history):
1205
1307
        """See Branch.set_revision_history."""
1206
 
        self.control_files.put_utf8(
1207
 
            'revision-history', '\n'.join(rev_history))
 
1308
        rev_history = [osutils.safe_revision_id(r) for r in rev_history]
 
1309
        self._write_revision_history(rev_history)
1208
1310
        transaction = self.get_transaction()
1209
1311
        history = transaction.map.find_revision_history()
1210
1312
        if history is not None:
1221
1323
        for hook in Branch.hooks['set_rh']:
1222
1324
            hook(self, rev_history)
1223
1325
 
 
1326
    @needs_write_lock
 
1327
    def set_last_revision_info(self, revno, revision_id):
 
1328
        revision_id = osutils.safe_revision_id(revision_id)
 
1329
        history = self._lefthand_history(revision_id)
 
1330
        assert len(history) == revno, '%d != %d' % (len(history), revno)
 
1331
        self.set_revision_history(history)
 
1332
 
 
1333
    def _gen_revision_history(self):
 
1334
        get_cached_utf8 = cache_utf8.get_cached_utf8
 
1335
        history = [get_cached_utf8(l.rstrip('\r\n')) for l in
 
1336
                self.control_files.get('revision-history').readlines()]
 
1337
        return history
 
1338
 
1224
1339
    @needs_read_lock
1225
1340
    def revision_history(self):
1226
1341
        """See Branch.revision_history."""
1229
1344
        if history is not None:
1230
1345
            # mutter("cache hit for revision-history in %s", self)
1231
1346
            return list(history)
1232
 
        decode_utf8 = cache_utf8.decode
1233
 
        history = [decode_utf8(l.rstrip('\r\n')) for l in
1234
 
                self.control_files.get('revision-history').readlines()]
 
1347
        history = self._gen_revision_history()
1235
1348
        transaction.map.add_revision_history(history)
1236
1349
        # this call is disabled because revision_history is 
1237
1350
        # not really an object yet, and the transaction is for objects.
1238
1351
        # transaction.register_clean(history, precious=True)
1239
1352
        return list(history)
1240
1353
 
1241
 
    @needs_write_lock
1242
 
    def generate_revision_history(self, revision_id, last_rev=None, 
1243
 
        other_branch=None):
1244
 
        """Create a new revision history that will finish with revision_id.
1245
 
        
1246
 
        :param revision_id: the new tip to use.
1247
 
        :param last_rev: The previous last_revision. If not None, then this
1248
 
            must be a ancestory of revision_id, or DivergedBranches is raised.
1249
 
        :param other_branch: The other branch that DivergedBranches should
1250
 
            raise with respect to.
1251
 
        """
 
1354
    def _lefthand_history(self, revision_id, last_rev=None,
 
1355
                          other_branch=None):
1252
1356
        # stop_revision must be a descendant of last_revision
1253
1357
        stop_graph = self.repository.get_revision_graph(revision_id)
1254
1358
        if last_rev is not None and last_rev not in stop_graph:
1265
1369
            except IndexError:
1266
1370
                current_rev_id = None
1267
1371
        new_history.reverse()
1268
 
        self.set_revision_history(new_history)
 
1372
        return new_history
 
1373
 
 
1374
    @needs_write_lock
 
1375
    def generate_revision_history(self, revision_id, last_rev=None,
 
1376
        other_branch=None):
 
1377
        """Create a new revision history that will finish with revision_id.
 
1378
 
 
1379
        :param revision_id: the new tip to use.
 
1380
        :param last_rev: The previous last_revision. If not None, then this
 
1381
            must be a ancestory of revision_id, or DivergedBranches is raised.
 
1382
        :param other_branch: The other branch that DivergedBranches should
 
1383
            raise with respect to.
 
1384
        """
 
1385
        revision_id = osutils.safe_revision_id(revision_id)
 
1386
        self.set_revision_history(self._lefthand_history(revision_id,
 
1387
            last_rev, other_branch))
1269
1388
 
1270
1389
    @needs_write_lock
1271
1390
    def update_revisions(self, other, stop_revision=None):
1277
1396
                if stop_revision is None:
1278
1397
                    # if there are no commits, we're done.
1279
1398
                    return
 
1399
            else:
 
1400
                stop_revision = osutils.safe_revision_id(stop_revision)
1280
1401
            # whats the current last revision, before we fetch [and change it
1281
1402
            # possibly]
1282
1403
            last_rev = self.last_revision()
1340
1461
        finally:
1341
1462
            source.unlock()
1342
1463
 
 
1464
    def _get_parent_location(self):
 
1465
        _locs = ['parent', 'pull', 'x-pull']
 
1466
        for l in _locs:
 
1467
            try:
 
1468
                return self.control_files.get(l).read().strip('\n')
 
1469
            except NoSuchFile:
 
1470
                pass
 
1471
        return None
 
1472
 
1343
1473
    @needs_read_lock
1344
1474
    def push(self, target, overwrite=False, stop_revision=None,
1345
1475
        _hook_master=None, _run_hooks=True):
1377
1507
    def get_parent(self):
1378
1508
        """See Branch.get_parent."""
1379
1509
 
1380
 
        _locs = ['parent', 'pull', 'x-pull']
1381
1510
        assert self.base[-1] == '/'
1382
 
        for l in _locs:
1383
 
            try:
1384
 
                parent = self.control_files.get(l).read().strip('\n')
1385
 
            except NoSuchFile:
1386
 
                continue
1387
 
            # This is an old-format absolute path to a local branch
1388
 
            # turn it into a url
1389
 
            if parent.startswith('/'):
1390
 
                parent = urlutils.local_path_to_url(parent.decode('utf8'))
1391
 
            try:
1392
 
                return urlutils.join(self.base[:-1], parent)
1393
 
            except errors.InvalidURLJoin, e:
1394
 
                raise errors.InaccessibleParent(parent, self.base)
1395
 
        return None
 
1511
        parent = self._get_parent_location()
 
1512
        if parent is None:
 
1513
            return parent
 
1514
        # This is an old-format absolute path to a local branch
 
1515
        # turn it into a url
 
1516
        if parent.startswith('/'):
 
1517
            parent = urlutils.local_path_to_url(parent.decode('utf8'))
 
1518
        try:
 
1519
            return urlutils.join(self.base[:-1], parent)
 
1520
        except errors.InvalidURLJoin, e:
 
1521
            raise errors.InaccessibleParent(parent, self.base)
1396
1522
 
1397
1523
    def get_push_location(self):
1398
1524
        """See Branch.get_push_location."""
1413
1539
        # FIXUP this and get_parent in a future branch format bump:
1414
1540
        # read and rewrite the file, and have the new format code read
1415
1541
        # using .get not .get_utf8. RBC 20060125
1416
 
        if url is None:
1417
 
            self.control_files._transport.delete('parent')
1418
 
        else:
 
1542
        if url is not None:
1419
1543
            if isinstance(url, unicode):
1420
1544
                try: 
1421
1545
                    url = url.encode('ascii')
1423
1547
                    raise bzrlib.errors.InvalidURL(url,
1424
1548
                        "Urls must be 7-bit ascii, "
1425
1549
                        "use bzrlib.urlutils.escape")
1426
 
                    
1427
1550
            url = urlutils.relative_url(self.base, url)
1428
 
            self.control_files.put('parent', StringIO(url + '\n'))
 
1551
        self._set_parent_location(url)
 
1552
 
 
1553
    def _set_parent_location(self, url):
 
1554
        if url is None:
 
1555
            self.control_files._transport.delete('parent')
 
1556
        else:
 
1557
            assert isinstance(url, str)
 
1558
            self.control_files.put_bytes('parent', url + '\n')
1429
1559
 
1430
1560
    @deprecated_function(zero_nine)
1431
1561
    def tree_config(self):
1692
1822
BranchFormat.register_format(BzrBranchExperimental)
1693
1823
 
1694
1824
 
 
1825
class BzrBranch6(BzrBranch5):
 
1826
 
 
1827
    @needs_read_lock
 
1828
    def last_revision_info(self):
 
1829
        revision_string = self.control_files.get('last-revision').read()
 
1830
        revno, revision_id = revision_string.rstrip('\n').split(' ', 1)
 
1831
        revision_id = cache_utf8.get_cached_utf8(revision_id)
 
1832
        revno = int(revno)
 
1833
        return revno, revision_id
 
1834
 
 
1835
    def last_revision(self):
 
1836
        """Return last revision id, or None"""
 
1837
        revision_id = self.last_revision_info()[1]
 
1838
        if revision_id == _mod_revision.NULL_REVISION:
 
1839
            revision_id = None
 
1840
        return revision_id
 
1841
 
 
1842
    def _write_last_revision_info(self, revno, revision_id):
 
1843
        """Simply write out the revision id, with no checks.
 
1844
 
 
1845
        Use set_last_revision_info to perform this safely.
 
1846
 
 
1847
        Does not update the revision_history cache.
 
1848
        Intended to be called by set_last_revision_info and
 
1849
        _write_revision_history.
 
1850
        """
 
1851
        if revision_id is None:
 
1852
            revision_id = 'null:'
 
1853
        out_string = '%d %s\n' % (revno, revision_id)
 
1854
        self.control_files.put_bytes('last-revision', out_string)
 
1855
 
 
1856
    @needs_write_lock
 
1857
    def set_last_revision_info(self, revno, revision_id):
 
1858
        revision_id = osutils.safe_revision_id(revision_id)
 
1859
        if self._get_append_revisions_only():
 
1860
            self._check_history_violation(revision_id)
 
1861
        self._write_last_revision_info(revno, revision_id)
 
1862
        transaction = self.get_transaction()
 
1863
        cached_history = transaction.map.find_revision_history()
 
1864
        if cached_history is not None:
 
1865
            transaction.map.remove_object(cached_history)
 
1866
 
 
1867
    def _check_history_violation(self, revision_id):
 
1868
        last_revision = self.last_revision()
 
1869
        if last_revision is None:
 
1870
            return
 
1871
        if last_revision not in self._lefthand_history(revision_id):
 
1872
            raise errors.AppendRevisionsOnlyViolation(self.base)
 
1873
 
 
1874
    def _gen_revision_history(self):
 
1875
        """Generate the revision history from last revision
 
1876
        """
 
1877
        history = list(self.repository.iter_reverse_revision_history(
 
1878
            self.last_revision()))
 
1879
        history.reverse()
 
1880
        return history
 
1881
 
 
1882
    def _write_revision_history(self, history):
 
1883
        """Factored out of set_revision_history.
 
1884
 
 
1885
        This performs the actual writing to disk, with format-specific checks.
 
1886
        It is intended to be called by BzrBranch5.set_revision_history.
 
1887
        """
 
1888
        if len(history) == 0:
 
1889
            last_revision = 'null:'
 
1890
        else:
 
1891
            if history != self._lefthand_history(history[-1]):
 
1892
                raise errors.NotLefthandHistory(history)
 
1893
            last_revision = history[-1]
 
1894
        if self._get_append_revisions_only():
 
1895
            self._check_history_violation(last_revision)
 
1896
        self._write_last_revision_info(len(history), last_revision)
 
1897
 
 
1898
    @needs_write_lock
 
1899
    def append_revision(self, *revision_ids):
 
1900
        revision_ids = [osutils.safe_revision_id(r) for r in revision_ids]
 
1901
        if len(revision_ids) == 0:
 
1902
            return
 
1903
        prev_revno, prev_revision = self.last_revision_info()
 
1904
        for revision in self.repository.get_revisions(revision_ids):
 
1905
            if prev_revision == _mod_revision.NULL_REVISION:
 
1906
                if revision.parent_ids != []:
 
1907
                    raise errors.NotLeftParentDescendant(self, prev_revision,
 
1908
                                                         revision.revision_id)
 
1909
            else:
 
1910
                if revision.parent_ids[0] != prev_revision:
 
1911
                    raise errors.NotLeftParentDescendant(self, prev_revision,
 
1912
                                                         revision.revision_id)
 
1913
            prev_revision = revision.revision_id
 
1914
        self.set_last_revision_info(prev_revno + len(revision_ids),
 
1915
                                    revision_ids[-1])
 
1916
 
 
1917
    def _set_config_location(self, name, url, config=None,
 
1918
                             make_relative=False):
 
1919
        if config is None:
 
1920
            config = self.get_config()
 
1921
        if url is None:
 
1922
            url = ''
 
1923
        elif make_relative:
 
1924
            url = urlutils.relative_url(self.base, url)
 
1925
        config.set_user_option(name, url)
 
1926
 
 
1927
 
 
1928
    def _get_config_location(self, name, config=None):
 
1929
        if config is None:
 
1930
            config = self.get_config()
 
1931
        location = config.get_user_option(name)
 
1932
        if location == '':
 
1933
            location = None
 
1934
        return location
 
1935
 
 
1936
    @needs_write_lock
 
1937
    def _set_parent_location(self, url):
 
1938
        """Set the parent branch"""
 
1939
        self._set_config_location('parent_location', url, make_relative=True)
 
1940
 
 
1941
    @needs_read_lock
 
1942
    def _get_parent_location(self):
 
1943
        """Set the parent branch"""
 
1944
        return self._get_config_location('parent_location')
 
1945
 
 
1946
    def set_push_location(self, location):
 
1947
        """See Branch.set_push_location."""
 
1948
        self._set_config_location('push_location', location)
 
1949
 
 
1950
    def set_bound_location(self, location):
 
1951
        """See Branch.set_push_location."""
 
1952
        result = None
 
1953
        config = self.get_config()
 
1954
        if location is None:
 
1955
            if config.get_user_option('bound') != 'True':
 
1956
                return False
 
1957
            else:
 
1958
                config.set_user_option('bound', 'False')
 
1959
                return True
 
1960
        else:
 
1961
            self._set_config_location('bound_location', location,
 
1962
                                      config=config)
 
1963
            config.set_user_option('bound', 'True')
 
1964
        return True
 
1965
 
 
1966
    def _get_bound_location(self, bound):
 
1967
        """Return the bound location in the config file.
 
1968
 
 
1969
        Return None if the bound parameter does not match"""
 
1970
        config = self.get_config()
 
1971
        config_bound = (config.get_user_option('bound') == 'True')
 
1972
        if config_bound != bound:
 
1973
            return None
 
1974
        return self._get_config_location('bound_location', config=config)
 
1975
 
 
1976
    def get_bound_location(self):
 
1977
        """See Branch.set_push_location."""
 
1978
        return self._get_bound_location(True)
 
1979
 
 
1980
    def get_old_bound_location(self):
 
1981
        """See Branch.get_old_bound_location"""
 
1982
        return self._get_bound_location(False)
 
1983
 
 
1984
    def set_append_revisions_only(self, enabled):
 
1985
        if enabled:
 
1986
            value = 'True'
 
1987
        else:
 
1988
            value = 'False'
 
1989
        self.get_config().set_user_option('append_revisions_only', value)
 
1990
 
 
1991
    def _get_append_revisions_only(self):
 
1992
        value = self.get_config().get_user_option('append_revisions_only')
 
1993
        return value == 'True'
 
1994
 
 
1995
    def _synchronize_history(self, destination, revision_id):
 
1996
        """Synchronize last revision and revision history between branches.
 
1997
 
 
1998
        This version is most efficient when the destination is also a
 
1999
        BzrBranch6, but works for BzrBranch5, as long as the destination's
 
2000
        repository contains all the lefthand ancestors of the intended
 
2001
        last_revision.  If not, set_last_revision_info will fail.
 
2002
 
 
2003
        :param destination: The branch to copy the history into
 
2004
        :param revision_id: The revision-id to truncate history at.  May
 
2005
          be None to copy complete history.
 
2006
        """
 
2007
        if revision_id is None:
 
2008
            revno, revision_id = self.last_revision_info()
 
2009
        else:
 
2010
            revno = self.revision_id_to_revno(revision_id)
 
2011
        destination.set_last_revision_info(revno, revision_id)
 
2012
 
 
2013
 
1695
2014
class BranchTestProviderAdapter(object):
1696
2015
    """A tool to generate a suite testing multiple branch formats at once.
1697
2016
 
1754
2073
    """See bzrlib.workingtree.is_control_file."""
1755
2074
    from bzrlib import workingtree
1756
2075
    return workingtree.is_control_file(*args, **kwargs)
 
2076
 
 
2077
 
 
2078
class Converter5to6(object):
 
2079
    """Perform an in-place upgrade of format 5 to format 6"""
 
2080
 
 
2081
    def convert(self, branch):
 
2082
        # Data for 5 and 6 can peacefully coexist.
 
2083
        format = BzrBranchFormat6()
 
2084
        new_branch = format.open(branch.bzrdir, _found=True)
 
2085
 
 
2086
        # Copy source data into target
 
2087
        new_branch.set_last_revision_info(*branch.last_revision_info())
 
2088
        new_branch.set_parent(branch.get_parent())
 
2089
        new_branch.set_bound_location(branch.get_bound_location())
 
2090
        new_branch.set_push_location(branch.get_push_location())
 
2091
 
 
2092
        # Copying done; now update target format
 
2093
        new_branch.control_files.put_utf8('format',
 
2094
            format.get_format_string())
 
2095
 
 
2096
        # Clean up old files
 
2097
        new_branch.control_files._transport.delete('revision-history')
 
2098
        try:
 
2099
            branch.set_parent(None)
 
2100
        except NoSuchFile:
 
2101
            pass
 
2102
        branch.set_bound_location(None)