~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/remote.py

  • Committer: Andrew Bennetts
  • Date: 2008-07-28 06:53:44 UTC
  • mfrom: (3581 +trunk)
  • mto: This revision was merged to the branch mainline in revision 3583.
  • Revision ID: andrew.bennetts@canonical.com-20080728065344-ocndjoycs903q6fz
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
88
88
            self._real_bzrdir = BzrDir.open_from_transport(
89
89
                self.root_transport, _server_formats=False)
90
90
 
 
91
    def cloning_metadir(self):
 
92
        self._ensure_real()
 
93
        return self._real_bzrdir.cloning_metadir()
 
94
 
 
95
    def _translate_error(self, err, **context):
 
96
        _translate_error(err, bzrdir=self, **context)
 
97
        
91
98
    def create_repository(self, shared=False):
92
99
        self._ensure_real()
93
100
        self._real_bzrdir.create_repository(shared=shared)
125
132
        try:
126
133
            response = self._client.call('BzrDir.open_branch', path)
127
134
        except errors.ErrorFromSmartServer, err:
128
 
            if err.error_tuple == ('nobranch',):
129
 
                raise errors.NotBranchError(path=self.root_transport.base)
130
 
            raise
 
135
            self._translate_error(err)
131
136
        if response[0] == 'ok':
132
137
            if response[1] == '':
133
138
                # branch at this location.
164
169
                verb = 'BzrDir.find_repository'
165
170
                response = self._client.call(verb, path)
166
171
        except errors.ErrorFromSmartServer, err:
167
 
            if err.error_verb == 'norepository':
168
 
                raise errors.NoRepositoryPresent(self)
169
 
            raise
 
172
            self._translate_error(err)
170
173
        if response[0] != 'ok':
171
174
            raise errors.UnexpectedSmartServerResponse(response)
172
175
        if verb == 'BzrDir.find_repository':
181
184
            format.supports_tree_reference = (response[3] == 'yes')
182
185
            # No wire format to check this yet.
183
186
            format.supports_external_lookups = (response[4] == 'yes')
 
187
            # Used to support creating a real format instance when needed.
 
188
            format._creating_bzrdir = self
184
189
            return RemoteRepository(self, format)
185
190
        else:
186
191
            raise errors.NoRepositoryPresent(self)
216
221
        """Upgrading of remote bzrdirs is not supported yet."""
217
222
        return False
218
223
 
219
 
    def clone(self, url, revision_id=None, force_new_repo=False):
 
224
    def clone(self, url, revision_id=None, force_new_repo=False,
 
225
              preserve_stacking=False):
220
226
        self._ensure_real()
221
227
        return self._real_bzrdir.clone(url, revision_id=revision_id,
222
 
            force_new_repo=force_new_repo)
 
228
            force_new_repo=force_new_repo, preserve_stacking=preserve_stacking)
 
229
 
 
230
    def get_config(self):
 
231
        self._ensure_real()
 
232
        return self._real_bzrdir.get_config()
223
233
 
224
234
 
225
235
class RemoteRepositoryFormat(repository.RepositoryFormat):
235
245
    the class level.
236
246
    """
237
247
 
238
 
    _matchingbzrdir = RemoteBzrDirFormat
 
248
    _matchingbzrdir = RemoteBzrDirFormat()
239
249
 
240
250
    def initialize(self, a_bzrdir, shared=False):
241
251
        if not isinstance(a_bzrdir, RemoteBzrDir):
242
 
            raise AssertionError('%r is not a RemoteBzrDir' % (a_bzrdir,))
 
252
            prior_repo = self._creating_bzrdir.open_repository()
 
253
            prior_repo._ensure_real()
 
254
            return prior_repo._real_repository._format.initialize(
 
255
                a_bzrdir, shared=shared)
243
256
        return a_bzrdir.create_repository(shared=shared)
244
257
    
245
258
    def open(self, a_bzrdir):
308
321
        self._reconcile_fixes_text_parents = False
309
322
        self._reconcile_backsup_inventory = False
310
323
        self.base = self.bzrdir.transport.base
 
324
        # Additional places to query for data.
 
325
        self._fallback_repositories = []
311
326
 
312
327
    def __str__(self):
313
328
        return "%s(%s)" % (self.__class__.__name__, self.base)
346
361
            #self._real_repository = self.bzrdir._real_bzrdir.open_repository()
347
362
            self._set_real_repository(self.bzrdir._real_bzrdir.open_repository())
348
363
 
 
364
    def _translate_error(self, err, **context):
 
365
        self.bzrdir._translate_error(err, repository=self, **context)
 
366
 
349
367
    def find_text_key_references(self):
350
368
        """Find the text key references within the repository.
351
369
 
388
406
            response = self._client.call_expecting_body(
389
407
                'Repository.get_revision_graph', path, revision_id)
390
408
        except errors.ErrorFromSmartServer, err:
391
 
            if err.error_verb == 'nosuchrevision':
392
 
                raise NoSuchRevision(self, revision_id)
