~ubuntu-branches/ubuntu/gutsy/bzr/gutsy

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

  • Committer: Bazaar Package Importer
  • Author(s): Etienne Goyer
  • Date: 2007-04-27 17:53:49 UTC
  • mfrom: (1.1.23 upstream)
  • Revision ID: james.westby@ubuntu.com-20070427175349-rvowqx994rfuikuu
Tags: 0.16~rc1-0ubuntu1
New upstream development release 

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
        revision as _mod_revision,
36
36
        transport,
37
37
        tree,
 
38
        tsort,
38
39
        ui,
39
40
        urlutils,
40
41
        )
54
55
                           NotBranchError, UninitializableFormat,
55
56
                           UnlistableStore, UnlistableBranch,
56
57
                           )
 
58
from bzrlib.hooks import Hooks
57
59
from bzrlib.symbol_versioning import (deprecated_function,
58
60
                                      deprecated_method,
59
61
                                      DEPRECATED_PARAMETER,
60
62
                                      deprecated_passed,
61
 
                                      zero_eight, zero_nine,
 
63
                                      zero_eight, zero_nine, zero_sixteen,
62
64
                                      )
63
65
from bzrlib.trace import mutter, note
64
66
 
98
100
 
99
101
    def __init__(self, *ignored, **ignored_too):
100
102
        self.tags = self._make_tags()
 
103
        self._revision_history_cache = None
 
104
        self._revision_id_to_revno_cache = None
101
105
 
102
106
    def break_lock(self):
103
107
        """Break a lock if one is present from another instance.
193
197
    def get_physical_lock_status(self):
194
198
        raise NotImplementedError(self.get_physical_lock_status)
195
199
 
 
200
    @needs_read_lock
 
201
    def get_revision_id_to_revno_map(self):
 
202
        """Return the revision_id => dotted revno map.
 
203
 
 
204
        This will be regenerated on demand, but will be cached.
 
205
 
 
206
        :return: A dictionary mapping revision_id => dotted revno.
 
207
            This dictionary should not be modified by the caller.
 
208
        """
 
209
        if self._revision_id_to_revno_cache is not None:
 
210
            mapping = self._revision_id_to_revno_cache
 
211
        else:
 
212
            mapping = self._gen_revno_map()
 
213
            self._cache_revision_id_to_revno(mapping)
 
214
        # TODO: jam 20070417 Since this is being cached, should we be returning
 
215
        #       a copy?
 
216
        # I would rather not, and instead just declare that users should not
 
217
        # modify the return value.
 
218
        return mapping
 
219
 
 
220
    def _gen_revno_map(self):
 
221
        """Create a new mapping from revision ids to dotted revnos.
 
222
 
 
223
        Dotted revnos are generated based on the current tip in the revision
 
224
        history.
 
225
        This is the worker function for get_revision_id_to_revno_map, which
 
226
        just caches the return value.
 
227
 
 
228
        :return: A dictionary mapping revision_id => dotted revno.
 
229
        """
 
230
        last_revision = self.last_revision()
 
231
        revision_graph = self.repository.get_revision_graph(last_revision)
 
232
        merge_sorted_revisions = tsort.merge_sort(
 
233
            revision_graph,
 
234
            last_revision,
 
235
            None,
 
236
            generate_revno=True)
 
237
        revision_id_to_revno = dict((rev_id, revno)
 
238
                                    for seq_num, rev_id, depth, revno, end_of_merge
 
239
                                     in merge_sorted_revisions)
 
240
        return revision_id_to_revno
 
241
 
 
242
    def leave_lock_in_place(self):
 
243
        """Tell this branch object not to release the physical lock when this
 
244
        object is unlocked.
 
245
        
 
246
        If lock_write doesn't return a token, then this method is not supported.
 
247
        """
 
248
        self.control_files.leave_in_place()
 
249
 
 
250
    def dont_leave_lock_in_place(self):
 
251
        """Tell this branch object to release the physical lock when this
 
252
        object is unlocked, even if it didn't originally acquire it.
 
