~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repository.py

  • Committer: Martin
  • Date: 2010-05-16 15:18:43 UTC
  • mfrom: (5235 +trunk)
  • mto: This revision was merged to the branch mainline in revision 5239.
  • Revision ID: gzlist@googlemail.com-20100516151843-lu53u7caehm3ie3i
Merge bzr.dev to resolve conflicts in NEWS and _chk_map_pyx

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
    chk_map,
27
27
    config,
28
28
    debug,
29
 
    errors,
30
29
    fetch as _mod_fetch,
31
30
    fifo_cache,
32
31
    generate_ids,
53
52
from bzrlib.testament import Testament
54
53
""")
55
54
 
 
55
from bzrlib import (
 
56
    errors,
 
57
    registry,
 
58
    )
56
59
from bzrlib.decorators import needs_read_lock, needs_write_lock, only_raises
57
60
from bzrlib.inter import InterObject
58
61
from bzrlib.inventory import (
61
64
    ROOT_ID,
62
65
    entry_factory,
63
66
    )
64
 
from bzrlib.lock import _RelockDebugMixin
65
 
from bzrlib import registry
 
67
from bzrlib.lock import _RelockDebugMixin, LogicalLockResult
66
68
from bzrlib.trace import (
67
69
    log_exception_quietly, note, mutter, mutter_callsite, warning)
68
70
 
71
73
_deprecation_warning_done = False
72
74
 
73
75
 
 
76
class IsInWriteGroupError(errors.InternalBzrError):
 
77
 
 
78
    _fmt = "May not refresh_data of repo %(repo)s while in a write group."
 
79
 
 
80
    def __init__(self, repo):
 
81
        errors.InternalBzrError.__init__(self, repo=repo)
 
82
 
 
83
 
74
84
class CommitBuilder(object):
75
85
    """Provides an interface to build up a commit.
76
86
 
278
288
 
279
289
        :param tree: The tree which is being committed.
280
290
        """
281
 
        # NB: if there are no parents then this method is not called, so no
282
 
        # need to guard on parents having length.
 
291
        if len(self.parents) == 0:
 
292
            raise errors.RootMissing()
283
293
        entry = entry_factory['directory'](tree.path2id(''), '',
284
294
            None)
285
295
        entry.revision = self._new_revision_id
860
870
        # versioned roots do not change unless the tree found a change.
861
871
 
862
872
 
 
873
class RepositoryWriteLockResult(LogicalLockResult):
 
874
    """The result of write locking a repository.
 
875
 
 
876
    :ivar repository_token: The token obtained from the underlying lock, or
 
877
        None.
 
878
    :ivar unlock: A callable which will unlock the lock.
 
879
    """
 
880
 
 
881
    def __init__(self, unlock, repository_token):
 
882
        LogicalLockResult.__init__(self, unlock)
 
883
        self.repository_token = repository_token
 
884
 
 
885
    def __repr__(self):
 
886
        return "RepositoryWriteLockResult(%s, %s)" % (self.repository_token,
 
887
            self.unlock)
 
888
 
 
889
 
863
890
######################################################################
864
891
# Repositories
865
892
 
1018
1045
                " id and insertion revid (%r, %r)"
1019
1046
                % (inv.revision_id, revision_id))
1020
1047
        if inv.root is None:
1021
 
            raise AssertionError()
 
1048
            raise errors.RootMissing()
1022
1049
        return self._add_inventory_checked(revision_id, inv, parents)
1023
1050
 
1024
1051
    def _add_inventory_checked(self, revision_id, inv, parents):
1376
1403
        data during reads, and allows a 'write_group' to be obtained. Write
1377
1404
        groups must be used for actual data insertion.
1378
1405
 
 
1406
        A token should be passed in if you know that you have locked the object
 
1407
        some other way, and need to synchronise this object's state with that
 
1408
        fact.
 
1409
 
 
1410
        XXX: this docstring is duplicated in many places, e.g. lockable_files.py
 
1411
 
1379
1412
        :param token: if this is already locked, then lock_write will fail
1380
1413
            unless the token matches the existing lock.
1381
1414
        :returns: a token if this instance supports tokens, otherwise None.
1384
1417
        :raises MismatchedToken: if the specified token doesn't match the token
1385
1418
            of the existing lock.
1386
1419
        :seealso: start_write_group.
1387
 
 
1388
 
        A token should be passed in if you know that you have locked the object
1389
 
        some other way, and need to synchronise this object's state with that
1390
 
        fact.
1391
 
 
1392
 
        XXX: this docstring is duplicated in many places, e.g. lockable_files.py
 
1420
        :return: A RepositoryWriteLockResult.
1393
1421
        """
1394
1422
        locked = self.is_locked()
1395
 
        result = self.control_files.lock_write(token=token)
 
1423
        token = self.control_files.lock_write(token=token)
1396
1424
        if not locked:
1397
1425
            self._warn_if_deprecated()
1398
1426
            self._note_lock('w')
1400
1428
                # Writes don't affect fallback repos
1401
1429
                repo.lock_read()
1402
1430
            self._refresh_data()
1403
 
        return result
 
1431
        return RepositoryWriteLockResult(self.unlock, token)
1404
1432
 
1405
1433
    def lock_read(self):
 
1434
        """Lock the repository for read operations.
 
1435
 
 
1436
        :return: An object with an unlock method which will release the lock
 
1437
            obtained.
 
1438
        """
1406
1439
        locked = self.is_locked()
1407
1440
        self.control_files.lock_read()
1408
1441
        if not locked:
1411
1444
            for repo in self._fallback_repositories:
1412
1445
                repo.lock_read()
1413
1446
            self._refresh_data()
 
1447
        return LogicalLockResult(self.unlock)
1414
1448
 
1415
1449
    def get_physical_lock_status(self):
1416
1450
        return self.control_files.get_physical_lock_status()
1634
1668
        return missing_keys
1635
1669
 
1636
1670
    def refresh_data(self):
1637
 
        """Re-read any data needed to to synchronise with disk.
 
1671
        """Re-read any data needed to synchronise with disk.
1638
1672
 
1639
1673
        This method is intended to be called after another repository instance
1640
1674
        (such as one used by a smart server) has inserted data into the
1641
 
        repository. It may not be called during a write group, but may be
1642
 
        called at any other time.
 
1675
        repository. On all repositories this will work outside of write groups.
 
1676
        Some repository formats (pack and newer for bzrlib native formats)
 
1677
        support refresh_data inside write groups. If called inside a write
 
1678
        group on a repository that does not support refreshing in a write group
 
1679
        IsInWriteGroupError will be raised.
1643
1680
        """
1644
 
        if self.is_in_write_group():
1645
 
            raise errors.InternalBzrError(
1646
 
                "May not refresh_data while in a write group.")
1647
1681
        self._refresh_data()
1648
1682
 
1649
1683
    def resume_write_group(self, tokens):