/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

  • Committer: Jelmer Vernooij
  • Date: 2009-06-03 21:31:43 UTC
  • mfrom: (4403 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4405.
  • Revision ID: jelmer@samba.org-20090603213143-0196mgzgefgvd5no
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
969
969
        """
970
970
        if not self._format.supports_external_lookups:
971
971
            raise errors.UnstackableRepositoryFormat(self._format, self.base)
 
972
        if self.is_locked():
 
973
            # This repository will call fallback.unlock() when we transition to
 
974
            # the unlocked state, so we make sure to increment the lock count
 
975
            repository.lock_read()
972
976
        self._check_fallback_repository(repository)
973
977
        self._fallback_repositories.append(repository)
974
978
        self.texts.add_fallback_versioned_files(repository.texts)
1240
1244
        """
1241
1245
        locked = self.is_locked()
1242
1246
        result = self.control_files.lock_write(token=token)
1243
 
        for repo in self._fallback_repositories:
1244
 
            # Writes don't affect fallback repos
1245
 
            repo.lock_read()
1246
1247
        if not locked:
 
1248
            for repo in self._fallback_repositories:
 
1249
                # Writes don't affect fallback repos
 
1250
                repo.lock_read()
1247
1251
            self._refresh_data()
1248
1252
        return result
1249
1253
 
1250
1254
    def lock_read(self):
1251
1255
        locked = self.is_locked()
1252
1256
        self.control_files.lock_read()
1253
 
        for repo in self._fallback_repositories:
1254
 
            repo.lock_read()
1255
1257
        if not locked:
 
1258
            for repo in self._fallback_repositories:
 
1259
                repo.lock_read()
1256
1260
            self._refresh_data()
1257
1261
 
1258
1262
    def get_physical_lock_status(self):
1424
1428
    def suspend_write_group(self):
1425
1429
        raise errors.UnsuspendableWriteGroup(self)
1426
1430
 
1427
 
    def get_missing_parent_inventories(self):
 
1431
    def get_missing_parent_inventories(self, check_for_missing_texts=True):
1428
1432
        """Return the keys of missing inventory parents for revisions added in
1429
1433
        this write group.
1430
1434
 
1439
1443
            return set()
1440
1444
        if not self.is_in_write_group():
1441
1445
            raise AssertionError('not in a write group')
1442
 
                
 
1446
 
1443
1447
        # XXX: We assume that every added revision already has its
1444
1448
        # corresponding inventory, so we only check for parent inventories that
1445
1449
        # might be missing, rather than all inventories.
1448
1452
        unstacked_inventories = self.inventories._index
1449
1453
        present_inventories = unstacked_inventories.get_parent_map(
1450
1454
            key[-1:] for key in parents)
1451
 
        if len(parents.difference(present_inventories)) == 0:
 
1455
        parents.difference_update(present_inventories)
 
1456
        if len(parents) == 0:
1452
1457
            # No missing parent inventories.
1453
1458
            return set()
 
1459
        if not check_for_missing_texts:
 
1460
            return set(('inventories', rev_id) for (rev_id,) in parents)
1454
1461
        # Ok, now we have a list of missing inventories.  But these only matter
1455
1462
        # if the inventories that reference them are missing some texts they
1456
1463
        # appear to introduce.
1577
1584
        self.control_files.unlock()
1578
1585
        if self.control_files._lock_count == 0:
1579
1586
            self._inventory_entry_cache.clear()
1580
 
        for repo in self._fallback_repositories:
1581
 
            repo.unlock()
 
1587
            for repo in self._fallback_repositories:
 
1588
                repo.unlock()
1582
1589
 
1583
1590
    @needs_read_lock
1584
1591
    def clone(self, a_bzrdir, revision_id=None):
4001
4008
        try:
4002
4009
            if resume_tokens:
4003
4010
                self.target_repo.resume_write_group(resume_tokens)
 
4011
                is_resume = True
4004
4012
            else:
4005
4013
                self.target_repo.start_write_group()
 
4014
                is_resume = False
4006
4015
            try:
4007
4016
                # locked_insert_stream performs a commit|suspend.
4008
 
                return self._locked_insert_stream(stream, src_format)
 
4017
                return self._locked_insert_stream(stream, src_format, is_resume)
4009
4018
            except:
4010
4019
                self.target_repo.abort_write_group(suppress_errors=True)
4011
4020
                raise
4012
4021
        finally:
4013
4022
            self.target_repo.unlock()
4014
4023
 
4015
 
    def _locked_insert_stream(self, stream, src_format):
 
4024
    def _locked_insert_stream(self, stream, src_format, is_resume):
4016
4025
        to_serializer = self.target_repo._format._serializer
4017
4026
        src_serializer = src_format._serializer
4018
4027
        new_pack = None
4068
4077
        if new_pack is not None:
4069
4078
            new_pack._write_data('', flush=True)
4070
4079
        # Find all the new revisions (including ones from resume_tokens)
4071
 
        missing_keys = self.target_repo.get_missing_parent_inventories()
 
4080
        missing_keys = self.target_repo.get_missing_parent_inventories(
 
4081
            check_for_missing_texts=is_resume)
4072
4082
        try:
4073
4083
            for prefix, versioned_file in (
4074
4084
                ('texts', self.target_repo.texts),
4075
4085
                ('inventories', self.target_repo.inventories),
4076
4086
                ('revisions', self.target_repo.revisions),
4077
4087
                ('signatures', self.target_repo.signatures),
 
4088
                ('chk_bytes', self.target_repo.chk_bytes),
4078
4089
                ):
 
4090
                if versioned_file is None:
 
4091
                    continue
4079
4092
                missing_keys.update((prefix,) + key for key in
4080
4093
                    versioned_file.get_missing_compression_parent_keys())
4081
4094
        except NotImplementedError:
4228
4241
        keys['texts'] = set()
4229
4242
        keys['revisions'] = set()
4230
4243
        keys['inventories'] = set()
 
4244
        keys['chk_bytes'] = set()
4231
4245
        keys['signatures'] = set()
4232
4246
        for key in missing_keys:
4233
4247
            keys[key[0]].add(key[1:])
4240
4254
                    keys['revisions'],))
4241
4255
        for substream_kind, keys in keys.iteritems():
4242
4256
            vf = getattr(self.from_repository, substream_kind)
 
4257
            if vf is None and keys:
 
4258
                    raise AssertionError(
 
4259
                        "cannot fill in keys for a versioned file we don't"
 
4260
                        " have: %s needs %s" % (substream_kind, keys))
 
4261
            if not keys:
 
4262
                # No need to stream something we don't have
 
4263
                continue
4243
4264
            # Ask for full texts always so that we don't need more round trips
4244
4265
            # after this stream.
4245
 
            stream = vf.get_record_stream(keys,
4246
 
                self.to_format._fetch_order, True)
 
4266
            # Some of the missing keys are genuinely ghosts, so filter absent
 
4267
            # records. The Sink is responsible for doing another check to
 
4268
            # ensure that ghosts don't introduce missing data for future
 
4269
            # fetches.
 
4270
            stream = versionedfile.filter_absent(vf.get_record_stream(keys,
 
4271
                self.to_format._fetch_order, True))
4247
4272
            yield substream_kind, stream
4248
4273
 
4249
4274
    def inventory_fetch_order(self):