393
 
            raise
 
409
            self._translate_error(err)
394
410
        response_tuple, response_handler = response
395
411
        if response_tuple[0] != 'ok':
396
412
            raise errors.UnexpectedSmartServerResponse(response_tuple)
525
541
        try:
526
542
            response = self._client.call('Repository.lock_write', path, token)
527
543
        except errors.ErrorFromSmartServer, err:
528
 
            if err.error_verb == 'LockContention':
529
 
                raise errors.LockContention('(remote lock)')
530
 
            elif err.error_verb == 'UnlockableTransport':
531
 
                raise errors.UnlockableTransport(self.bzrdir.root_transport)
532
 
            elif err.error_verb == 'LockFailed':
533
 
                raise errors.LockFailed(err.error_args[0], err.error_args[1])
534
 
            raise
 
544
            self._translate_error(err, token=token)
535
545
 
536
546
        if response[0] == 'ok':
537
547
            ok, token = response
608
618
        try:
609
619
            response = self._client.call('Repository.unlock', path, token)
610
620
        except errors.ErrorFromSmartServer, err:
611
 
            if err.error_verb == 'TokenMismatch':
612
 
                raise errors.TokenMismatch(token, '(remote token)')
613
 
            raise
 
621
            self._translate_error(err, token=token)
614
622
        if response == ('ok',):
615
623
            return
616
624
        else:
700
708
                committer=committer, revprops=revprops, revision_id=revision_id)
701
709
        return builder
702
710
 
 
711
    def add_fallback_repository(self, repository):
 
712
        """Add a repository to use for looking up data not held locally.
 
713
        
 
714
        :param repository: A repository.
 
715
        """
 
716
        if not self._format.supports_external_lookups:
 
717
            raise errors.UnstackableRepositoryFormat(self._format, self.base)
 
718
        # We need to accumulate additional repositories here, to pass them in
 
719
        # on various RPC's.
 
720
        self._fallback_repositories.append(repository)
 
721
 
703
722
    def add_inventory(self, revid, inv, parents):
704
723
        self._ensure_real()
705
724
        return self._real_repository.add_inventory(revid, inv, parents)
1265
1284
            if self._lock_mode == 'r':
1266
1285
                self._real_branch.lock_read()
1267
1286
 
 
1287
    def _translate_error(self, err, **context):
 
1288
        self.repository._translate_error(err, branch=self, **context)
 
1289
 
1268
1290
    def _clear_cached_state(self):
1269
1291
        super(RemoteBranch, self)._clear_cached_state()
1270
1292
        if self._real_branch is not None:
1301
1323
        self._ensure_real()
1302
1324
        return self._real_branch.get_physical_lock_status()
1303
1325
 
 
1326
    def get_stacked_on_url(self):
 
1327
        """Get the URL this branch is stacked against.
 
1328
 
 
1329
        :raises NotStacked: If the branch is not stacked.
 
1330
        :raises UnstackableBranchFormat: If the branch does not support
 
1331
            stacking.
 
1332
        :raises UnstackableRepositoryFormat: If the repository does not support
 
1333
            stacking.
 
1334
        """
 
1335
        self._ensure_real()
 
1336
        return self._real_branch.get_stacked_on_url()
 
1337
 
1304
1338
    def lock_read(self):
1305
1339
        if not self._lock_mode:
1306
1340
            self._lock_mode = 'r'
1322
1356
            response = self._client.call(
1323
1357
                'Branch.lock_write', path, branch_token, repo_token or '')
1324
1358
        except errors.ErrorFromSmartServer, err:
1325
 
            if err.error_verb == 'LockContention':
1326
 
                raise errors.LockContention('(remote lock)')
1327
 
            elif err.error_verb == 'TokenMismatch':
1328
 
                raise errors.TokenMismatch(token, '(remote token)')
1329
 
            elif err.error_verb == 'UnlockableTransport':
1330
 
                raise errors.UnlockableTransport(self.bzrdir.root_transport)
1331
 
            elif err.error_verb == 'ReadOnlyError':
1332
 
                raise errors.ReadOnlyError(self)
1333
 
            elif err.error_verb == 'LockFailed':
1334
 
                raise errors.LockFailed(err.error_args[0], err.error_args[1])
1335
 
            raise
 
1359
            self._translate_error(err, token=token)
1336
1360
        if response[0] != 'ok':
1337
1361
            raise errors.UnexpectedSmartServerResponse(response)
1338
1362
        ok, branch_token, repo_token = response
1383
1407
            response = self._client.call('Branch.unlock', path, branch_token,
1384
1408
                                         repo_token or '')
1385
1409
        except errors.ErrorFromSmartServer, err:
1386
 
            if err.error_verb == 'TokenMismatch':
1387
 
                raise errors.TokenMismatch(
1388
 
                    str((branch_token, repo_token)), '(remote tokens)')
1389
 
            raise
 
1410
            self._translate_error(err, token=str((branch_token, repo_token)))
1390
1411
        if response == ('ok',):
