~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/remote.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-02-24 09:53:04 UTC
  • mfrom: (4032.3.6 integration)
  • Revision ID: pqm@pqm.ubuntu.com-20090224095304-uk12twrtk4u1mkd1
(robertc) Use a HPSS verb to create Branch objects on bzr:// servers.
        (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
70
70
        except errors.ErrorFromSmartServer, err:
71
71
            self._translate_error(err, **err_context)
72
72
 
 
73
 
 
74
def response_tuple_to_repo_format(response):
 
75
    """Convert a response tuple describing a repository format to a format."""
 
76
    format = RemoteRepositoryFormat()
 
77
    format.rich_root_data = (response[0] == 'yes')
 
78
    format.supports_tree_reference = (response[1] == 'yes')
 
79
    format.supports_external_lookups = (response[2] == 'yes')
 
80
    format._network_name = response[3]
 
81
    return format
 
82
 
 
83
 
73
84
# Note: RemoteBzrDirFormat is in bzrdir.py
74
85
 
75
86
class RemoteBzrDir(BzrDir, _RpcHelper):
343
354
            return self._vfs_initialize(a_bzrdir, shared)
344
355
        else:
345
356
            # Turn the response into a RemoteRepository object.
346
 
            format = RemoteRepositoryFormat()
347
 
            format.rich_root_data = (response[1] == 'yes')
348
 
            format.supports_tree_reference = (response[2] == 'yes')
349
 
            format.supports_external_lookups = (response[3] == 'yes')
350
 
            format._network_name = response[4]
 
357
            format = response_tuple_to_repo_format(response[1:])
351
358
            # Used to support creating a real format instance when needed.
352
359
            format._creating_bzrdir = a_bzrdir
353
360
            remote_repo = RemoteRepository(a_bzrdir, format)
382
389
 
383
390
    @property
384
391
    def _serializer(self):
385
 
        # We should only be getting asked for the serializer for
386
 
        # RemoteRepositoryFormat objects when the RemoteRepositoryFormat object
387
 
        # is a concrete instance for a RemoteRepository. In this case we know
388
 
        # the creating_repo and can use it to supply the serializer.
389
 
        self._creating_repo._ensure_real()
390
 
        return self._creating_repo._real_repository._format._serializer
 
392
        if self._custom_format is not None:
 
393
            return self._custom_format._serializer
 
394
        elif self._network_name is not None:
 
395
            self._custom_format = repository.network_format_registry.get(
 
396
                self._network_name)
 
397
            return self._custom_format._serializer
 
398
        else:
 
399
            # We should only be getting asked for the serializer for
 
400
            # RemoteRepositoryFormat objects when the RemoteRepositoryFormat object
 
401
            # is a concrete instance for a RemoteRepository. In this case we know
 
402
            # the creating_repo and can use it to supply the serializer.
 
403
            self._creating_repo._ensure_real()
 
404
            return self._creating_repo._real_repository._format._serializer
391
405
 
392
406
 
393
407
class RemoteRepository(_RpcHelper):
754
768
            raise errors.UnexpectedSmartServerResponse(response)
755
769
 
756
770
    def unlock(self):
 
771
        if not self._lock_count:
 
772
            raise errors.LockNotHeld(self)
757
773
        self._lock_count -= 1
758
774
        if self._lock_count > 0:
759
775
            return
1456
1472
        super(RemoteBranchFormat, self).__init__()
1457
1473
        self._matchingbzrdir = RemoteBzrDirFormat()
1458
1474
        self._matchingbzrdir.set_branch_format(self)
 
1475
        self._custom_format = None
1459
1476
 
1460
1477
    def __eq__(self, other):
1461
1478
        return (isinstance(other, RemoteBranchFormat) and
1464
1481
    def get_format_description(self):
1465
1482
        return 'Remote BZR Branch'
1466
1483
 
1467
 
    def get_format_string(self):
1468
 
        return 'Remote BZR Branch'
 
1484
    def network_name(self):
 
1485
        return self._network_name
1469
1486
 
1470
1487
    def open(self, a_bzrdir):
1471
1488
        return a_bzrdir.open_branch()
1472
1489
 
 
1490
    def _vfs_initialize(self, a_bzrdir):
 
1491
        # Initialisation when using a local bzrdir object, or a non-vfs init
 
1492
        # method is not available on the server.
 
1493
        # self._custom_format is always set - the start of initialize ensures
 
1494
        # that.
 
1495
        if isinstance(a_bzrdir, RemoteBzrDir):
 
1496
            a_bzrdir._ensure_real()
 
1497
            result = self._custom_format.initialize(a_bzrdir._real_bzrdir)
 
1498
        else:
 
1499
            # We assume the bzrdir is parameterised; it may not be.
 
1500
            result = self._custom_format.initialize(a_bzrdir)
 
1501
        if (isinstance(a_bzrdir, RemoteBzrDir) and
 
1502
            not isinstance(result, RemoteBranch)):
 
1503
            result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result)
 
1504
        return result
 
1505
 
1473
1506
    def initialize(self, a_bzrdir):
1474
 
        # Delegate to a _real object here - the RemoteBzrDir format now
1475
 
        # supports delegating to parameterised branch formats and as such
1476
 
        # this RemoteBranchFormat method is only called when no specific format
1477
 
        # is selected.
 
1507
        # 1) get the network name to use.
 
1508
        if self._custom_format:
 
1509
            network_name = self._custom_format.network_name()
 
1510
        else:
 
1511
            # Select the current bzrlib default and ask for that.
 
1512
            reference_bzrdir_format = bzrdir.format_registry.get('default')()
 
1513
            reference_format = reference_bzrdir_format.get_branch_format()
 
1514
            self._custom_format = reference_format
 
1515
            network_name = reference_format.network_name()
 
1516
        # Being asked to create on a non RemoteBzrDir:
1478
1517
        if not isinstance(a_bzrdir, RemoteBzrDir):
1479
 
            result = a_bzrdir.create_branch()
 
1518
            return self._vfs_initialize(a_bzrdir)
 
1519
        medium = a_bzrdir._client._medium
 
1520
        if medium._is_remote_before((1, 13)):
 
1521
            return self._vfs_initialize(a_bzrdir)
 
1522
        # Creating on a remote bzr dir.
 
1523
        # 2) try direct creation via RPC
 
1524
        path = a_bzrdir._path_for_remote_call(a_bzrdir._client)
 
1525
        verb = 'BzrDir.create_branch'
 
1526
        try:
 
1527
            response = a_bzrdir._call(verb, path, network_name)
 
1528
        except errors.UnknownSmartMethod:
 
1529
            # Fallback - use vfs methods
 
1530
            return self._vfs_initialize(a_bzrdir)
 
1531
        if response[0] != 'ok':
 
1532
            raise errors.UnexpectedSmartServerResponse(response)
 
1533
        # Turn the response into a RemoteRepository object.
 
1534
        format = RemoteBranchFormat()
 
1535
        format._network_name = response[1]
 
1536
        repo_format = response_tuple_to_repo_format(response[3:])
 
1537
        if response[2] == '':
 
1538
            repo_bzrdir = a_bzrdir
1480
1539
        else:
1481
 
            a_bzrdir._ensure_real()
1482
 
            result = a_bzrdir._real_bzrdir.create_branch()
1483
 
        if not isinstance(result, RemoteBranch):
1484
 
            result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result)