253
 
 
254
        If lock_write doesn't return a token, then this method is not supported.
 
255
        """
 
256
        self.control_files.dont_leave_in_place()
 
257
 
196
258
    def abspath(self, name):
197
259
        """Return absolute filename for something in the branch
198
260
        
296
358
            raise InvalidRevisionNumber(revno)
297
359
        return self.repository.get_revision_delta(rh[revno-1])
298
360
 
 
361
    @deprecated_method(zero_sixteen)
299
362
    def get_root_id(self):
300
 
        """Return the id of this branches root"""
 
363
        """Return the id of this branches root
 
364
 
 
365
        Deprecated: branches don't have root ids-- trees do.
 
366
        Use basis_tree().get_root_id() instead.
 
367
        """
301
368
        raise NotImplementedError(self.get_root_id)
302
369
 
303
370
    def print_file(self, file, revision_id):
310
377
    def set_revision_history(self, rev_history):
311
378
        raise NotImplementedError(self.set_revision_history)
312
379
 
 
380
    def _cache_revision_history(self, rev_history):
 
381
        """Set the cached revision history to rev_history.
 
382
 
 
383
        The revision_history method will use this cache to avoid regenerating
 
384
        the revision history.
 
385
 
 
386
        This API is semi-public; it only for use by subclasses, all other code
 
387
        should consider it to be private.
 
388
        """
 
389
        self._revision_history_cache = rev_history
 
390
 
 
391
    def _cache_revision_id_to_revno(self, revision_id_to_revno):
 
392
        """Set the cached revision_id => revno map to revision_id_to_revno.
 
393
 
 
394
        This API is semi-public; it only for use by subclasses, all other code
 
395
        should consider it to be private.
 
396
        """
 
397
        self._revision_id_to_revno_cache = revision_id_to_revno
 
398
 
 
399
    def _clear_cached_state(self):
 
400
        """Clear any cached data on this branch, e.g. cached revision history.
 
401
 
 
402
        This means the next call to revision_history will need to call
 
403
        _gen_revision_history.
 
404
 
 
405
        This API is semi-public; it only for use by subclasses, all other code
 
406
        should consider it to be private.
 
407
        """
 
408
        self._revision_history_cache = None
 
409
        self._revision_id_to_revno_cache = None
 
410
 
 
411
    def _gen_revision_history(self):
 
412
        """Return sequence of revision hashes on to this branch.
 
413
        
 
414
        Unlike revision_history, this method always regenerates or rereads the
 
415
        revision history, i.e. it does not cache the result, so repeated calls
 
416
        may be expensive.
 
417
 
 
418
        Concrete subclasses should override this instead of revision_history so
 
419
        that subclasses do not need to deal with caching logic.
 
420
        
 
421
        This API is semi-public; it only for use by subclasses, all other code
 
422
        should consider it to be private.
 
423
        """
 
424
        raise NotImplementedError(self._gen_revision_history)
 
425
 
 
426
    @needs_read_lock
313
427
    def revision_history(self):
314
 
        """Return sequence of revision hashes on to this branch."""
315
 
        raise NotImplementedError(self.revision_history)
 
428
        """Return sequence of revision hashes on to this branch.
 
429
        
 
430
        This method will cache the revision history for as long as it is safe to
 
431
        do so.
 
432
        """
 
433
        if self._revision_history_cache is not None:
 
434
            history = self._revision_history_cache
 
435
        else:
 
436
            history = self._gen_revision_history()
 
437
            self._cache_revision_history(history)
 
438
        return list(history)
316
439
 
317
440
    def revno(self):