1391
1412
            return
1392
1413
        raise errors.UnexpectedSmartServerResponse(response)
1462
1483
                path, self._lock_token, self._repo_lock_token, revision_id,
1463
1484
                int(allow_diverged), int(allow_overwrite_descendant))
1464
1485
        except errors.ErrorFromSmartServer, err:
1465
 
            if err.error_verb == 'NoSuchRevision':
1466
 
                raise NoSuchRevision(self, revision_id)
1467
 
            elif err.error_verb == 'Diverged':
1468
 
                raise errors.DivergedBranches(self, other_branch)
1469
 
            raise
 
1486
            self._translate_error(err, other_branch=other_branch)
1470
1487
        self._clear_cached_state()
1471
1488
        if len(response) != 3 and response[0] != 'ok':
1472
1489
            raise errors.UnexpectedSmartServerResponse(response)
1481
1498
            response = self._client.call('Branch.set_last_revision',
1482
1499
                path, self._lock_token, self._repo_lock_token, revision_id)
1483
1500
        except errors.ErrorFromSmartServer, err:
1484
 
            if err.error_verb == 'NoSuchRevision':
1485
 
                raise NoSuchRevision(self, revision_id)
1486
 
            raise
 
1501
            self._translate_error(err)
1487
1502
        if response != ('ok',):
1488
1503
            raise errors.UnexpectedSmartServerResponse(response)
1489
1504
 
1507
1522
        self._ensure_real()
1508
1523
        return self._real_branch.set_parent(url)
1509
1524
        
 
1525
    def set_stacked_on_url(self, stacked_location):
 
1526
        """Set the URL this branch is stacked against.
 
1527
 
 
1528
        :raises UnstackableBranchFormat: If the branch does not support
 
1529
            stacking.
 
1530
        :raises UnstackableRepositoryFormat: If the repository does not support
 
1531
            stacking.
 
1532
        """
 
1533
        self._ensure_real()
 
1534
        return self._real_branch.set_stacked_on_url(stacked_location)
 
1535
 
1510
1536
    def sprout(self, to_bzrdir, revision_id=None):
1511
1537
        # Like Branch.sprout, except that it sprouts a branch in the default
1512
1538
        # format, because RemoteBranches can't be created at arbitrary URLs.
1551
1577
            self._last_revision_info_cache = revno, revision_id
1552
1578
            return
1553
1579
        except errors.ErrorFromSmartServer, err:
1554
 
            if err.error_verb == 'NoSuchRevision':
1555
 
                raise NoSuchRevision(self, err.error_args[0])
1556
 
            raise
 
1580
            self._translate_error(err)
1557
1581
        if response == ('ok',):
1558
1582
            self._clear_cached_state()
1559
1583
            self._last_revision_info_cache = revno, revision_id
1636
1660
    """
1637
1661
    for tarinfo in tar:
1638
1662
        tar.extract(tarinfo, to_dir)
 
1663
 
 
1664
 
 
1665
def _translate_error(err, **context):
 
1666
    """Translate an ErrorFromSmartServer into a more useful error.
 
1667
 
 
1668
    Possible context keys:
 
1669
      - branch
 
1670
      - repository
 
1671
      - bzrdir
 
1672
      - token
 
1673
      - other_branch
 
1674
    """
 
1675
    def find(name):
 
1676
        try:
 
1677
            return context[name]
 
1678
        except KeyError, keyErr:
 
1679
            mutter('Missing key %r in context %r', keyErr.args[0], context)
 
1680
            raise err
 
1681
    if err.error_verb == 'NoSuchRevision':
 
1682
        raise NoSuchRevision(find('branch'), err.error_args[0])
 
1683
    elif err.error_verb == 'nosuchrevision':
 
1684
        raise NoSuchRevision(find('repository'), err.error_args[0])
 
1685
    elif err.error_tuple == ('nobranch',):
 
1686
        raise errors.NotBranchError(path=find('bzrdir').root_transport.base)
 
1687
    elif err.error_verb == 'norepository':
 
1688
        raise errors.NoRepositoryPresent(find('bzrdir'))
 
1689
    elif err.error_verb == 'LockContention':
 
1690
        raise errors.LockContention('(remote lock)')
 
1691
    elif err.error_verb == 'UnlockableTransport':
 
1692
        raise errors.UnlockableTransport(find('bzrdir').root_transport)
 
1693
    elif err.error_verb == 'LockFailed':
 
1694
        raise errors.LockFailed(err.error_args[0], err.error_args[1])
 
1695
    elif err.error_verb == 'TokenMismatch':
 
1696
        raise errors.TokenMismatch(find('token'), '(remote token)')
 
1697
    elif err.error_verb == 'Diverged':
 
1698
        raise errors.DivergedBranches(find('branch'), find('other_branch'))
 
1699
    elif err.error_verb == 'TipChangeRejected':
 
1700
        raise errors.TipChangeRejected(err.error_args[0].decode('utf8'))
 
1701
    raise
 
1702