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

merge bzr.dev r4029

Show diffs side-by-side

added added

removed removed

Lines of Context:
1094
1094
        extent possible considering file system caching etc).
1095
1095
        """
1096
1096
 
 
1097
    def suspend_write_group(self):
 
1098
        raise errors.UnsuspendableWriteGroup(self)
 
1099
 
 
1100
    def resume_write_group(self, tokens):
 
1101
        if not self.is_write_locked():
 
1102
            raise errors.NotWriteLocked(self)
 
1103
        if self._write_group:
 
1104
            raise errors.BzrError('already in a write group')
 
1105
        self._resume_write_group(tokens)
 
1106
        # so we can detect unlock/relock - the write group is now entered.
 
1107
        self._write_group = self.get_transaction()
 
1108
    
 
1109
    def _resume_write_group(self, tokens):
 
1110
        raise errors.UnsuspendableWriteGroup(self)
 
1111
 
1097
1112
    def fetch(self, source, revision_id=None, pb=None, find_ghosts=False):
1098
1113
        """Fetch the content required to construct revision_id from source.
1099
1114
 
1220
1235
                dest_repo = a_bzrdir.open_repository()
1221
1236
        return dest_repo
1222
1237
 
 
1238
    def _get_sink(self):
 
1239
        """Return a sink for streaming into this repository."""
 
1240
        return StreamSink(self)
 
1241
 
1223
1242
    @needs_read_lock
1224
1243
    def has_revision(self, revision_id):
1225
1244
        """True if this repository has a copy of the revision."""
2191
2210
class RepositoryFormatRegistry(registry.Registry):
2192
2211
    """Registry of RepositoryFormats."""
2193
2212
 
 
2213
    def __init__(self, other_registry=None):
 
2214
        registry.Registry.__init__(self)
 
2215
        self._other_registry = other_registry
 
2216
 
 
2217
    def register_lazy(self, key, module_name, member_name,
 
2218
                      help=None, info=None,
 
2219
                      override_existing=False):
 
2220
        # Overridden to allow capturing registrations to two seperate
 
2221
        # registries in a single call.
 
2222
        registry.Registry.register_lazy(self, key, module_name, member_name,
 
2223
                help=help, info=info, override_existing=override_existing)
 
2224
        if self._other_registry is not None:
 
2225
            self._other_registry.register_lazy(key, module_name, member_name,
 
2226
                help=help, info=info, override_existing=override_existing)
 
2227
 
2194
2228
    def get(self, format_string):
2195
2229
        r = registry.Registry.get(self, format_string)
2196
2230
        if callable(r):
2198
2232
        return r
2199
2233
    
2200
2234
 
2201
 
format_registry = RepositoryFormatRegistry()
2202
 
"""Registry of formats, indexed by their identifying format string.
 
2235
network_format_registry = RepositoryFormatRegistry()
 
2236
"""Registry of formats indexed by their network name.
 
2237
 
 
2238
The network name for a repository format is an identifier that can be used when
 
2239
referring to formats with smart server operations. See
 
2240
RepositoryFormat.network_name() for more detail.
 
2241
"""
 
2242
 
 
2243
 
 
2244
format_registry = RepositoryFormatRegistry(network_format_registry)
 
2245
"""Registry of formats, indexed by their BzrDirMetaFormat format string.
2203
2246
 
