/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

Merge with extras

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
# across to run on the server.
19
19
 
20
20
import bz2
21
 
from cStringIO import StringIO
22
21
 
23
22
from bzrlib import (
24
23
    branch,
32
31
)
33
32
from bzrlib.branch import BranchReferenceFormat
34
33
from bzrlib.bzrdir import BzrDir, RemoteBzrDirFormat
35
 
from bzrlib.config import BranchConfig, TreeConfig
36
34
from bzrlib.decorators import needs_read_lock, needs_write_lock
37
35
from bzrlib.errors import (
38
36
    NoSuchRevision,
39
37
    SmartProtocolError,
40
38
    )
41
39
from bzrlib.lockable_files import LockableFiles
42
 
from bzrlib.pack import ContainerPushParser
43
40
from bzrlib.smart import client, vfs
44
 
from bzrlib.symbol_versioning import (
45
 
    deprecated_in,
46
 
    deprecated_method,
47
 
    )
48
41
from bzrlib.revision import ensure_null, NULL_REVISION
49
42
from bzrlib.trace import mutter, note, warning
50
43
 
88
81
            self._real_bzrdir = BzrDir.open_from_transport(
89
82
                self.root_transport, _server_formats=False)
90
83
 
91
 
    def cloning_metadir(self):
 
84
    def cloning_metadir(self, stacked=False):
92
85
        self._ensure_real()
93
 
        return self._real_bzrdir.cloning_metadir()
 
86
        return self._real_bzrdir.cloning_metadir(stacked)
94
87
 
95
88
    def _translate_error(self, err, **context):
96
89
        _translate_error(err, bzrdir=self, **context)
356
349
 
357
350
        Used before calls to self._real_repository.
358
351
        """
359
 
        if not self._real_repository:
 
352
        if self._real_repository is None:
360
353
            self.bzrdir._ensure_real()
361
 
            #self._real_repository = self.bzrdir._real_bzrdir.open_repository()
362
 
            self._set_real_repository(self.bzrdir._real_bzrdir.open_repository())
 
354
            self._set_real_repository(
 
355
                self.bzrdir._real_bzrdir.open_repository())
363
356
 
364
357
    def _translate_error(self, err, **context):
365
358
        self.bzrdir._translate_error(err, repository=self, **context)
549
542
        else:
550
543
            raise errors.UnexpectedSmartServerResponse(response)
551
544
 
552
 
    def lock_write(self, token=None):
 
545
    def lock_write(self, token=None, _skip_rpc=False):
553
546
        if not self._lock_mode:
554
 
            self._lock_token = self._remote_lock_write(token)
 
547
            if _skip_rpc:
 
548
                if self._lock_token is not None:
 
549
                    if token != self._lock_token:
 
550
                        raise errors.TokenMismatch(token, self._lock_token)
 
551
                self._lock_token = token
 
552
            else:
 
553
                self._lock_token = self._remote_lock_write(token)
555
554
            # if self._lock_token is None, then this is something like packs or
556
555
            # svn where we don't get to lock the repo, or a weave style repository
557
556
            # where we cannot lock it over the wire and attempts to do so will
589
588
        :param repository: The repository to fallback to for non-hpss
590
589
            implemented operations.
591
590
        """
 
591
        if self._real_repository is not None:
 
592
            raise AssertionError('_real_repository is already set')
592
593
        if isinstance(repository, RemoteRepository):
593
594
            raise AssertionError()
594
595
        self._real_repository = repository
703
704
        # FIXME: It ought to be possible to call this without immediately
704
705
        # triggering _ensure_real.  For now it's the easiest thing to do.
705
706
        self._ensure_real()
706
 
        builder = self._real_repository.get_commit_builder(branch, parents,
 
707
        real_repo = self._real_repository
 
708
        builder = real_repo.get_commit_builder(branch, parents,
707
709
                config, timestamp=timestamp, timezone=timezone,
708
710
                committer=committer, revprops=revprops, revision_id=revision_id)
709
711
        return builder
1039
1041
        # destination
1040
1042
        from bzrlib import osutils
1041
1043
        import tarfile
1042
 
        import tempfile
1043
1044
        # TODO: Maybe a progress bar while streaming the tarball?
1044
1045
        note("Copying repository content as tarball...")
1045
1046
        tar_file = self._get_tarball('bz2')
1049
1050
        try:
1050
1051
            tar = tarfile.open('repository', fileobj=tar_file,
1051
1052
                mode='r|bz2')
1052
 
            tmpdir = tempfile.mkdtemp()
 
1053
            tmpdir = osutils.mkdtemp()
1053
1054
            try:
1054
1055
                _extract_tar(tar, tmpdir)
1055
1056
                tmp_bzrdir = BzrDir.open(tmpdir)
1302
1303
                    'to use vfs implementation')
