/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/repository.py

  • Committer: Jelmer Vernooij
  • Date: 2010-08-02 23:53:16 UTC
  • mto: This revision was merged to the branch mainline in revision 5389.
  • Revision ID: jelmer@samba.org-20100802235316-v6a6p0r2a1os0dsn
baseĀ ControlDirĀ onĀ ControlComponent.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
    check,
26
26
    chk_map,
27
27
    config,
 
28
    controldir,
28
29
    debug,
29
 
    errors,
30
30
    fetch as _mod_fetch,
31
31
    fifo_cache,
32
32
    generate_ids,
44
44
    symbol_versioning,
45
45
    trace,
46
46
    tsort,
47
 
    ui,
48
47
    versionedfile,
49
48
    )
50
49
from bzrlib.bundle import serializer
53
52
from bzrlib.testament import Testament
54
53
""")
55
54
 
 
55
from bzrlib import (
 
56
    errors,
 
57
    registry,
 
58
    ui,
 
59
    )
56
60
from bzrlib.decorators import needs_read_lock, needs_write_lock, only_raises
57
61
from bzrlib.inter import InterObject
58
62
from bzrlib.inventory import (
61
65
    ROOT_ID,
62
66
    entry_factory,
63
67
    )
64
 
from bzrlib.lock import _RelockDebugMixin
65
 
from bzrlib import registry
 
68
from bzrlib.recordcounter import RecordCounter
 
69
from bzrlib.lock import _RelockDebugMixin, LogicalLockResult
66
70
from bzrlib.trace import (
67
71
    log_exception_quietly, note, mutter, mutter_callsite, warning)
68
72
 
71
75
_deprecation_warning_done = False
72
76
 
73
77
 
 
78
class IsInWriteGroupError(errors.InternalBzrError):
 
79
 
 
80
    _fmt = "May not refresh_data of repo %(repo)s while in a write group."
 
81
 
 
82
    def __init__(self, repo):
 
83
        errors.InternalBzrError.__init__(self, repo=repo)
 
84
 
 
85
 
74
86
class CommitBuilder(object):
75
87
    """Provides an interface to build up a commit.
76
88
 
278
290
 
279
291
        :param tree: The tree which is being committed.
280
292
        """
281
 
        # NB: if there are no parents then this method is not called, so no
282
 
        # need to guard on parents having length.
 
293
        if len(self.parents) == 0:
 
294
            raise errors.RootMissing()
283
295
        entry = entry_factory['directory'](tree.path2id(''), '',
284
296
            None)
285
297
        entry.revision = self._new_revision_id
860
872
        # versioned roots do not change unless the tree found a change.
861
873
 
862
874
 
 
875
class RepositoryWriteLockResult(LogicalLockResult):
 
876
    """The result of write locking a repository.
 
877
 
 
878
    :ivar repository_token: The token obtained from the underlying lock, or
 
879
        None.
 
880
    :ivar unlock: A callable which will unlock the lock.
 
881
    """
 
882
 
 
883
    def __init__(self, unlock, repository_token):
 
884
        LogicalLockResult.__init__(self, unlock)
 
885
        self.repository_token = repository_token
 
886
 
 
887
    def __repr__(self):
 
888
        return "RepositoryWriteLockResult(%s, %s)" % (self.repository_token,
 
889
            self.unlock)
 
890
 
 
891
 
863
892
######################################################################
864
893
# Repositories
865
894
 
866
895
 
867
 
class Repository(_RelockDebugMixin, bzrdir.ControlComponent):
 
896
class Repository(_RelockDebugMixin, controldir.ControlComponent):
868
897
    """Repository holding history for one or more branches.
869
898
 
870
899
    The repository holds and retrieves historical information including
1018
1047
                " id and insertion revid (%r, %r)"
1019
1048
                % (inv.revision_id, revision_id))
1020
1049
        if inv.root is None:
1021
 
            raise AssertionError()
 
1050
            raise errors.RootMissing()
1022
1051
        return self._add_inventory_checked(revision_id, inv, parents)
1023
1052
 
1024
1053
    def _add_inventory_checked(self, revision_id, inv, parents):
1376
1405
        data during reads, and allows a 'write_group' to be obtained. Write
1377
1406
        groups must be used for actual data insertion.
1378
1407
 
 
1408
        A token should be passed in if you know that you have locked the object
 
1409
        some other way, and need to synchronise this object's state with that
 
1410
        fact.
 
