~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/remote.py

Merge with get_file_sha1

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
    repository,
29
29
    revision,
30
30
    symbol_versioning,
 
31
    urlutils,
31
32
)
32
33
from bzrlib.branch import BranchReferenceFormat
33
34
from bzrlib.bzrdir import BzrDir, RemoteBzrDirFormat
425
426
            'Repository.has_revision', path, revision_id)
426
427
        if response[0] not in ('yes', 'no'):
427
428
            raise errors.UnexpectedSmartServerResponse(response)
428
 
        return response[0] == 'yes'
 
429
        if response[0] == 'yes':
 
430
            return True
 
431
        for fallback_repo in self._fallback_repositories:
 
432
            if fallback_repo.has_revision(revision_id):
 
433
                return True
 
434
        return False
429
435
 
430
436
    def has_revisions(self, revision_ids):
431
437
        """See Repository.has_revisions()."""
 
438
        # FIXME: This does many roundtrips, particularly when there are
 
439
        # fallback repositories.  -- mbp 20080905
432
440
        result = set()
433
441
        for revision_id in revision_ids:
434
442
            if self.has_revision(revision_id):
593
601
        if isinstance(repository, RemoteRepository):
594
602
            raise AssertionError()
595
603
        self._real_repository = repository
 
604
        for fb in self._fallback_repositories:
 
605
            self._real_repository.add_fallback_repository(fb)
596
606
        if self._lock_mode == 'w':
597
607
            # if we are already locked, the real repository must be able to
598
608
            # acquire the lock with our token.
715
725
        
716
726
        :param repository: A repository.
717
727
        """
718
 
        if not self._format.supports_external_lookups:
719
 
            raise errors.UnstackableRepositoryFormat(self._format, self.base)
 
728
        # XXX: At the moment the RemoteRepository will allow fallbacks
 
729
        # unconditionally - however, a _real_repository will usually exist,
 
730
        # and may raise an error if it's not accommodated by the underlying
 
731
        # format.  Eventually we should check when opening the repository
 
732
        # whether it's willing to allow them or not.
 
733
        #
720
734
        # We need to accumulate additional repositories here, to pass them in
721
735
        # on various RPC's.
722
736
        self._fallback_repositories.append(repository)
 
737
        # They are also seen by the fallback repository.  If it doesn't exist
 
738
        # yet they'll be added then.  This implicitly copies them.
 
739
        self._ensure_real()
723
740
 
724
741
    def add_inventory(self, revid, inv, parents):
725
742
        self._ensure_real()
1279
1296
        self._repo_lock_token = None
1280
1297
        self._lock_count = 0
1281
1298
        self._leave_lock = False
 
1299
        self._setup_stacking()
 
1300
 
 
1301
    def _setup_stacking(self):
 
1302
        # configure stacking into the remote repository, by reading it from
 
1303
        # the vfs branch.
 
1304
        try:
 
1305
            fallback_url = self.get_stacked_on_url()
 
1306
        except (errors.NotStacked, errors.UnstackableBranchFormat,
 
1307
            errors.UnstackableRepositoryFormat), e:
 
1308
            return
 
1309
        # it's relative to this branch...
 
1310
        fallback_url = urlutils.join(self.base, fallback_url)
 
1311
        transports = [self.bzrdir.root_transport]
 
1312
        if self._real_branch is not None:
 
1313
            transports.append(self._real_branch._transport)
 
1314
        fallback_bzrdir = BzrDir.open(fallback_url, transports)
 
1315
        fallback_repo = fallback_bzrdir.open_repository()
 
1316
        self.repository.add_fallback_repository(fallback_repo)
1282
1317
 
1283
1318
    def _get_real_transport(self):
1284
1319
        # if we try vfs access, return the real branch's vfs transport
1366
1401
        :raises UnstackableRepositoryFormat: If the repository does not support
1367
1402
            stacking.
1368
1403
        """
1369
 
        self._ensure_real()
1370
 
        return self._real_branch.get_stacked_on_url()
 
1404
        try:
 
1405
            response = self._client.call('Branch.get_stacked_on_url',
 
1406
                self._remote_path())
 
1407
            if response[0] != 'ok':
 
1408
                raise errors.UnexpectedSmartServerResponse(response)
 
1409
            return response[1]
 
1410
        except errors.ErrorFromSmartServer, err:
 
1411
            # there may not be a repository yet, so we can't call through
 
1412
            # its _translate_error
 
1413
            _translate_error(err, branch=self)
 
1414
        except errors.UnknownSmartMethod, err:
 
1415
            self._ensure_real()
 
1416
            return self._real_branch.get_stacked_on_url()
1371
1417
 
1372
1418
    def lock_read(self):
1373
1419
        self.repository.lock_read()
1386
1432
            branch_token = token
1387
1433
            repo_token = self.repository.lock_write()
1388
1434
            self.repository.unlock()
1389
 
        path = self.bzrdir._path_for_remote_call(self._client)
1390
1435
        try:
1391
1436
            response = self._client.call(
1392
 
                'Branch.lock_write', path, branch_token, repo_token or '')
 