2204
2247
This can contain either format instances themselves, or classes/factories that
2205
2248
can be called to obtain one.
2212
2255
class RepositoryFormat(object):
2213
2256
    """A repository format.
2214
2257
 
2215
 
    Formats provide three things:
 
2258
    Formats provide four things:
2216
2259
     * An initialization routine to construct repository data on disk.
2217
 
     * a format string which is used when the BzrDir supports versioned
2218
 
       children.
 
2260
     * a optional format string which is used when the BzrDir supports
 
2261
       versioned children.
2219
2262
     * an open routine which returns a Repository instance.
 
2263
     * A network name for referring to the format in smart server RPC
 
2264
       methods.
2220
2265
 
2221
2266
    There is one and only one Format subclass for each on-disk format. But
2222
2267
    there can be one Repository subclass that is used for several different
2223
2268
    formats. The _format attribute on a Repository instance can be used to
2224
2269
    determine the disk format.
2225
2270
 
2226
 
    Formats are placed in an dict by their format string for reference 
2227
 
    during opening. These should be subclasses of RepositoryFormat
2228
 
    for consistency.
 
2271
    Formats are placed in a registry by their format string for reference
 
2272
    during opening. These should be subclasses of RepositoryFormat for
 
2273
    consistency.
2229
2274
 
2230
2275
    Once a format is deprecated, just deprecate the initialize and open
2231
2276
    methods on the format class. Do not deprecate the object, as the 
2232
 
    object will be created every system load.
 
2277
    object may be created even when a repository instnace hasn't been
 
2278
    created.
2233
2279
 
2234
2280
    Common instance attributes:
2235
2281
    _matchingbzrdir - the bzrdir format that the repository format was
2342
2388
        """
2343
2389
        return True
2344
2390
 
 
2391
    def network_name(self):
 
2392
        """A simple byte string uniquely identifying this format for RPC calls.
 
2393
 
 
2394
        MetaDir repository formats use their disk format string to identify the
 
2395
        repository over the wire. All in one formats such as bzr < 0.8, and
 
2396
        foreign formats like svn/git and hg should use some marker which is
 
2397
        unique and immutable.
 
2398
        """
 
2399
        raise NotImplementedError(self.network_name)
 
2400
 
2345
2401
    def check_conversion_target(self, target_format):
2346
2402
        raise NotImplementedError(self.check_conversion_target)
2347
2403
 
2397
2453
        finally:
2398
2454
            control_files.unlock()
2399
2455
 
2400
 
 
2401
 
# formats which have no format string are not discoverable
2402
 
# and not independently creatable, so are not registered.  They're 
 
2456
    def network_name(self):
 
2457
        """Metadir formats have matching disk and network format strings."""
 
2458
        return self.get_format_string()
 
2459
 
 
2460
 
 
2461
# Pre-0.8 formats that don't have a disk format string (because they are
 
2462
# versioned by the matching control directory). We use the control directories
 
2463
# disk format string as a key for the network_name because they meet the
 
2464
# constraints (simple string, unique, immmutable).
 
2465
network_format_registry.register_lazy(
 
2466
    "Bazaar-NG branch, format 5\n",
 
2467
    'bzrlib.repofmt.weaverepo',
 
2468
    'RepositoryFormat5',
 
2469
)
 
2470
network_format_registry.register_lazy(
 
2471
    "Bazaar-NG branch, format 6\n",
 
2472
    'bzrlib.repofmt.weaverepo',
 
2473
    'RepositoryFormat6',
 
2474
)
 
2475
 
 
2476
# formats which have no format string are not discoverable or independently
 
2477
# creatable on disk, so are not registered in format_registry.  They're 
2403
2478
# all in bzrlib.repofmt.weaverepo now.  When an instance of one of these is
2404
2479
# needed, it's constructed directly by the BzrDir.  Non-native formats where
2405
2480
# the repository is not separately opened are similar.
3412
3487
    
3413
3488
    def _autopack(self):
3414
3489
        self.target.autopack()
 
3490
 
 
3491
    @needs_write_lock
 
3492
    def fetch(self, revision_id=None, pb=None, find_ghosts=False):
 
3493
        """See InterRepository.fetch()."""
 
3494
        # Always fetch using the generic streaming fetch code, to allow
 
3495
        # streaming fetching into remote servers.
 
3496
        from bzrlib.fetch import RepoFetcher
 
3497
        fetcher = RepoFetcher(self.target, self.source, revision_id,
 
3498
                              pb, find_ghosts)
 