318
441
        """Return current revision number for this branch.
391
514
        try:
392
515
            return history.index(revision_id) + 1
393
516
        except ValueError:
394
 
            raise bzrlib.errors.NoSuchRevision(self, revision_id)
 
517
            raise errors.NoSuchRevision(self, revision_id)
395
518
 
396
519
    def get_rev_id(self, revno, history=None):
397
520
        """Find the revision id of the specified revno."""
400
523
        if history is None:
401
524
            history = self.revision_history()
402
525
        if revno <= 0 or revno > len(history):
403
 
            raise bzrlib.errors.NoSuchRevision(self, revno)
 
526
            raise errors.NoSuchRevision(self, revno)
404
527
        return history[revno - 1]
405
528
 
406
529
    def pull(self, source, overwrite=False, stop_revision=None):
509
632
 
510
633
    def get_push_location(self):
511
634
        """Return the None or the location to push this branch to."""
512
 
        raise NotImplementedError(self.get_push_location)
 
635
        push_loc = self.get_config().get_user_option('push_location')
 
636
        return push_loc
513
637
 
514
638
    def set_push_location(self, location):
515
639
        """Set a new push location for this branch."""
543
667
            raise InvalidRevisionNumber(revno)
544
668
 
545
669
    @needs_read_lock
546
 
    def clone(self, *args, **kwargs):
 
670
    def clone(self, to_bzrdir, revision_id=None):
547
671
        """Clone this branch into to_bzrdir preserving all semantic values.
548
672
        
549
673
        revision_id: if not None, the revision history in the new branch will
550
674
                     be truncated to end with revision_id.
551
675
        """
552
 
        # for API compatibility, until 0.8 releases we provide the old api:
553
 
        # def clone(self, to_location, revision=None, basis_branch=None, to_branch_format=None):
554
 
        # after 0.8 releases, the *args and **kwargs should be changed:
555
 
        # def clone(self, to_bzrdir, revision_id=None):
556
 
        if (kwargs.get('to_location', None) or
557
 
            kwargs.get('revision', None) or
558
 
            kwargs.get('basis_branch', None) or
559
 
            (len(args) and isinstance(args[0], basestring))):
560
 
            # backwards compatibility api:
561
 
            warn("Branch.clone() has been deprecated for BzrDir.clone() from"
562
 
                 " bzrlib 0.8.", DeprecationWarning, stacklevel=3)
563
 
            # get basis_branch
564
 
            if len(args) > 2:
565
 
                basis_branch = args[2]
566
 
            else:
567
 
                basis_branch = kwargs.get('basis_branch', None)
568
 
            if basis_branch:
569
 
                basis = basis_branch.bzrdir
570
 
            else:
571
 
                basis = None
572
 
            # get revision
573
 
            if len(args) > 1:
574
 
                revision_id = args[1]
575
 
            else:
576
 
                revision_id = kwargs.get('revision', None)
577
 
            # get location
578
 
            if len(args):
579
 
                url = args[0]
580
 
            else:
581
 
                # no default to raise if not provided.
582
 
                url = kwargs.get('to_location')
583
 
            return self.bzrdir.clone(url,
584
 
                                     revision_id=revision_id,
585
 
                                     basis=basis).open_branch()
586
 
        # new cleaner api.
587
 
        # generate args by hand 
588
 
        if len(args) > 1:
589
 
            revision_id = args[1]
590
 
        else:
591
 
            revision_id = kwargs.get('revision_id', None)
592
 
        if len(args):
593
 
            to_bzrdir = args[0]
594
 
        else:
595
 
            # no default to raise if not provided.
596
 
            to_bzrdir = kwargs.get('to_bzrdir')
597
676
        result = self._format.initialize(to_bzrdir)
598
677
        self.copy_content_into(result, revision_id=revision_id)
599
678
        return  result
682
761
 
683
762
    def _get_checkout_format(self):
684
763
        """Return the most suitable metadir for a checkout of this branch.
685
 
        Weaves are used if this branch's repostory uses weaves.
 
764
        Weaves are used if this branch's repository uses weaves.
686
765
        """
687
766
        if isinstance(self.bzrdir, bzrdir.BzrDirPreSplitOut):
688
767
            from bzrlib.repofmt import weaverepo
788
867
        """Return the current default format."""
789
868
        return klass._default_format
790
869
 
 
870
    def get_reference(self, a_bzrdir):
 
871
        """Get the target reference of the branch in a_bzrdir.
 
872
 
 
873
        format probing must have been completed before calling
 
874
        this method - it is assumed that the format of the branch
 