1437
                'Branch.lock_write', self._remote_path(),
 
1438
                branch_token, repo_token or '')
1393
1439
        except errors.ErrorFromSmartServer, err:
1394
1440
            self._translate_error(err, token=token)
1395
1441
        if response[0] != 'ok':
1431
1477
        return self._lock_token or None
1432
1478
 
1433
1479
    def _unlock(self, branch_token, repo_token):
1434
 
        path = self.bzrdir._path_for_remote_call(self._client)
1435
1480
        try:
1436
 
            response = self._client.call('Branch.unlock', path, branch_token,
 
1481
            response = self._client.call('Branch.unlock', self._remote_path(), branch_token,
1437
1482
                                         repo_token or '')
1438
1483
        except errors.ErrorFromSmartServer, err:
1439
1484
            self._translate_error(err, token=str((branch_token, repo_token)))
1487
1532
        self._leave_lock = False
1488
1533
 
1489
1534
    def _last_revision_info(self):
1490
 
        path = self.bzrdir._path_for_remote_call(self._client)
1491
 
        response = self._client.call('Branch.last_revision_info', path)
 
1535
        response = self._client.call('Branch.last_revision_info', self._remote_path())
1492
1536
        if response[0] != 'ok':
1493
1537
            raise SmartProtocolError('unexpected response code %s' % (response,))
1494
1538
        revno = int(response[1])
1497
1541
 
1498
1542
    def _gen_revision_history(self):
1499
1543
        """See Branch._gen_revision_history()."""
1500
 
        path = self.bzrdir._path_for_remote_call(self._client)
1501
1544
        response_tuple, response_handler = self._client.call_expecting_body(
1502
 
            'Branch.revision_history', path)
 
1545
            'Branch.revision_history', self._remote_path())
1503
1546
        if response_tuple[0] != 'ok':
1504
1547
            raise errors.UnexpectedSmartServerResponse(response_tuple)
1505
1548
        result = response_handler.read_body_bytes().split('\x00')
1507
1550
            return []
1508
1551
        return result
1509
1552
 
 
1553
    def _remote_path(self):
 
1554
        return self.bzrdir._path_for_remote_call(self._client)
 
1555
 
1510
1556
    def _set_last_revision_descendant(self, revision_id, other_branch,
1511
1557
            allow_diverged=False, allow_overwrite_descendant=False):
1512
 
        path = self.bzrdir._path_for_remote_call(self._client)
1513
1558
        try:
1514
1559
            response = self._client.call('Branch.set_last_revision_ex',
1515
 
                path, self._lock_token, self._repo_lock_token, revision_id,
 
1560
                self._remote_path(), self._lock_token, self._repo_lock_token, revision_id,
1516
1561
                int(allow_diverged), int(allow_overwrite_descendant))
1517
1562
        except errors.ErrorFromSmartServer, err:
1518
1563
            self._translate_error(err, other_branch=other_branch)
1526
1571
            self._real_branch._last_revision_info_cache = cache
1527
1572
 
1528
1573
    def _set_last_revision(self, revision_id):
1529
 
        path = self.bzrdir._path_for_remote_call(self._client)
1530
1574
        self._clear_cached_state()
1531
1575
        try:
1532
1576
            response = self._client.call('Branch.set_last_revision',
1533
 
                path, self._lock_token, self._repo_lock_token, revision_id)
 
1577
                self._remote_path(), self._lock_token, self._repo_lock_token, revision_id)
1534
1578
        except errors.ErrorFromSmartServer, err:
1535
1579
            self._translate_error(err)
1536
1580
        if response != ('ok',):
1605
1649
    @needs_write_lock
1606
1650
    def set_last_revision_info(self, revno, revision_id):
1607
1651
        revision_id = ensure_null(revision_id)
1608
 
        path = self.bzrdir._path_for_remote_call(self._client)
1609
1652
        try:
1610
1653
            response = self._client.call('Branch.set_last_revision_info',
1611
 
                path, self._lock_token, self._repo_lock_token, str(revno), revision_id)
 
1654
                self._remote_path(), self._lock_token, self._repo_lock_token, str(revno), revision_id)
1612
1655
        except errors.UnknownSmartMethod:
1613
1656
            self._ensure_real()
1614
1657
            self._clear_cached_state_of_remote_branch_only()
1740
1783
        raise errors.DivergedBranches(find('branch'), find('other_branch'))
1741
1784
    elif err.error_verb == 'TipChangeRejected':
1742
1785
        raise errors.TipChangeRejected(err.error_args[0].decode('utf8'))
 
1786
    elif err.error_verb == 'UnstackableBranchFormat':
 
1787
        raise errors.UnstackableBranchFormat(*err.error_args)
 
1788
    elif err.error_verb == 'UnstackableRepositoryFormat':
 
1789
        raise errors.UnstackableRepositoryFormat(*err.error_args)
 
1790
    elif err.error_verb == 'NotStacked':
 
1791
        raise errors.NotStacked(branch=find('branch'))
1743
1792
    raise errors.UnknownErrorFromSmartServer(err)
1744