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

  • Committer: Jelmer Vernooij
  • Date: 2019-05-29 03:22:34 UTC
  • mfrom: (7303 work)
  • mto: This revision was merged to the branch mainline in revision 7306.
  • Revision ID: jelmer@jelmer.uk-20190529032234-mt3fuws8gq03tapi
Merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
from .lazy_import import lazy_import
20
20
lazy_import(globals(), """
21
 
import itertools
22
21
import time
23
22
 
24
23
from breezy import (
25
24
    config,
26
25
    controldir,
27
26
    debug,
28
 
    generate_ids,
29
27
    graph,
30
28
    osutils,
31
29
    revision as _mod_revision,
32
 
    testament as _mod_testament,
33
30
    gpg,
34
31
    )
35
32
from breezy.bundle import serializer
47
44
from .sixish import (
48
45
    text_type,
49
46
    viewitems,
50
 
    viewvalues,
51
47
    )
52
48
from .trace import (
53
49
    log_exception_quietly, note, mutter, mutter_callsite, warning)
104
100
        if committer is None:
105
101
            self._committer = self._config_stack.get('email')
106
102
        elif not isinstance(committer, text_type):
107
 
            self._committer = committer.decode() # throw if non-ascii
 
103
            self._committer = committer.decode()  # throw if non-ascii
108
104
        else:
109
105
            self._committer = committer
110
106
 
186
182
        """
187
183
        raise NotImplementedError(self.finish_inventory)
188
184
 
189
 
    def _gen_revision_id(self):
190
 
        """Return new revision-id."""
191
 
        return generate_ids.gen_revision_id(self._committer, self._timestamp)
192
 
 
193
185
    def _generate_revision_if_needed(self, revision_id):
194
186
        """Create a revision id if None was supplied.
195
187
 
221
213
            to basis_revision_id. The iterator must not include any items with
222
214
            a current kind of None - missing items must be either filtered out
223
215
            or errored-on beefore record_iter_changes sees the item.
224
 
        :return: A generator of (file_id, relpath, fs_hash) tuples for use with
 
216
        :return: A generator of (relpath, fs_hash) tuples for use with
225
217
            tree._observed_sha1.
226
218
        """
227
219
        raise NotImplementedError(self.record_iter_changes)
241
233
 
242
234
    def __repr__(self):
243
235
        return "RepositoryWriteLockResult(%s, %s)" % (self.repository_token,
244
 
            self.unlock)
 
236
                                                      self.unlock)
245
237
 
246
238
 
247
239
class WriteGroup(object):
281
273
    base class for most Bazaar repositories.
282
274
    """
283
275
 
 
276
    # Does this repository implementation support random access to
 
277
    # items in the tree, or just bulk fetching/pushing of data?
 
278
    supports_random_access = True
 
279
 
284
280
    def abort_write_group(self, suppress_errors=False):
285
281
        """Commit the contents accrued within the current write group.
286
282
 
294
290
            # has an unlock or relock occured ?
295
291
            if suppress_errors:
296
292
                mutter(
297
 
                '(suppressed) mismatched lock context and write group. %r, %r',
298
 
                self._write_group, self.get_transaction())
 
293
                    '(suppressed) mismatched lock context and write group. %r, %r',
 
294
                    self._write_group, self.get_transaction())
299
295
                return
300
296
            raise errors.BzrError(
301
297
                'mismatched lock context and write group. %r, %r' %
541
537
                if committers:
542
538
                    all_committers = set()
543
539
                revisions = [r for (r, p) in graph.iter_ancestry([revid])
544
 
                            if r != _mod_revision.NULL_REVISION]
 
540
                             if r != _mod_revision.NULL_REVISION]
545
541
                last_revision = None
546
542
                if not committers:
547
543
                    # ignore the revisions in the middle - just grab first and last
555
551
                if committers:
556
552
                    result['committers'] = len(all_committers)
557
553
                result['firstrev'] = (first_revision.timestamp,
558
 
                    first_revision.timezone)
 
554
                                      first_revision.timezone)
559
555
                result['latestrev'] = (last_revision.timestamp,
560
 
                    last_revision.timezone)
 
556
                                       last_revision.timezone)
561
557
            return result
562
558
 
563
559
    def find_branches(self, using=False):
569
565
        """
570
566
        if using and not self.is_shared():
571
567
            return self.controldir.list_branches()
 
568
 
572
569
        class Evaluator(object):
573
570
 
574
571
            def __init__(self):
598
595
        return ret
599
596
 
600
597
    def search_missing_revision_ids(self, other,
601
 
            find_ghosts=True, revision_ids=None, if_present_ids=None,
602
 
            limit=None):
 
598
                                    find_ghosts=True, revision_ids=None, if_present_ids=None,
 
599
                                    limit=None):
603
600
        """Return the revision ids that other has that this does not.