875
        in a_bzrdir is correct.
 
876
 
 
877
        :param a_bzrdir: The bzrdir to get the branch data from.
 
878
        :return: None if the branch is not a reference branch.
 
879
        """
 
880
        return None
 
881
 
791
882
    def get_format_string(self):
792
883
        """Return the ASCII format string that identifies this format."""
793
884
        raise NotImplementedError(self.get_format_string)
884
975
            control_files.unlock()
885
976
 
886
977
 
887
 
class BranchHooks(dict):
 
978
class BranchHooks(Hooks):
888
979
    """A dictionary mapping hook name to a list of callables for branch hooks.
889
980
    
890
981
    e.g. ['set_rh'] Is the list of items to be called when the
897
988
        These are all empty initially, because by default nothing should get
898
989
        notified.
899
990
        """
900
 
        dict.__init__(self)
 
991
        Hooks.__init__(self)
901
992
        # Introduced in 0.15:
902
993
        # invoked whenever the revision history has been set
903
994
        # with set_revision_history. The api signature is
936
1027
        # and an empty branch recieves new_revno of 0, new_revid of None.
937
1028
        self['post_uncommit'] = []
938
1029
 
939
 
    def install_hook(self, hook_name, a_callable):
940
 
        """Install a_callable in to the hook hook_name.
941
 
 
942
 
        :param hook_name: A hook name. See the __init__ method of BranchHooks
943
 
            for the complete list of hooks.
944
 
        :param a_callable: The callable to be invoked when the hook triggers.
945
 
            The exact signature will depend on the hook - see the __init__ 
946
 
            method of BranchHooks for details on each hook.
947
 
        """
948
 
        try:
949
 
            self[hook_name].append(a_callable)
950
 
        except KeyError:
951
 
            raise errors.UnknownHook('branch', hook_name)
952
 
 
953
1030
 
954
1031
# install the default hooks into the Branch class.
955
1032
Branch.hooks = BranchHooks()
1038
1115
        if not _found:
1039
1116
            format = BranchFormat.find_format(a_bzrdir)
1040
1117
            assert format.__class__ == self.__class__
1041
 
        transport = a_bzrdir.get_branch_transport(None)
1042
 
        control_files = lockable_files.LockableFiles(transport, 'lock',
1043
 
                                                     lockdir.LockDir)
1044
 
        return BzrBranch5(_format=self,
1045
 
                          _control_files=control_files,
1046
 
                          a_bzrdir=a_bzrdir,
1047
 
                          _repository=a_bzrdir.find_repository())
 
1118
        try:
 
1119
            transport = a_bzrdir.get_branch_transport(None)
 
1120
            control_files = lockable_files.LockableFiles(transport, 'lock',
 
1121
                                                         lockdir.LockDir)
 
1122
            return BzrBranch5(_format=self,
 
1123
                              _control_files=control_files,
 
1124
                              a_bzrdir=a_bzrdir,
 
1125
                              _repository=a_bzrdir.find_repository())
 
1126
        except NoSuchFile:
 
1127
            raise NotBranchError(path=transport.base)
1048
1128
 
1049
1129
 
1050
1130
class BzrBranchFormat6(BzrBranchFormat5):
1114
1194
        """See BranchFormat.get_format_description()."""
1115
1195
        return "Checkout reference format 1"
1116
1196
        
 
1197
    def get_reference(self, a_bzrdir):
 
1198
        """See BranchFormat.get_reference()."""
 
1199
        transport = a_bzrdir.get_branch_transport(None)
 
1200
        return transport.get('location').read()
 
1201
 
1117
1202
    def initialize(self, a_bzrdir, target_branch=None):
1118
1203
        """Create a branch of this format in a_bzrdir."""
1119
1204
        if target_branch is None:
1141
1226
            # emit some sort of warning/error to the caller ?!
1142
1227
        return clone
1143
1228
 
1144
 
    def open(self, a_bzrdir, _found=False):
 
1229
    def open(self, a_bzrdir, _found=False, location=None):
1145
1230
        """Return the branch that the branch reference in a_bzrdir points at.