1303
1304
            self.bzrdir._ensure_real()
1304
1305
            self._real_branch = self.bzrdir._real_bzrdir.open_branch()
1305
 
            # Give the remote repository the matching real repo.
1306
 
            real_repo = self._real_branch.repository
1307
 
            if isinstance(real_repo, RemoteRepository):
1308
 
                real_repo._ensure_real()
1309
 
                real_repo = real_repo._real_repository
1310
 
            self.repository._set_real_repository(real_repo)
1311
 
            # Give the branch the remote repository to let fast-pathing happen.
 
1306
            if self.repository._real_repository is None:
 
1307
                # Give the remote repository the matching real repo.
 
1308
                real_repo = self._real_branch.repository
 
1309
                if isinstance(real_repo, RemoteRepository):
 
1310
                    real_repo._ensure_real()
 
1311
                    real_repo = real_repo._real_repository
 
1312
                self.repository._set_real_repository(real_repo)
 
1313
            # Give the real branch the remote repository to let fast-pathing
 
1314
            # happen.
1312
1315
            self._real_branch.repository = self.repository
1313
 
            # XXX: deal with _lock_mode == 'w'
1314
1316
            if self._lock_mode == 'r':
1315
1317
                self._real_branch.lock_read()
 
1318
            elif self._lock_mode == 'w':
 
1319
                self._real_branch.lock_write(token=self._lock_token)
1316
1320
 
1317
1321
    def _translate_error(self, err, **context):
1318
1322
        self.repository._translate_error(err, branch=self, **context)
1366
1370
        return self._real_branch.get_stacked_on_url()
1367
1371
 
1368
1372
    def lock_read(self):
 
1373
        self.repository.lock_read()
1369
1374
        if not self._lock_mode:
1370
1375
            self._lock_mode = 'r'
1371
1376
            self._lock_count = 1
1394
1399
            
1395
1400
    def lock_write(self, token=None):
1396
1401
        if not self._lock_mode:
 
1402
            # Lock the branch and repo in one remote call.
1397
1403
            remote_tokens = self._remote_lock_write(token)
1398
1404
            self._lock_token, self._repo_lock_token = remote_tokens
1399
1405
            if not self._lock_token:
1400
1406
                raise SmartProtocolError('Remote server did not return a token!')
1401
 
            # TODO: We really, really, really don't want to call _ensure_real
1402
 
            # here, but it's the easiest way to ensure coherency between the
1403
 
            # state of the RemoteBranch and RemoteRepository objects and the
1404
 
            # physical locks.  If we don't materialise the real objects here,
1405
 
            # then getting everything in the right state later is complex, so
1406
 
            # for now we just do it the lazy way.
1407
 
            #   -- Andrew Bennetts, 2007-02-22.
1408
 
            self._ensure_real()
 
1407
            # Tell the self.repository object that it is locked.
 
1408
            self.repository.lock_write(
 
1409
                self._repo_lock_token, _skip_rpc=True)
 
1410
 
1409
1411
            if self._real_branch is not None:
1410
 
                self._real_branch.repository.lock_write(
1411
 
                    token=self._repo_lock_token)
1412
 
                try:
1413
 
                    self._real_branch.lock_write(token=self._lock_token)
1414
 
                finally:
1415
 
                    self._real_branch.repository.unlock()
 
1412
                self._real_branch.lock_write(token=self._lock_token)
1416
1413
            if token is not None:
1417
1414
                self._leave_lock = True
1418
1415
            else:
1419
 
                # XXX: this case seems to be unreachable; token cannot be None.
1420
1416
                self._leave_lock = False
1421
1417
            self._lock_mode = 'w'
1422
1418
            self._lock_count = 1
1424
1420
            raise errors.ReadOnlyTransaction
1425
1421
        else:
1426
1422
            if token is not None:
1427
 
                # A token was given to lock_write, and we're relocking, so check
1428
 
                # that the given token actually matches the one we already have.
 
1423
                # A token was given to lock_write, and we're relocking, so
 
1424
                # check that the given token actually matches the one we
 
1425
                # already have.
1429
1426
                if token != self._lock_token:
1430
1427
                    raise errors.TokenMismatch(token, self._lock_token)
1431
1428
            self._lock_count += 1
 
1429
            # Re-lock the repository too.
 
1430
            self.repository.lock_write(self._repo_lock_token)
1432
1431
        return self._lock_token or None
1433
1432
 
1434
1433
    def _unlock(self, branch_token, repo_token):
1443
1442
        raise errors.UnexpectedSmartServerResponse(response)