1485
 
        return result
 
1540
            repo_bzrdir = RemoteBzrDir(
 
1541
                a_bzrdir.root_transport.clone(response[2]), a_bzrdir._format,
 
1542
                a_bzrdir._client)
 
1543
        remote_repo = RemoteRepository(repo_bzrdir, repo_format)
 
1544
        remote_branch = RemoteBranch(a_bzrdir, remote_repo,
 
1545
            format=format, setup_stacking=False)
 
1546
        return remote_branch
1486
1547
 
1487
1548
    def supports_tags(self):
1488
1549
        # Remote branches might support tags, but we won't know until we
1497
1558
    """
1498
1559
 
1499
1560
    def __init__(self, remote_bzrdir, remote_repository, real_branch=None,
1500
 
        _client=None):
 
1561
        _client=None, format=None, setup_stacking=True):
1501
1562
        """Create a RemoteBranch instance.
1502
1563
 
1503
1564
        :param real_branch: An optional local implementation of the branch
1504
1565
            format, usually accessing the data via the VFS.
1505
1566
        :param _client: Private parameter for testing.
 
1567
        :param format: A RemoteBranchFormat object, None to create one
 
1568
            automatically. If supplied it should have a network_name already
 
1569
            supplied.
 
1570
        :param setup_stacking: If True make an RPC call to determine the
 