1411
 
 
1412
        XXX: this docstring is duplicated in many places, e.g. lockable_files.py
 
1413
 
1379
1414
        :param token: if this is already locked, then lock_write will fail
1380
1415
            unless the token matches the existing lock.
1381
1416
        :returns: a token if this instance supports tokens, otherwise None.
1384
1419
        :raises MismatchedToken: if the specified token doesn't match the token
1385
1420
            of the existing lock.
1386
1421
        :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
 
1422
        :return: A RepositoryWriteLockResult.
1393
1423
        """
1394
1424
        locked = self.is_locked()
1395
 
        result = self.control_files.lock_write(token=token)
 
1425
        token = self.control_files.lock_write(token=token)
1396
1426
        if not locked:
1397
1427
            self._warn_if_deprecated()
1398
1428
            self._note_lock('w')
1400
1430
                # Writes don't affect fallback repos
1401
1431
                repo.lock_read()
1402
1432
            self._refresh_data()
1403
 
        return result
 
1433
        return RepositoryWriteLockResult(self.unlock, token)
1404
1434
 
1405
1435
    def lock_read(self):
 
1436
        """Lock the repository for read operations.
 
1437
 
 
1438
        :return: An object with an unlock method which will release the lock
 
1439
            obtained.
 
1440
        """
1406
1441
        locked = self.is_locked()
1407
1442
        self.control_files.lock_read()
1408
1443
        if not locked:
1411
1446
            for repo in self._fallback_repositories:
1412
1447
                repo.lock_read()
1413
1448
            self._refresh_data()
 
1449
        return LogicalLockResult(self.unlock)
1414
1450
 
1415
1451
    def get_physical_lock_status(self):
1416
1452
        return self.control_files.get_physical_lock_status()
1634
1670
        return missing_keys
1635
1671
 
1636
1672
    def refresh_data(self):
1637
 
        """Re-read any data needed to to synchronise with disk.
 
1673
        """Re-read any data needed to synchronise with disk.
1638
1674
 
1639
1675
        This method is intended to be called after another repository instance
1640
1676
        (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.
 
1677
        repository. On all repositories this will work outside of write groups.
 
1678
        Some repository formats (pack and newer for bzrlib native formats)
 
1679
        support refresh_data inside write groups. If called inside a write
 
1680
        group on a repository that does not support refreshing in a write group
 
1681
        IsInWriteGroupError will be raised.
1643
1682
        """
1644
 
        if self.is_in_write_group():
1645
 
            raise errors.InternalBzrError(
1646
 
                "May not refresh_data while in a write group.")
1647
1683
        self._refresh_data()
1648
1684
 
1649
1685
    def resume_write_group(self, tokens):
1688
1724
                "May not fetch while in a write group.")
1689
1725
        # fast path same-url fetch operations
1690
1726
        # TODO: lift out to somewhere common with RemoteRepository
1691
 
        # <https://bugs.edge.launchpad.net/bzr/+bug/401646>
 
1727
        # <https://bugs.launchpad.net/bzr/+bug/401646>
1692
1728
        if (self.has_same_location(source)
1693
1729
            and fetch_spec is None
1694
1730
            and self._has_same_fallbacks(source)):
4249
4285
                is_resume = False
4250
4286
            try:
4251
4287
                # locked_insert_stream performs a commit|suspend.
4252
 
                return self._locked_insert_stream(stream, src_format, is_resume)
 
4288
                return self._locked_insert_stream(stream, src_format,
 
4289
                    is_resume)
4253
4290
            except:
4254
4291
                self.target_repo.abort_write_group(suppress_errors=True)
4255
4292
                raise
4302
4339
                # required if the serializers are different only in terms of
4303
4340
                # the inventory.
4304
4341
                if src_serializer == to_serializer:
4305
 
                    self.target_repo.revisions.insert_record_stream(
4306
 
                        substream)
 
4342
                    self.target_repo.revisions.insert_record_stream(substream)
4307
4343
                else:
4308
4344
                    self._extract_and_insert_revisions(substream,
4309
4345
                        src_serializer)
4417
4453
        """Create a StreamSource streaming from from_repository."""
4418
4454
        self.from_repository = from_repository
4419
4455
        self.to_format = to_format
 
4456
        self._record_counter = RecordCounter()
4420
4457
 
4421
4458
    def delta_on_metadata(self):
4422
4459
        """Return True if delta's are permitted on metadata streams.