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

  • Committer: Martin Pool
  • Date: 2009-03-23 07:25:27 UTC
  • mfrom: (4183 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4189.
  • Revision ID: mbp@sourcefrog.net-20090323072527-317my4n8zej1g6v9
merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
428
428
        if self._supports_external_lookups is None:
429
429
            self._ensure_real()
430
430
            self._supports_external_lookups = \
431
 
                self._custom_format.supports_external_lookups 
 
431
                self._custom_format.supports_external_lookups
432
432
        return self._supports_external_lookups
433
433
 
434
434
    @property
1236
1236
        stop_keys = result_parents.difference(start_set)
1237
1237
        included_keys = start_set.intersection(result_parents)
1238
1238
        start_set.difference_update(included_keys)
1239
 
        recipe = (start_set, stop_keys, len(parents_map))
 
1239
        recipe = ('manual', start_set, stop_keys, len(parents_map))
1240
1240
        body = self._serialise_search_recipe(recipe)
1241
1241
        path = self.bzrdir._path_for_remote_call(self._client)
1242
1242
        for key in keys:
1305
1305
        return self._real_repository.all_revision_ids()
1306
1306
 
1307
1307
    @needs_read_lock
1308
 
    def get_deltas_for_revisions(self, revisions):
 
1308
    def get_deltas_for_revisions(self, revisions, specific_fileids=None):
1309
1309
        self._ensure_real()
1310
 
        return self._real_repository.get_deltas_for_revisions(revisions)
 
1310
        return self._real_repository.get_deltas_for_revisions(revisions,
 
1311
            specific_fileids=specific_fileids)
1311
1312
 
1312
1313
    @needs_read_lock
1313
 
    def get_revision_delta(self, revision_id):
 
1314
    def get_revision_delta(self, revision_id, specific_fileids=None):
1314
1315
        self._ensure_real()
1315
 
        return self._real_repository.get_revision_delta(revision_id)
 
1316
        return self._real_repository.get_revision_delta(revision_id,
 
1317
            specific_fileids=specific_fileids)
1316
1318
 
1317
1319
    @needs_read_lock
1318
1320
    def revision_trees(self, revision_ids):
1495
1497
        :param recipe: A search recipe (start, stop, count).
1496
1498
        :return: Serialised bytes.
1497
1499
        """
1498
 
        start_keys = ' '.join(recipe[0])
1499
 
        stop_keys = ' '.join(recipe[1])
1500
 
        count = str(recipe[2])
 
1500
        start_keys = ' '.join(recipe[1])
 
1501
        stop_keys = ' '.join(recipe[2])
 
1502
        count = str(recipe[3])
1501
1503
        return '\n'.join((start_keys, stop_keys, count))
1502
1504
 
1503
1505
    def _serialise_search_result(self, search_result):
1506
1508
            parts.extend(search_result.heads)
1507
1509
        else:
1508
1510
            recipe = search_result.get_recipe()
1509
 
            parts = ['search', self._serialise_search_recipe(recipe)]
 
1511
            parts = [recipe[0], self._serialise_search_recipe(recipe)]
1510
1512
        return '\n'.join(parts)
1511
1513
 
1512
1514
    def autopack(self):
1584
1586
    """Stream data from a remote server."""
1585
1587
 
1586
1588
    def get_stream(self, search):
1587
 
        # streaming with fallback repositories is not well defined yet: The
1588
 
        # remote repository cannot see the fallback repositories, and thus
1589
 
        # cannot satisfy the entire search in the general case. Likewise the
1590
 
        # fallback repositories cannot reify the search to determine what they
1591
 
        # should send. It likely needs a return value in the stream listing the
1592
 
        # edge of the search to resume from in fallback repositories.
1593
 
        if self.from_repository._fallback_repositories:
1594
 
            return repository.StreamSource.get_stream(self, search)
1595
 
        repo = self.from_repository
 
1589
        if (self.from_repository._fallback_repositories and
 
1590
            self.to_format._fetch_order == 'topological'):
 
1591
            return self._real_stream(self.from_repository, search)
 
1592
        return self.missing_parents_chain(search, [self.from_repository] +
 
1593
            self.from_repository._fallback_repositories)
 
1594
 
 
1595
    def _real_stream(self, repo, search):
 
1596
        """Get a stream for search from repo.
 
1597
        
 
1598
        This never called RemoteStreamSource.get_stream, and is a heler
 
1599
        for RemoteStreamSource._get_stream to allow getting a stream 
 
1600
        reliably whether fallback back because of old servers or trying
 
1601
        to stream from a non-RemoteRepository (which the stacked support
 
1602
        code will do).
 
1603
        """
 
1604
        source = repo._get_source(self.to_format)
 
1605
        if isinstance(source, RemoteStreamSource):
 
1606
            return repository.StreamSource.get_stream(source, search)
 
1607
        return source.get_stream(search)
 
1608
 
 
1609
    def _get_stream(self, repo, search):
 
1610
        """Core worker to get a stream from repo for search.
 
1611
 
 
1612
        This is used by both get_stream and the stacking support logic. It
 
1613
        deliberately gets a stream for repo which does not need to be
 
1614
        self.from_repository. In the event that repo is not Remote, or
 
1615
        cannot do a smart stream, a fallback is made to the generic
 
1616
        repository._get_stream() interface, via self._real_stream.
 
1617
 
 
1618
        In the event of stacking, streams from _get_stream will not
 
1619
        contain all the data for search - this is normal (see get_stream).
 
1620
 
 
1621
        :param repo: A repository.
 
1622
        :param search: A search.
 
1623
        """
 
1624
        # Fallbacks may be non-smart
 
1625
        if not isinstance(repo, RemoteRepository):
 
1626
            return self._real_stream(repo, search)
1596
1627
        client = repo._client
1597
1628
        medium = client._medium
1598
1629
        if medium._is_remote_before((1, 13)):
1599
 
            # No possible way this can work.
1600
 
            return repository.StreamSource.get_stream(self, search)
 
1630
            # streaming was added in 1.13
 
1631
            return self._real_stream(repo, search)
1601
1632
        path = repo.bzrdir._path_for_remote_call(client)
1602
1633
        try:
1603
1634
            search_bytes = repo._serialise_search_result(search)
1607
1638
            response_tuple, response_handler = response
1608
1639
        except errors.UnknownSmartMethod:
1609
1640
            medium._remember_remote_is_before((1,13))
1610
 
            return repository.StreamSource.get_stream(self, search)
 
1641
            return self._real_stream(repo, search)
1611
1642
        if response_tuple[0] != 'ok':
1612
1643
            raise errors.UnexpectedSmartServerResponse(response_tuple)
1613
1644
        byte_stream = response_handler.read_streamed_body()
1618
1649
                src_format.network_name(), repo._format.network_name()))
1619
1650
        return stream
1620
1651
 
 
1652
    def missing_parents_chain(self, search, sources):
 
1653
        """Chain multiple streams together to handle stacking.
 
1654
 
 
1655
        :param search: The overall search to satisfy with streams.
 
1656
        :param sources: A list of Repository objects to query.
 
1657
        """
 
1658
        self.serialiser = self.to_format._serializer
 
1659
        self.seen_revs = set()
 
1660
        self.referenced_revs = set()
 
1661
        # If there are heads in the search, or the key count is > 0, we are not
 
1662
        # done.
 
1663
        while not search.is_empty() and len(sources) > 1:
 
1664
            source = sources.pop(0)
 
1665
            stream = self._get_stream(source, search)
 
1666
            for kind, substream in stream:
 
1667
                if kind != 'revisions':
 
1668
                    yield kind, substream
 
1669
                else:
 
1670
                    yield kind, self.missing_parents_rev_handler(substream)
 
1671
            search = search.refine(self.seen_revs, self.referenced_revs)
 
1672
            self.seen_revs = set()
 
1673
            self.referenced_revs = set()
 
1674
        if not search.is_empty():
 
1675
            for kind, stream in self._get_stream(sources[0], search):
 
1676
                yield kind, stream
 
1677
 
 
1678
    def missing_parents_rev_handler(self, substream):
 
1679
        for content in substream:
 
1680
            revision_bytes = content.get_bytes_as('fulltext')
 
1681
            revision = self.serialiser.read_revision_from_string(revision_bytes)
 
1682
            self.seen_revs.add(content.key[-1])
 
1683
            self.referenced_revs.update(revision.parent_ids)
 
1684
            yield content
 
1685
 
1621
1686
 
1622
1687
class RemoteBranchLockableFiles(LockableFiles):
1623
1688
    """A 'LockableFiles' implementation that talks to a smart server.