1444
1443
 
1445
1444
    def unlock(self):
1446
 
        self._lock_count -= 1
1447
 
        if not self._lock_count:
1448
 
            self._clear_cached_state()
1449
 
            mode = self._lock_mode
1450
 
            self._lock_mode = None
1451
 
            if self._real_branch is not None:
1452
 
                if (not self._leave_lock and mode == 'w' and
1453
 
                    self._repo_lock_token):
1454
 
                    # If this RemoteBranch will remove the physical lock for the
1455
 
                    # repository, make sure the _real_branch doesn't do it
1456
 
                    # first.  (Because the _real_branch's repository is set to
1457
 
                    # be the RemoteRepository.)
1458
 
                    self._real_branch.repository.leave_lock_in_place()
1459
 
                self._real_branch.unlock()
1460
 
            if mode != 'w':
1461
 
                # Only write-locked branched need to make a remote method call
1462
 
                # to perfom the unlock.
1463
 
                return
1464
 
            if not self._lock_token:
1465
 
                raise AssertionError('Locked, but no token!')
1466
 
            branch_token = self._lock_token
1467
 
            repo_token = self._repo_lock_token
1468
 
            self._lock_token = None
1469
 
            self._repo_lock_token = None
1470
 
            if not self._leave_lock:
1471
 
                self._unlock(branch_token, repo_token)
 
1445
        try:
 
1446
            self._lock_count -= 1
 
1447
            if not self._lock_count:
 
1448
                self._clear_cached_state()
 
1449
                mode = self._lock_mode
 
1450
                self._lock_mode = None
 
1451
                if self._real_branch is not None:
 
1452
                    if (not self._leave_lock and mode == 'w' and
 
1453
                        self._repo_lock_token):
 
1454
                        # If this RemoteBranch will remove the physical lock
 
1455
                        # for the repository, make sure the _real_branch
 
1456
                        # doesn't do it first.  (Because the _real_branch's
 
1457
                        # repository is set to be the RemoteRepository.)
 
1458
                        self._real_branch.repository.leave_lock_in_place()
 
1459
                    self._real_branch.unlock()
 
1460
                if mode != 'w':
 
1461
                    # Only write-locked branched need to make a remote method
 
1462
                    # call to perfom the unlock.
 
1463
                    return
 
1464
                if not self._lock_token:
 
1465
                    raise AssertionError('Locked, but no token!')
 
1466
                branch_token = self._lock_token
 
1467
                repo_token = self._repo_lock_token
 
1468
                self._lock_token = None
 
1469
                self._repo_lock_token = None
 
1470
                if not self._leave_lock:
 
1471
                    self._unlock(branch_token, repo_token)
 
1472
        finally:
 
1473
            self.repository.unlock()
1472
1474
 
1473
1475
    def break_lock(self):
1474
1476
        self._ensure_real()
1519
1521
            raise errors.UnexpectedSmartServerResponse(response)
1520
1522
        new_revno, new_revision_id = response[1:]
1521
1523
        self._last_revision_info_cache = new_revno, new_revision_id
1522
 
        self._real_branch._last_revision_info_cache = new_revno, new_revision_id
 
1524
        if self._real_branch is not None:
 
1525
            cache = new_revno, new_revision_id
 
1526
            self._real_branch._last_revision_info_cache = cache
1523
1527
 
1524
1528
    def _set_last_revision(self, revision_id):
1525
1529
        path = self.bzrdir._path_for_remote_call(self._client)
1593
1597
    def is_locked(self):
1594
1598
        return self._lock_count >= 1
1595
1599
 
 
1600
    @needs_read_lock
 
1601
    def revision_id_to_revno(self, revision_id):
 
1602
        self._ensure_real()
 
1603
        return self._real_branch.revision_id_to_revno(revision_id)
 
1604
 
1596
1605
    @needs_write_lock
1597
1606
    def set_last_revision_info(self, revno, revision_id):
1598
1607
        revision_id = ensure_null(revision_id)
1701
1710
      - bzrdir
1702
1711
      - token
1703
1712
      - other_branch
 
1713
 
 
1714
    If the error from the server doesn't match a known pattern, then
 
1715
    UnknownErrorFromSmartServer is raised.
1704
1716
    """
1705
1717
    def find(name):
1706
1718
        try:
1728
1740
        raise errors.DivergedBranches(find('branch'), find('other_branch'))
1729
1741
    elif err.error_verb == 'TipChangeRejected':
1730
1742
        raise errors.TipChangeRejected(err.error_args[0].decode('utf8'))
1731
 
    raise
 
1743
    raise errors.UnknownErrorFromSmartServer(err)
1732
1744