1146
1231
 
1147
1232
        _found is a private parameter, do not use it. It is used to indicate
1150
1235
        if not _found:
1151
1236
            format = BranchFormat.find_format(a_bzrdir)
1152
1237
            assert format.__class__ == self.__class__
1153
 
        transport = a_bzrdir.get_branch_transport(None)
1154
 
        real_bzrdir = bzrdir.BzrDir.open(transport.get('location').read())
 
1238
        if location is None:
 
1239
            location = self.get_reference(a_bzrdir)
 
1240
        real_bzrdir = bzrdir.BzrDir.open(location)
1155
1241
        result = real_bzrdir.open_branch()
1156
1242
        # this changes the behaviour of result.clone to create a new reference
1157
1243
        # rather than a copy of the content of the branch.
1183
1269
    it's writable, and can be accessed via the normal filesystem API.
1184
1270
    """
1185
1271
    
1186
 
    def __init__(self, transport=DEPRECATED_PARAMETER, init=DEPRECATED_PARAMETER,
1187
 
                 relax_version_check=DEPRECATED_PARAMETER, _format=None,
 
1272
    def __init__(self, _format=None,
1188
1273
                 _control_files=None, a_bzrdir=None, _repository=None):
1189
 
        """Create new branch object at a particular location.
1190
 
 
1191
 
        transport -- A Transport object, defining how to access files.
1192
 
        
1193
 
        init -- If True, create new control files in a previously
1194
 
             unversioned directory.  If False, the branch must already
1195
 
             be versioned.
1196
 
 
1197
 
        relax_version_check -- If true, the usual check for the branch
1198
 
            version is not applied.  This is intended only for
1199
 
            upgrade/recovery type use; it's not guaranteed that
1200
 
            all operations will work on old format branches.
1201
 
        """
 
1274
        """Create new branch object at a particular location."""
1202
1275
        Branch.__init__(self)
1203
1276
        if a_bzrdir is None:
1204
 
            self.bzrdir = bzrdir.BzrDir.open(transport.base)
 
1277
            raise ValueError('a_bzrdir must be supplied')
1205
1278
        else:
1206
1279
            self.bzrdir = a_bzrdir
1207
1280
        # self._transport used to point to the directory containing the
1213
1286
            raise ValueError('BzrBranch _control_files is None')
1214
1287
        self.control_files = _control_files
1215
1288
        self._transport = _control_files._transport
1216
 
        if deprecated_passed(init):
1217
 
            warn("BzrBranch.__init__(..., init=XXX): The init parameter is "
1218
 
                 "deprecated as of bzr 0.8. Please use Branch.create().",
1219
 
                 DeprecationWarning,
1220
 
                 stacklevel=2)
1221
 
            if init:
1222
 
                # this is slower than before deprecation, oh well never mind.
1223
 
                # -> its deprecated.
1224
 
                self._initialize(transport.base)
1225
 
        self._check_format(_format)
1226
 
        if deprecated_passed(relax_version_check):
1227
 
            warn("BzrBranch.__init__(..., relax_version_check=XXX_: The "
1228
 
                 "relax_version_check parameter is deprecated as of bzr 0.8. "
1229
 
                 "Please use BzrDir.open_downlevel, or a BzrBranchFormat's "
1230
 
                 "open() method.",
1231
 
                 DeprecationWarning,
1232
 
                 stacklevel=2)
1233
 
            if (not relax_version_check
1234
 
                and not self._format.is_supported()):
1235
 
                raise errors.UnsupportedFormatError(format=fmt)
1236
 
        if deprecated_passed(transport):
1237
 
            warn("BzrBranch.__init__(transport=XXX...): The transport "
1238
 
                 "parameter is deprecated as of bzr 0.8. "
1239
 
                 "Please use Branch.open, or bzrdir.open_branch().",
1240
 
                 DeprecationWarning,
1241
 
                 stacklevel=2)
1242
1289
        self.repository = _repository
1243
1290
 
1244
1291
    def __str__(self):
1252
1299
 
1253
1300
    base = property(_get_base, doc="The URL for the root of this branch.")
1254
1301
 
1255
 
    def _finish_transaction(self):
1256
 
        """Exit the current transaction."""
1257
 
        return self.control_files._finish_transaction()
1258
 
 
1259
 
    def get_transaction(self):
1260
 
        """Return the current active transaction.