604
601
 
605
602
        These are returned in topological order.
633
630
        """Commit the contents accrued within the current write group.
634
631
 
635
632
        :seealso: start_write_group.
636
 
        
 
633
 
637
634
        :return: it may return an opaque hint that can be passed to 'pack'.
638
635
        """
639
636
        if self._write_group is not self.get_transaction():
640
637
            # has an unlock or relock occured ?
641
638
            raise errors.BzrError('mismatched lock context %r and '
642
 
                'write group %r.' %
643
 
                (self.get_transaction(), self._write_group))
 
639
                                  'write group %r.' %
 
640
                                  (self.get_transaction(), self._write_group))
644
641
        result = self._commit_write_group()
645
642
        self._write_group = None
646
643
        return result
711
708
        # TODO: lift out to somewhere common with RemoteRepository
712
709
        # <https://bugs.launchpad.net/bzr/+bug/401646>
713
710
        if (self.has_same_location(source)
714
 
            and self._has_same_fallbacks(source)):
 
711
                and self._has_same_fallbacks(source)):
715
712
            # check that last_revision is in 'from' and then return a
716
713
            # no-operation.
717
714
            if (revision_id is not None and
718
 
                not _mod_revision.is_null(revision_id)):
 
715
                    not _mod_revision.is_null(revision_id)):
719
716
                self.get_revision(revision_id)
720
717
            return 0, []
721
718
        inter = InterRepository.get(source, self)
822
819
            # created, but on some old all-in-one formats it's not needed
823
820
            try:
824
821
                dest_repo = self._format.initialize(
825
 
                        a_controldir, shared=shared)
 
822
                    a_controldir, shared=shared)
826
823
            except errors.UninitializableFormat:
827
824
                dest_repo = a_controldir.open_repository()
828
825
        return dest_repo
910
907
                [r], specific_fileids=specific_fileids))[0]
911
908
 
912
909
    def store_revision_signature(self, gpg_strategy, plaintext, revision_id):
913
 
        with self.lock_write():
914
 
            signature = gpg_strategy.sign(plaintext, gpg.MODE_CLEAR)
915
 
            self.add_signature_text(revision_id, signature)
 
910
        raise NotImplementedError(self.store_revision_signature)
916
911
 
917
912
    def add_signature_text(self, revision_id, signature):
918
913
        """Store a signature text for a revision.
979
974
 
980
975
    def reconcile(self, other=None, thorough=False):
981
976
        """Reconcile this repository."""
982
 
        from .reconcile import RepoReconciler
983
 
        with self.lock_write():
984
 
            reconciler = RepoReconciler(self, thorough=thorough)
985
 
            reconciler.reconcile()
986
 
            return reconciler
 
977
        raise NotImplementedError(self.reconcile)
987
978
 
988
979
    def _refresh_data(self):
989
980
        """Helper called from lock_* to ensure coherency with disk.
1060
1051
                vf.get_parent_map(query_keys)):
1061
1052
            if parent_keys:
1062
1053
                result[revision_id] = tuple([parent_revid
1063
 
                    for (parent_revid,) in parent_keys])
 
1054
                                             for (parent_revid,) in parent_keys])
1064
1055
            else:
1065
1056
                result[revision_id] = (_mod_revision.NULL_REVISION,)
1066
1057
        return result
1089
1080
        """Return the graph walker for this repository format"""
1090
1081
        parents_provider = self._make_parents_provider()
1091
1082
        if (other_repository is not None and
1092
 
            not self.has_same_location(other_repository)):
 
1083
                not self.has_same_location(other_repository)):
1093
1084
            parents_provider = graph.StackedParentsProvider(
1094
1085
                [parents_provider, other_repository._make_parents_provider()])
1095
1086
        return graph.Graph(parents_provider)
1110
1101
        raise NotImplementedError(self.make_working_trees)
1111
1102
 
1112
1103
    def sign_revision(self, revision_id, gpg_strategy):
1113
 
        with self.lock_write():
1114
 
            testament = _mod_testament.Testament.from_revision(self, revision_id)
1115
 
            plaintext = testament.as_short_text()
1116
 
            self.store_revision_signature(gpg_strategy, plaintext, revision_id)
 
1104
        raise NotImplementedError(self.sign_revision)
1117
1105
 
1118
1106
    def verify_revision_signature(self, revision_id, gpg_strategy):
1119
1107
        """Verify the signature on a revision.
1123
1111
 
1124
1112
        :return: gpg.SIGNATURE_VALID or a failed SIGNATURE_ value
1125
1113
        """