3499
        self.target.autopack()
 
3500
        return fetcher.count_copied, fetcher.failed_revisions
3415
3501
        
3416
3502
    def _get_target_pack_collection(self):
3417
3503
        return self.target._real_repository._pack_collection
3587
3673
        revision_graph[key] = tuple(parent for parent in parents if parent
3588
3674
            in revision_graph)
3589
3675
    return revision_graph
 
3676
 
 
3677
 
 
3678
class StreamSink(object):
 
3679
    """An object that can insert a stream into a repository.
 
3680
 
 
3681
    This interface handles the complexity of reserialising inventories and
 
3682
    revisions from different formats, and allows unidirectional insertion into
 
3683
    stacked repositories without looking for the missing basis parents
 
3684
    beforehand.
 
3685
    """
 
3686
 
 
3687
    def __init__(self, target_repo):
 
3688
        self.target_repo = target_repo
 
3689
 
 
3690
    def insert_stream(self, stream, src_format):
 
3691
        """Insert a stream's content into the target repository.
 
3692
 
 
3693
        :param src_format: a bzr repository format.
 
3694
 
 
3695
        :return: an iterable of keys additional items required before the
 
3696
        insertion can be completed.
 
3697
        """
 
3698
        result = []
 
3699
        to_serializer = self.target_repo._format._serializer
 
3700
        src_serializer = src_format._serializer
 
3701
        for substream_type, substream in stream:
 
3702
            if substream_type == 'texts':
 
3703
                self.target_repo.texts.insert_record_stream(substream)
 
3704
            elif substream_type == 'inventories':
 
3705
                if src_serializer == to_serializer:
 
3706
                    self.target_repo.inventories.insert_record_stream(
 
3707
                        substream)
 
3708
                else:
 
3709
                    self._extract_and_insert_inventories(
 
3710
                        substream, src_serializer)
 
3711
            elif substream_type == 'revisions':
 
3712
                # This may fallback to extract-and-insert more often than
 
3713
                # required if the serializers are different only in terms of
 
3714
                # the inventory.
 
3715
                if src_serializer == to_serializer:
 
3716
                    self.target_repo.revisions.insert_record_stream(
 
3717
                        substream)
 
3718
                else:
 
3719
                    self._extract_and_insert_revisions(substream,
 
3720
                        src_serializer)
 
3721
            elif substream_type == 'signatures':
 
3722
                self.target_repo.signatures.insert_record_stream(substream)
 
3723
            else:
 
3724
                raise AssertionError('kaboom! %s' % (substream_type,))
 
3725
        return result
 
3726
 
 
3727
    def _extract_and_insert_inventories(self, substream, serializer):
 
3728
        """Generate a new inventory versionedfile in target, converting data.
 
3729
        
 
3730
        The inventory is retrieved from the source, (deserializing it), and
 
3731
        stored in the target (reserializing it in a different format).
 
3732
        """
 
3733
        for record in substream:
 
3734
            bytes = record.get_bytes_as('fulltext')
 
3735
            revision_id = record.key[0]
 
3736
            inv = serializer.read_inventory_from_string(bytes, revision_id)
 
3737
            parents = [key[0] for key in record.parents]
 
3738
            self.target_repo.add_inventory(revision_id, inv, parents)
 
3739
 
 
3740
    def _extract_and_insert_revisions(self, substream, serializer):
 
3741
        for record in substream:
 
3742
            bytes = record.get_bytes_as('fulltext')
 
3743
            revision_id = record.key[0]
 
3744
            rev = serializer.read_revision_from_string(bytes)
 
3745
            if rev.revision_id != revision_id:
 
3746
                raise AssertionError('wtf: %s != %s' % (rev, revision_id))
 
3747
            self.target_repo.add_revision(revision_id, rev)
 
3748
 
 
3749
    def finished(self):
 
3750
        if self.target_repo._fetch_reconcile:
 
3751
            self.target_repo.reconcile()
 
3752