1261
 
 
1262
 
        If no transaction is active, this returns a passthrough object
1263
 
        for which all data is immediately flushed and no caching happens.
1264
 
        """
1265
 
        # this is an explicit function so that we can do tricky stuff
1266
 
        # when the storage in rev_storage is elsewhere.
1267
 
        # we probably need to hook the two 'lock a location' and 
1268
 
        # 'have a transaction' together more delicately, so that
1269
 
        # we can have two locks (branch and storage) and one transaction
1270
 
        # ... and finishing the transaction unlocks both, but unlocking
1271
 
        # does not. - RBC 20051121
1272
 
        return self.control_files.get_transaction()
1273
 
 
1274
 
    def _set_transaction(self, transaction):
1275
 
        """Set a new active transaction."""
1276
 
        return self.control_files._set_transaction(transaction)
1277
 
 
1278
1302
    def abspath(self, name):
1279
1303
        """See Branch.abspath."""
1280
1304
        return self.control_files._transport.abspath(name)
1281
1305
 
1282
 
    def _check_format(self, format):
1283
 
        """Identify the branch format if needed.
1284
 
 
1285
 
        The format is stored as a reference to the format object in
1286
 
        self._format for code that needs to check it later.
1287
 
 
1288
 
        The format parameter is either None or the branch format class
1289
 
        used to open this branch.
1290
 
 
1291
 
        FIXME: DELETE THIS METHOD when pre 0.8 support is removed.