1126
 
        with self.lock_read():
1127
 
            if not self.has_signature_for_revision_id(revision_id):
1128
 
                return gpg.SIGNATURE_NOT_SIGNED, None
1129
 
            signature = self.get_signature_text(revision_id)
1130
 
 
1131
 
            testament = _mod_testament.Testament.from_revision(self, revision_id)
1132
 
 
1133
 
            (status, key, signed_plaintext) = gpg_strategy.verify(signature)
1134
 
            if testament.as_short_text() != signed_plaintext:
1135
 
                return gpg.SIGNATURE_NOT_VALID, None
1136
 
            return (status, key)
 
1114
        raise NotImplementedError(self.verify_revision_signature)
1137
1115
 
1138
1116
    def verify_revision_signatures(self, revision_ids, gpg_strategy):
1139
1117
        """Verify revision signatures for a number of revisions.
1165
1143
        :param callback_refs: A dict of check-refs to resolve and callback
1166
1144
            the check/_check method on the items listed as wanting the ref.
1167
1145
            see breezy.check.
1168
 
        :param check_repo: If False do not check the repository contents, just 
 
1146
        :param check_repo: If False do not check the repository contents, just
1169
1147
            calculate the data callback_refs requires and call them back.
1170
1148
        """
1171
1149
        return self._check(revision_ids=revision_ids, callback_refs=callback_refs,
1172
 
            check_repo=check_repo)
 
1150
                           check_repo=check_repo)
1173
1151
 
1174
1152
    def _check(self, revision_ids=None, callback_refs=None, check_repo=True):
1175
1153
        raise NotImplementedError(self.check)
1388
1366
            raise errors.BadConversionTarget(
1389
1367
                'Does not support rich root data.', target_format,
1390
1368
                from_format=self)
1391
 
        if (self.supports_tree_reference and 
1392
 
            not getattr(target_format, 'supports_tree_reference', False)):
 
1369
        if (self.supports_tree_reference
 
1370
                and not getattr(target_format, 'supports_tree_reference', False)):
1393
1371
            raise errors.BadConversionTarget(
1394
1372
                'Does not support nested trees', target_format,
1395
1373
                from_format=self)
1581
1559
        """
1582
1560
        if source.supports_rich_root() != target.supports_rich_root():
1583
1561
            raise errors.IncompatibleRepositories(source, target,
1584
 
                "different rich-root support")
 
1562
                                                  "different rich-root support")
1585
1563
        if source._serializer != target._serializer:
1586
1564
            raise errors.IncompatibleRepositories(source, target,
1587
 
                "different serializers")
 
1565
                                                  "different serializers")
1588
1566
 
1589
1567
 
1590
1568
class CopyConverter(object):
1615
1593
            self.repo_dir = repo.controldir
1616
1594
            pb.update(gettext('Moving repository to repository.backup'))
1617
1595
            self.repo_dir.transport.move('repository', 'repository.backup')
1618
 
            backup_transport =  self.repo_dir.transport.clone('repository.backup')
 
1596
            backup_transport = self.repo_dir.transport.clone(
 
1597
                'repository.backup')
1619
1598
            repo._format.check_conversion_target(self.target_format)
1620
1599
            self.source_repo = repo._format.open(self.repo_dir,
1621
 
                _found=True,
1622
 
                _override_transport=backup_transport)
 
1600
                                                 _found=True,
 
1601
                                                 _override_transport=backup_transport)
1623
1602
            pb.update(gettext('Creating new repository'))
1624
1603
            converted = self.target_format.initialize(self.repo_dir,
1625
1604
                                                      self.source_repo.is_shared())
1641
1620
        del revision_graph[_mod_revision.NULL_REVISION]
1642
1621
    for key, parents in viewitems(revision_graph):
1643
1622
        revision_graph[key] = tuple(parent for parent in parents if parent
1644
 
            in revision_graph)
 
1623
                                    in revision_graph)
1645
1624
    return revision_graph
1646
1625
 
1647
1626
 
1662
1641
    start_revision = partial_history_cache[-1]
1663
1642
    graph = repo.get_graph()
1664
1643
    iterator = graph.iter_lefthand_ancestry(start_revision,
1665
 
        (_mod_revision.NULL_REVISION,))
 
1644
                                            (_mod_revision.NULL_REVISION,))
1666
1645
    try:
1667
1646
        # skip the last revision in the list
1668
1647
        next(iterator)
1669
1648
        while True:
1670
1649
            if (stop_index is not None and
1671
 
                len(partial_history_cache) > stop_index):
 
1650
                    len(partial_history_cache) > stop_index):
1672
1651
                break
1673
1652
            if partial_history_cache[-1] == stop_revision:
1674
1653
                break