1571
            stacked (or not) status of the branch. If False assume the branch
 
1572
            is not stacked.
1506
1573
        """
1507
1574
        # We intentionally don't call the parent class's __init__, because it
1508
1575
        # will try to assign to self.tags, which is a property in this subclass.
1531
1598
        else:
1532
1599
            self._real_branch = None
1533
1600
        # Fill out expected attributes of branch for bzrlib api users.
1534
 
        self._format = RemoteBranchFormat()
1535
1601
        self.base = self.bzrdir.root_transport.base
1536
1602
        self._control_files = None
1537
1603
        self._lock_mode = None
1539
1605
        self._repo_lock_token = None
1540
1606
        self._lock_count = 0
1541
1607
        self._leave_lock = False
 
1608
        # Setup a format: note that we cannot call _ensure_real until all the
 
1609
        # attributes above are set: This code cannot be moved higher up in this
 
1610
        # function.
 
1611
        if format is None:
 
1612
            self._format = RemoteBranchFormat()
 
1613
            if real_branch is not None:
 
1614
                self._format._network_name = \
 
1615
                    self._real_branch._format.network_name()
 
1616
            #else:
 
1617
            #    # XXX: Need to get this from BzrDir.open_branch's return value.
 
1618
            #    self._ensure_real()
 
1619
            #    self._format._network_name = \
 
1620
            #        self._real_branch._format.network_name()
 
1621
        else:
 
1622
            self._format = format
1542
1623
        # The base class init is not called, so we duplicate this:
1543
1624
        hooks = branch.Branch.hooks['open']
1544
1625
        for hook in hooks:
1545
1626
            hook(self)
1546
 
        self._setup_stacking()
 
1627
        if setup_stacking:
 
1628
            self._setup_stacking()
1547
1629
 
1548
1630
    def _setup_stacking(self):
1549
1631
        # configure stacking into the remote repository, by reading it from
1889
1971
        self._ensure_real()
1890
1972
        return self._real_branch.set_stacked_on_url(stacked_location)
1891
1973
 
1892
 
    def sprout(self, to_bzrdir, revision_id=None):
1893
 
        branch_format = to_bzrdir._format._branch_format
1894
 
        if (branch_format is None or
1895
 
            isinstance(branch_format, RemoteBranchFormat)):
1896
 
            # The to_bzrdir specifies RemoteBranchFormat (or no format, which
1897
 
            # implies the same thing), but RemoteBranches can't be created at
1898
 
            # arbitrary URLs.  So create a branch in the same format as
1899
 
            # _real_branch instead.
1900
 
            # XXX: if to_bzrdir is a RemoteBzrDir, this should perhaps do
1901
 
            # to_bzrdir.create_branch to create a RemoteBranch after all...
1902
 
            self._ensure_real()
1903
 
            result = self._real_branch._format.initialize(to_bzrdir)
1904
 
            self.copy_content_into(result, revision_id=revision_id)
1905
 
            result.set_parent(self.bzrdir.root_transport.base)
1906
 
        else:
1907
 
            result = branch.Branch.sprout(
1908
 
                self, to_bzrdir, revision_id=revision_id)
1909
 
        return result
1910
 
 
1911
1974
    @needs_write_lock
1912
1975
    def pull(self, source, overwrite=False, stop_revision=None,
1913
1976
             **kwargs):