1292
 
        """
1293
 
        if format is None:
1294
 
            format = BranchFormat.find_format(self.bzrdir)
1295
 
        self._format = format
1296
 
        mutter("got branch format %s", self._format)
1297
 
 
 
1306
 
 
1307
    @deprecated_method(zero_sixteen)
1298
1308
    @needs_read_lock
1299
1309
    def get_root_id(self):
1300
1310
        """See Branch.get_root_id."""
1304
1314
    def is_locked(self):
1305
1315
        return self.control_files.is_locked()
1306
1316
 
1307
 
    def lock_write(self):
1308
 
        self.repository.lock_write()
 
1317
    def lock_write(self, token=None):
 
1318
        repo_token = self.repository.lock_write()
1309
1319
        try:
1310
 
            self.control_files.lock_write()
 
1320
            token = self.control_files.lock_write(token=token)
1311
1321
        except:
1312
1322
            self.repository.unlock()
1313
1323
            raise
 
1324
        return token
1314
1325
 
1315
1326
    def lock_read(self):
1316
1327
        self.repository.lock_read()
1326
1337
            self.control_files.unlock()
1327
1338
        finally:
1328
1339
            self.repository.unlock()
 
1340
        if not self.control_files.is_locked():
 
1341
            # we just released the lock
 
1342
            self._clear_cached_state()
1329
1343
        
1330
1344
    def peek_lock_mode(self):
1331
1345
        if self.control_files._lock_count == 0:
1364
1378
    def set_revision_history(self, rev_history):
1365
1379
        """See Branch.set_revision_history."""
1366
1380
        rev_history = [osutils.safe_revision_id(r) for r in rev_history]
 
1381
        self._clear_cached_state()
1367
1382
        self._write_revision_history(rev_history)
1368
 
        transaction = self.get_transaction()
1369
 
        history = transaction.map.find_revision_history()
1370
 
        if history is not None:
1371
 
            # update the revision history in the identity map.
1372
 
            history[:] = list(rev_history)
1373
 
            # this call is disabled because revision_history is 
1374
 
            # not really an object yet, and the transaction is for objects.
1375
 
            # transaction.register_dirty(history)
1376
 
        else:
1377
 
            transaction.map.add_revision_history(rev_history)
1378
 
            # this call is disabled because revision_history is 
1379
 
            # not really an object yet, and the transaction is for objects.
1380
 
            # transaction.register_clean(history)
 
1383
        self._cache_revision_history(rev_history)
1381
1384
        for hook in Branch.hooks['set_rh']:
1382
1385
            hook(self, rev_history)
1383
1386
 
1395
1398
            history.pop()
1396
1399
        return history
1397
1400
 
1398
 
    @needs_read_lock
1399
 
    def revision_history(self):
1400
 
        """See Branch.revision_history."""
1401
 
        transaction = self.get_transaction()
1402
 
        history = transaction.map.find_revision_history()
1403
 
        if history is not None:
1404
 
            # mutter("cache hit for revision-history in %s", self)
1405
 
            return list(history)
1406
 
        history = self._gen_revision_history()
1407
 
        transaction.map.add_revision_history(history)
1408
 
        # this call is disabled because revision_history is 
1409
 
        # not really an object yet, and the transaction is for objects.
1410
 
        # transaction.register_clean(history, precious=True)
1411
 
        return list(history)
1412
 
 
1413
1401
    def _lefthand_history(self, revision_id, last_rev=None,
1414
1402
                          other_branch=None):
1415
1403
        # stop_revision must be a descendant of last_revision
1589
1577
        except errors.InvalidURLJoin, e:
1590
1578
            raise errors.InaccessibleParent(parent, self.base)
1591
1579
 
1592
 
    def get_push_location(self):
1593
 
        """See Branch.get_push_location."""
1594
 
        push_loc = self.get_config().get_user_option('push_location')
1595
 
        return push_loc
1596
 
 
1597
1580
    def set_push_location(self, location):
1598
1581
        """See Branch.set_push_location."""
1599
1582
        self.get_config().set_user_option(
1613
1596
                try: 
1614
1597
                    url = url.encode('ascii')
1615
1598
                except UnicodeEncodeError:
1616
 
                    raise bzrlib.errors.InvalidURL(url,
 
1599
                    raise errors.InvalidURL(url,
1617
1600
                        "Urls must be 7-bit ascii, "
1618
1601
                        "use bzrlib.urlutils.escape")
1619
1602
            url = urlutils.relative_url(self.base, url)
1833
1816
        return "Experimental branch format"
1834
1817
 
1835
1818
    @classmethod
 
1819
    def get_reference(cls, a_bzrdir):
 
1820
        """Get the target reference of the branch in a_bzrdir.
 
1821
 
 
1822
        format probing must have been completed before calling
 
1823
        this method - it is assumed that the format of the branch
 
1824
        in a_bzrdir is correct.
 
1825
 
 
1826
        :param a_bzrdir: The bzrdir to get the branch data from.
 
1827
        :return: None if the branch is not a reference branch.
 
1828
        """
 
1829
        return None
 
1830
 
 
1831
    @classmethod
1836
1832
    def _initialize_control_files(cls, a_bzrdir, utf8_files, lock_filename,
1837
1833
            lock_class):
1838
1834
        branch_transport = a_bzrdir.get_branch_transport(cls)
1928
1924
        if self._get_append_revisions_only():
1929
1925
            self._check_history_violation(revision_id)
1930
1926
        self._write_last_revision_info(revno, revision_id)
1931
 
        transaction = self.get_transaction()
1932
 
        cached_history = transaction.map.find_revision_history()
1933
 
        if cached_history is not None:
1934
 
            transaction.map.remove_object(cached_history)
 
1927
        self._clear_cached_state()
1935
1928
 
1936
1929
    def _check_history_violation(self, revision_id):
1937
1930
        last_revision = self.last_revision()
2073
2066
    easy to identify.
2074
2067
    """
2075
2068
 
2076
 
    def __init__(self, transport_server, transport_readonly_server, formats):
 
2069
    def __init__(self, transport_server, transport_readonly_server, formats,
 
2070
        vfs_transport_factory=None):
2077
2071
        self._transport_server = transport_server
2078
2072
        self._transport_readonly_server = transport_readonly_server
2079
2073
        self._formats = formats